//===- Stmt.h - Classes for representing statements -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file defines the Stmt interface and subclasses.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_STMT_H
#define LLVM_CLANG_AST_STMT_H

#include "clang/AST/DeclGroup.h"
#include "clang/AST/DependenceFlags.h"
#include "clang/AST/StmtIterator.h"
#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <string>

namespace llvm {

class FoldingSetNodeID;

} // namespace llvm

namespace clang {

class ASTContext;
class Attr;
class CapturedDecl;
class Decl;
class Expr;
class AddrLabelExpr;
class LabelDecl;
class ODRHash;
class PrinterHelper;
struct PrintingPolicy;
class RecordDecl;
class SourceManager;
class StringLiteral;
class Token;
class ValueDecl;
class VarDecl;

//===----------------------------------------------------------------------===//
// AST classes for statements.
//===----------------------------------------------------------------------===//

/// Stmt - This represents one statement.
///
class alignas(void *) Stmt {
public:
  enum StmtClass {
    NoStmtClass = 0,
#define STMT(CLASS, PARENT) CLASS##Class,
#define STMT_RANGE(BASE, FIRST, LAST) \
        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
#define ABSTRACT_STMT(STMT)
#include "clang/AST/StmtNodes.inc"
  };

  // Make vanilla 'new' and 'delete' illegal for Stmts.
protected:
  friend class ASTStmtReader;
  friend class ASTStmtWriter;

  void *operator new(size_t bytes) noexcept {
    llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
  }

  void operator delete(void *data) noexcept {
    llvm_unreachable("Stmts cannot be released with regular 'delete'.");
  }

  //===--- Statement bitfields classes ---===//

  class StmtBitfields {
    friend class ASTStmtReader;
    friend class ASTStmtWriter;
    friend class Stmt;

    /// The statement class.
    unsigned sClass : 8;
  };
  enum { NumStmtBits = 8 };

  class NullStmtBitfields {
    friend class ASTStmtReader;
    friend class ASTStmtWriter;
    friend class NullStmt;

    unsigned : NumStmtBits;

    /// True if the null statement was preceded by an empty macro, e.g:
    /// @code
    ///   #define CALL(x)
    ///   CALL(0);
    /// @endcode
    unsigned HasLeadingEmptyMacro : 1;

    /// The location of the semi-colon.
    SourceLocation SemiLoc;
  };

  class CompoundStmtBitfields {
    friend class ASTStmtReader;
    friend class CompoundStmt;

    unsigned : NumStmtBits;

    /// True if the compound statement has one or more pragmas that set some
    /// floating-point features.
    unsigned HasFPFeatures : 1;

    unsigned NumStmts;
  };

  class LabelStmtBitfields {
    friend class LabelStmt;

    unsigned : NumStmtBits;

    SourceLocation IdentLoc;
  };

  class AttributedStmtBitfields {
    friend class ASTStmtReader;
    friend class AttributedStmt;

    unsigned : NumStmtBits;

    /// Number of attributes.
    unsigned NumAttrs : 32 - NumStmtBits;

    /// The location of the attribute.
    SourceLocation AttrLoc;
  };

  class IfStmtBitfields {
    friend class ASTStmtReader;
    friend class IfStmt;

    unsigned : NumStmtBits;

    /// Whether this is a constexpr if, or a consteval if, or neither.
    unsigned Kind : 3;

    /// True if this if statement has storage for an else statement.
    unsigned HasElse : 1;

    /// True if this if statement has storage for a variable declaration.
    unsigned HasVar : 1;

    /// True if this if statement has storage for an init statement.
    unsigned HasInit : 1;

    /// The location of the "if".
    SourceLocation IfLoc;
  };

  class SwitchStmtBitfields {
    friend class SwitchStmt;

    unsigned : NumStmtBits;

    /// True if the SwitchStmt has storage for an init statement.
    unsigned HasInit : 1;

    /// True if the SwitchStmt has storage for a condition variable.
    unsigned HasVar : 1;

    /// If the SwitchStmt is a switch on an enum value, records whether all
    /// the enum values were covered by CaseStmts.  The coverage information
    /// value is meant to be a hint for possible clients.
    unsigned AllEnumCasesCovered : 1;

    /// The location of the "switch".
    SourceLocation SwitchLoc;
  };

  class WhileStmtBitfields {
    friend class ASTStmtReader;
    friend class WhileStmt;

    unsigned : NumStmtBits;

    /// True if the WhileStmt has storage for a condition variable.
    unsigned HasVar : 1;

    /// The location of the "while".
    SourceLocation WhileLoc;
  };

  class DoStmtBitfields {
    friend class DoStmt;

    unsigned : NumStmtBits;

    /// The location of the "do".
    SourceLocation DoLoc;
  };

  class ForStmtBitfields {
    friend class ForStmt;

    unsigned : NumStmtBits;

    /// The location of the "for".
    SourceLocation ForLoc;
  };

  class GotoStmtBitfields {
    friend class GotoStmt;
    friend class IndirectGotoStmt;

    unsigned : NumStmtBits;

    /// The location of the "goto".
    SourceLocation GotoLoc;
  };

  class ContinueStmtBitfields {
    friend class ContinueStmt;

    unsigned : NumStmtBits;

    /// The location of the "continue".
    SourceLocation ContinueLoc;
  };

  class BreakStmtBitfields {
    friend class BreakStmt;

    unsigned : NumStmtBits;

    /// The location of the "break".
    SourceLocation BreakLoc;
  };

  class ReturnStmtBitfields {
    friend class ReturnStmt;

    unsigned : NumStmtBits;

    /// True if this ReturnStmt has storage for an NRVO candidate.
    unsigned HasNRVOCandidate : 1;

    /// The location of the "return".
    SourceLocation RetLoc;
  };

  class SwitchCaseBitfields {
    friend class SwitchCase;
    friend class CaseStmt;

    unsigned : NumStmtBits;

    /// Used by CaseStmt to store whether it is a case statement
    /// of the form case LHS ... RHS (a GNU extension).
    unsigned CaseStmtIsGNURange : 1;

    /// The location of the "case" or "default" keyword.
    SourceLocation KeywordLoc;
  };

  //===--- Expression bitfields classes ---===//

  class ExprBitfields {
    friend class ASTStmtReader; // deserialization
    friend class AtomicExpr; // ctor
    friend class BlockDeclRefExpr; // ctor
    friend class CallExpr; // ctor
    friend class CXXConstructExpr; // ctor
    friend class CXXDependentScopeMemberExpr; // ctor
    friend class CXXNewExpr; // ctor
    friend class CXXUnresolvedConstructExpr; // ctor
    friend class DeclRefExpr; // computeDependence
    friend class DependentScopeDeclRefExpr; // ctor
    friend class DesignatedInitExpr; // ctor
    friend class Expr;
    friend class InitListExpr; // ctor
    friend class ObjCArrayLiteral; // ctor
    friend class ObjCDictionaryLiteral; // ctor
    friend class ObjCMessageExpr; // ctor
    friend class OffsetOfExpr; // ctor
    friend class OpaqueValueExpr; // ctor
    friend class OverloadExpr; // ctor
    friend class ParenListExpr; // ctor
    friend class PseudoObjectExpr; // ctor
    friend class ShuffleVectorExpr; // ctor

    unsigned : NumStmtBits;

    unsigned ValueKind : 2;
    unsigned ObjectKind : 3;
    unsigned /*ExprDependence*/ Dependent : llvm::BitWidth<ExprDependence>;
  };
  enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth<ExprDependence> };

  class ConstantExprBitfields {
    friend class ASTStmtReader;
    friend class ASTStmtWriter;
    friend class ConstantExpr;

    unsigned : NumExprBits;

    /// The kind of result that is tail-allocated.
    unsigned ResultKind : 2;

    /// The kind of Result as defined by APValue::Kind.
    unsigned APValueKind : 4;

    /// When ResultKind == RSK_Int64, true if the tail-allocated integer is
    /// unsigned.
    unsigned IsUnsigned : 1;

    /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated
    /// integer. 7 bits because it is the minimal number of bits to represent a
    /// value from 0 to 64 (the size of the tail-allocated integer).
    unsigned BitWidth : 7;

    /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the
    /// tail-allocated APValue.
    unsigned HasCleanup : 1;

    /// True if this ConstantExpr was created for immediate invocation.
    unsigned IsImmediateInvocation : 1;
  };

  class PredefinedExprBitfields {
    friend class ASTStmtReader;
    friend class PredefinedExpr;

    unsigned : NumExprBits;

    /// The kind of this PredefinedExpr. One of the enumeration values
    /// in PredefinedExpr::IdentKind.
    unsigned Kind : 4;

    /// True if this PredefinedExpr has a trailing "StringLiteral *"
    /// for the predefined identifier.
    unsigned HasFunctionName : 1;

    /// The location of this PredefinedExpr.
    SourceLocation Loc;
  };

  class DeclRefExprBitfields {
    friend class ASTStmtReader; // deserialization
    friend class DeclRefExpr;

    unsigned : NumExprBits;

    unsigned HasQualifier : 1;
    unsigned HasTemplateKWAndArgsInfo : 1;
    unsigned HasFoundDecl : 1;
    unsigned HadMultipleCandidates : 1;
    unsigned RefersToEnclosingVariableOrCapture : 1;
    unsigned NonOdrUseReason : 2;

    /// The location of the declaration name itself.
    SourceLocation Loc;
  };


  class FloatingLiteralBitfields {
    friend class FloatingLiteral;

    unsigned : NumExprBits;

    unsigned Semantics : 3; // Provides semantics for APFloat construction
    unsigned IsExact : 1;
  };

  class StringLiteralBitfields {
    friend class ASTStmtReader;
    friend class StringLiteral;

    unsigned : NumExprBits;

    /// The kind of this string literal.
    /// One of the enumeration values of StringLiteral::StringKind.
    unsigned Kind : 3;

    /// The width of a single character in bytes. Only values of 1, 2,
    /// and 4 bytes are supported. StringLiteral::mapCharByteWidth maps
    /// the target + string kind to the appropriate CharByteWidth.
    unsigned CharByteWidth : 3;

    unsigned IsPascal : 1;

    /// The number of concatenated token this string is made of.
    /// This is the number of trailing SourceLocation.
    unsigned NumConcatenated;
  };

  class CharacterLiteralBitfields {
    friend class CharacterLiteral;

    unsigned : NumExprBits;

    unsigned Kind : 3;
  };

  class UnaryOperatorBitfields {
    friend class UnaryOperator;

    unsigned : NumExprBits;

    unsigned Opc : 5;
    unsigned CanOverflow : 1;
    //
    /// This is only meaningful for operations on floating point
    /// types when additional values need to be in trailing storage.
    /// It is 0 otherwise.
    unsigned HasFPFeatures : 1;

    SourceLocation Loc;
  };

  class UnaryExprOrTypeTraitExprBitfields {
    friend class UnaryExprOrTypeTraitExpr;

    unsigned : NumExprBits;

    unsigned Kind : 3;
    unsigned IsType : 1; // true if operand is a type, false if an expression.
  };

  class ArrayOrMatrixSubscriptExprBitfields {
    friend class ArraySubscriptExpr;
    friend class MatrixSubscriptExpr;

    unsigned : NumExprBits;

    SourceLocation RBracketLoc;
  };

  class CallExprBitfields {
    friend class CallExpr;

    unsigned : NumExprBits;

    unsigned NumPreArgs : 1;

    /// True if the callee of the call expression was found using ADL.
    unsigned UsesADL : 1;

    /// True if the call expression has some floating-point features.
    unsigned HasFPFeatures : 1;

    /// Padding used to align OffsetToTrailingObjects to a byte multiple.
    unsigned : 24 - 3 - NumExprBits;

    /// The offset in bytes from the this pointer to the start of the
    /// trailing objects belonging to CallExpr. Intentionally byte sized
    /// for faster access.
    unsigned OffsetToTrailingObjects : 8;
  };
  enum { NumCallExprBits = 32 };

  class MemberExprBitfields {
    friend class ASTStmtReader;
    friend class MemberExpr;

    unsigned : NumExprBits;

    /// IsArrow - True if this is "X->F", false if this is "X.F".
    unsigned IsArrow : 1;

    /// True if this member expression used a nested-name-specifier to
    /// refer to the member, e.g., "x->Base::f", or found its member via
    /// a using declaration.  When true, a MemberExprNameQualifier
    /// structure is allocated immediately after the MemberExpr.
    unsigned HasQualifierOrFoundDecl : 1;

    /// True if this member expression specified a template keyword
    /// and/or a template argument list explicitly, e.g., x->f<int>,
    /// x->template f, x->template f<int>.
    /// When true, an ASTTemplateKWAndArgsInfo structure and its
    /// TemplateArguments (if any) are present.
    unsigned HasTemplateKWAndArgsInfo : 1;

    /// True if this member expression refers to a method that
    /// was resolved from an overloaded set having size greater than 1.
    unsigned HadMultipleCandidates : 1;

    /// Value of type NonOdrUseReason indicating why this MemberExpr does
    /// not constitute an odr-use of the named declaration. Meaningful only
    /// when naming a static member.
    unsigned NonOdrUseReason : 2;

    /// This is the location of the -> or . in the expression.
    SourceLocation OperatorLoc;
  };

  class CastExprBitfields {
    friend class CastExpr;
    friend class ImplicitCastExpr;

    unsigned : NumExprBits;

    unsigned Kind : 7;
    unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.

    /// True if the call expression has some floating-point features.
    unsigned HasFPFeatures : 1;

    /// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
    /// here. ([implimits] Direct and indirect base classes [16384]).
    unsigned BasePathSize;
  };

  class BinaryOperatorBitfields {
    friend class BinaryOperator;

    unsigned : NumExprBits;

    unsigned Opc : 6;

    /// This is only meaningful for operations on floating point
    /// types when additional values need to be in trailing storage.
    /// It is 0 otherwise.
    unsigned HasFPFeatures : 1;

    SourceLocation OpLoc;
  };

  class InitListExprBitfields {
    friend class InitListExpr;

    unsigned : NumExprBits;

    /// Whether this initializer list originally had a GNU array-range
    /// designator in it. This is a temporary marker used by CodeGen.
    unsigned HadArrayRangeDesignator : 1;
  };

  class ParenListExprBitfields {
    friend class ASTStmtReader;
    friend class ParenListExpr;

    unsigned : NumExprBits;

    /// The number of expressions in the paren list.
    unsigned NumExprs;
  };

  class GenericSelectionExprBitfields {
    friend class ASTStmtReader;
    friend class GenericSelectionExpr;

    unsigned : NumExprBits;

    /// The location of the "_Generic".
    SourceLocation GenericLoc;
  };

  class PseudoObjectExprBitfields {
    friend class ASTStmtReader; // deserialization
    friend class PseudoObjectExpr;

    unsigned : NumExprBits;

    // These don't need to be particularly wide, because they're
    // strictly limited by the forms of expressions we permit.
    unsigned NumSubExprs : 8;
    unsigned ResultIndex : 32 - 8 - NumExprBits;
  };

  class SourceLocExprBitfields {
    friend class ASTStmtReader;
    friend class SourceLocExpr;

    unsigned : NumExprBits;

    /// The kind of source location builtin represented by the SourceLocExpr.
    /// Ex. __builtin_LINE, __builtin_FUNCTION, etc.
    unsigned Kind : 3;
  };

  class StmtExprBitfields {
    friend class ASTStmtReader;
    friend class StmtExpr;

    unsigned : NumExprBits;

    /// The number of levels of template parameters enclosing this statement
    /// expression. Used to determine if a statement expression remains
    /// dependent after instantiation.
    unsigned TemplateDepth;
  };

  //===--- C++ Expression bitfields classes ---===//

  class CXXOperatorCallExprBitfields {
    friend class ASTStmtReader;
    friend class CXXOperatorCallExpr;

    unsigned : NumCallExprBits;

    /// The kind of this overloaded operator. One of the enumerator
    /// value of OverloadedOperatorKind.
    unsigned OperatorKind : 6;
  };

  class CXXRewrittenBinaryOperatorBitfields {
    friend class ASTStmtReader;
    friend class CXXRewrittenBinaryOperator;

    unsigned : NumCallExprBits;

    unsigned IsReversed : 1;
  };

  class CXXBoolLiteralExprBitfields {
    friend class CXXBoolLiteralExpr;

    unsigned : NumExprBits;

    /// The value of the boolean literal.
    unsigned Value : 1;

    /// The location of the boolean literal.
    SourceLocation Loc;
  };

  class CXXNullPtrLiteralExprBitfields {
    friend class CXXNullPtrLiteralExpr;

    unsigned : NumExprBits;

    /// The location of the null pointer literal.
    SourceLocation Loc;
  };

  class CXXThisExprBitfields {
    friend class CXXThisExpr;

    unsigned : NumExprBits;

    /// Whether this is an implicit "this".
    unsigned IsImplicit : 1;

    /// The location of the "this".
    SourceLocation Loc;
  };

  class CXXThrowExprBitfields {
    friend class ASTStmtReader;
    friend class CXXThrowExpr;

    unsigned : NumExprBits;

    /// Whether the thrown variable (if any) is in scope.
    unsigned IsThrownVariableInScope : 1;

    /// The location of the "throw".
    SourceLocation ThrowLoc;
  };

  class CXXDefaultArgExprBitfields {
    friend class ASTStmtReader;
    friend class CXXDefaultArgExpr;

    unsigned : NumExprBits;

    /// The location where the default argument expression was used.
    SourceLocation Loc;
  };

  class CXXDefaultInitExprBitfields {
    friend class ASTStmtReader;
    friend class CXXDefaultInitExpr;

    unsigned : NumExprBits;

    /// The location where the default initializer expression was used.
    SourceLocation Loc;
  };

  class CXXScalarValueInitExprBitfields {
    friend class ASTStmtReader;
    friend class CXXScalarValueInitExpr;

    unsigned : NumExprBits;

    SourceLocation RParenLoc;
  };

  class CXXNewExprBitfields {
    friend class ASTStmtReader;
    friend class ASTStmtWriter;
    friend class CXXNewExpr;

    unsigned : NumExprBits;

    /// Was the usage ::new, i.e. is the global new to be used?
    unsigned IsGlobalNew : 1;

    /// Do we allocate an array? If so, the first trailing "Stmt *" is the
    /// size expression.
    unsigned IsArray : 1;

    /// Should the alignment be passed to the allocation function?
    unsigned ShouldPassAlignment : 1;

    /// If this is an array allocation, does the usual deallocation
    /// function for the allocated type want to know the allocated size?
    unsigned UsualArrayDeleteWantsSize : 1;

    /// What kind of initializer do we have? Could be none, parens, or braces.
    /// In storage, we distinguish between "none, and no initializer expr", and
    /// "none, but an implicit initializer expr".
    unsigned StoredInitializationStyle : 2;

    /// True if the allocated type was expressed as a parenthesized type-id.
    unsigned IsParenTypeId : 1;

    /// The number of placement new arguments.
    unsigned NumPlacementArgs;
  };

  class CXXDeleteExprBitfields {
    friend class ASTStmtReader;
    friend class CXXDeleteExpr;

    unsigned : NumExprBits;

    /// Is this a forced global delete, i.e. "::delete"?
    unsigned GlobalDelete : 1;

    /// Is this the array form of delete, i.e. "delete[]"?
    unsigned ArrayForm : 1;

    /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is
    /// applied to pointer-to-array type (ArrayFormAsWritten will be false
    /// while ArrayForm will be true).
    unsigned ArrayFormAsWritten : 1;

    /// Does the usual deallocation function for the element type require
    /// a size_t argument?
    unsigned UsualArrayDeleteWantsSize : 1;

    /// Location of the expression.
    SourceLocation Loc;
  };

  class TypeTraitExprBitfields {
    friend class ASTStmtReader;
    friend class ASTStmtWriter;
    friend class TypeTraitExpr;

    unsigned : NumExprBits;

    /// The kind of type trait, which is a value of a TypeTrait enumerator.
    unsigned Kind : 8;

    /// If this expression is not value-dependent, this indicates whether
    /// the trait evaluated true or false.
    unsigned Value : 1;

    /// The number of arguments to this type trait. According to [implimits]
    /// 8 bits would be enough, but we require (and test for) at least 16 bits
    /// to mirror FunctionType.
    unsigned NumArgs;
  };

  class DependentScopeDeclRefExprBitfields {
    friend class ASTStmtReader;
    friend class ASTStmtWriter;
    friend class DependentScopeDeclRefExpr;

    unsigned : NumExprBits;

    /// Whether the name includes info for explicit template
    /// keyword and arguments.
    unsigned HasTemplateKWAndArgsInfo : 1;
  };

  class CXXConstructExprBitfields {
    friend class ASTStmtReader;
    friend class CXXConstructExpr;

    unsigned : NumExprBits;

    unsigned Elidable : 1;
    unsigned HadMultipleCandidates : 1;
    unsigned ListInitialization : 1;
    unsigned StdInitListInitialization : 1;
    unsigned ZeroInitialization : 1;
    unsigned ConstructionKind : 3;

    SourceLocation Loc;
  };

  class ExprWithCleanupsBitfields {
    friend class ASTStmtReader; // deserialization
    friend class ExprWithCleanups;

    unsigned : NumExprBits;

    // When false, it must not have side effects.
    unsigned CleanupsHaveSideEffects : 1;

    unsigned NumObjects : 32 - 1 - NumExprBits;
  };

  class CXXUnresolvedConstructExprBitfields {
    friend class ASTStmtReader;
    friend class CXXUnresolvedConstructExpr;

    unsigned : NumExprBits;

    /// The number of arguments used to construct the type.
    unsigned NumArgs;
  };

  class CXXDependentScopeMemberExprBitfields {
    friend class ASTStmtReader;
    friend class CXXDependentScopeMemberExpr;

    unsigned : NumExprBits;

    /// Whether this member expression used the '->' operator or
    /// the '.' operator.
    unsigned IsArrow : 1;

    /// Whether this member expression has info for explicit template
    /// keyword and arguments.
    unsigned HasTemplateKWAndArgsInfo : 1;

    /// See getFirstQualifierFoundInScope() and the comment listing
    /// the trailing objects.
    unsigned HasFirstQualifierFoundInScope : 1;

    /// The location of the '->' or '.' operator.
    SourceLocation OperatorLoc;
  };

  class OverloadExprBitfields {
    friend class ASTStmtReader;
    friend class OverloadExpr;

    unsigned : NumExprBits;

    /// Whether the name includes info for explicit template
    /// keyword and arguments.
    unsigned HasTemplateKWAndArgsInfo : 1;

    /// Padding used by the derived classes to store various bits. If you
    /// need to add some data here, shrink this padding and add your data
    /// above. NumOverloadExprBits also needs to be updated.
    unsigned : 32 - NumExprBits - 1;

    /// The number of results.
    unsigned NumResults;
  };
  enum { NumOverloadExprBits = NumExprBits + 1 };

  class UnresolvedLookupExprBitfields {
    friend class ASTStmtReader;
    friend class UnresolvedLookupExpr;

    unsigned : NumOverloadExprBits;

    /// True if these lookup results should be extended by
    /// argument-dependent lookup if this is the operand of a function call.
    unsigned RequiresADL : 1;

    /// True if these lookup results are overloaded.  This is pretty trivially
    /// rederivable if we urgently need to kill this field.
    unsigned Overloaded : 1;
  };
  static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
                "UnresolvedLookupExprBitfields must be <= than 4 bytes to"
                "avoid trashing OverloadExprBitfields::NumResults!");

  class UnresolvedMemberExprBitfields {
    friend class ASTStmtReader;
    friend class UnresolvedMemberExpr;

    unsigned : NumOverloadExprBits;

    /// Whether this member expression used the '->' operator or
    /// the '.' operator.
    unsigned IsArrow : 1;

    /// Whether the lookup results contain an unresolved using declaration.
    unsigned HasUnresolvedUsing : 1;
  };
  static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
                "UnresolvedMemberExprBitfields must be <= than 4 bytes to"
                "avoid trashing OverloadExprBitfields::NumResults!");

  class CXXNoexceptExprBitfields {
    friend class ASTStmtReader;
    friend class CXXNoexceptExpr;

    unsigned : NumExprBits;

    unsigned Value : 1;
  };

  class SubstNonTypeTemplateParmExprBitfields {
    friend class ASTStmtReader;
    friend class SubstNonTypeTemplateParmExpr;

    unsigned : NumExprBits;

    /// The location of the non-type template parameter reference.
    SourceLocation NameLoc;
  };

  class LambdaExprBitfields {
    friend class ASTStmtReader;
    friend class ASTStmtWriter;
    friend class LambdaExpr;

    unsigned : NumExprBits;

    /// The default capture kind, which is a value of type
    /// LambdaCaptureDefault.
    unsigned CaptureDefault : 2;

    /// Whether this lambda had an explicit parameter list vs. an
    /// implicit (and empty) parameter list.
    unsigned ExplicitParams : 1;

    /// Whether this lambda had the result type explicitly specified.
    unsigned ExplicitResultType : 1;

    /// The number of captures.
    unsigned NumCaptures : 16;
  };

  class RequiresExprBitfields {
    friend class ASTStmtReader;
    friend class ASTStmtWriter;
    friend class RequiresExpr;

    unsigned : NumExprBits;

    unsigned IsSatisfied : 1;
    SourceLocation RequiresKWLoc;
  };

  //===--- C++ Coroutines TS bitfields classes ---===//

  class CoawaitExprBitfields {
    friend class CoawaitExpr;

    unsigned : NumExprBits;

    unsigned IsImplicit : 1;
  };

  //===--- Obj-C Expression bitfields classes ---===//

  class ObjCIndirectCopyRestoreExprBitfields {
    friend class ObjCIndirectCopyRestoreExpr;

    unsigned : NumExprBits;

    unsigned ShouldCopy : 1;
  };

  //===--- Clang Extensions bitfields classes ---===//

  class OpaqueValueExprBitfields {
    friend class ASTStmtReader;
    friend class OpaqueValueExpr;

    unsigned : NumExprBits;

    /// The OVE is a unique semantic reference to its source expression if this
    /// bit is set to true.
    unsigned IsUnique : 1;

    SourceLocation Loc;
  };

  union {
    // Same order as in StmtNodes.td.
    // Statements
    StmtBitfields StmtBits;
    NullStmtBitfields NullStmtBits;
    CompoundStmtBitfields CompoundStmtBits;
    LabelStmtBitfields LabelStmtBits;
    AttributedStmtBitfields AttributedStmtBits;
    IfStmtBitfields IfStmtBits;
    SwitchStmtBitfields SwitchStmtBits;
    WhileStmtBitfields WhileStmtBits;
    DoStmtBitfields DoStmtBits;
    ForStmtBitfields ForStmtBits;
    GotoStmtBitfields GotoStmtBits;
    ContinueStmtBitfields ContinueStmtBits;
    BreakStmtBitfields BreakStmtBits;
    ReturnStmtBitfields ReturnStmtBits;
    SwitchCaseBitfields SwitchCaseBits;

    // Expressions
    ExprBitfields ExprBits;
    ConstantExprBitfields ConstantExprBits;
    PredefinedExprBitfields PredefinedExprBits;
    DeclRefExprBitfields DeclRefExprBits;
    FloatingLiteralBitfields FloatingLiteralBits;
    StringLiteralBitfields StringLiteralBits;
    CharacterLiteralBitfields CharacterLiteralBits;
    UnaryOperatorBitfields UnaryOperatorBits;
    UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
    ArrayOrMatrixSubscriptExprBitfields ArrayOrMatrixSubscriptExprBits;
    CallExprBitfields CallExprBits;
    MemberExprBitfields MemberExprBits;
    CastExprBitfields CastExprBits;
    BinaryOperatorBitfields BinaryOperatorBits;
    InitListExprBitfields InitListExprBits;
    ParenListExprBitfields ParenListExprBits;
    GenericSelectionExprBitfields GenericSelectionExprBits;
    PseudoObjectExprBitfields PseudoObjectExprBits;
    SourceLocExprBitfields SourceLocExprBits;

    // GNU Extensions.
    StmtExprBitfields StmtExprBits;

    // C++ Expressions
    CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
    CXXRewrittenBinaryOperatorBitfields CXXRewrittenBinaryOperatorBits;
    CXXBoolLiteralExprBitfields CXXBoolLiteralExprBits;
    CXXNullPtrLiteralExprBitfields CXXNullPtrLiteralExprBits;
    CXXThisExprBitfields CXXThisExprBits;
    CXXThrowExprBitfields CXXThrowExprBits;
    CXXDefaultArgExprBitfields CXXDefaultArgExprBits;
    CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
    CXXScalarValueInitExprBitfields CXXScalarValueInitExprBits;
    CXXNewExprBitfields CXXNewExprBits;
    CXXDeleteExprBitfields CXXDeleteExprBits;
    TypeTraitExprBitfields TypeTraitExprBits;
    DependentScopeDeclRefExprBitfields DependentScopeDeclRefExprBits;
    CXXConstructExprBitfields CXXConstructExprBits;
    ExprWithCleanupsBitfields ExprWithCleanupsBits;
    CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
    CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
    OverloadExprBitfields OverloadExprBits;
    UnresolvedLookupExprBitfields UnresolvedLookupExprBits;
    UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
    CXXNoexceptExprBitfields CXXNoexceptExprBits;
    SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
    LambdaExprBitfields LambdaExprBits;
    RequiresExprBitfields RequiresExprBits;

    // C++ Coroutines TS expressions
    CoawaitExprBitfields CoawaitBits;

    // Obj-C Expressions
    ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;

    // Clang Extensions
    OpaqueValueExprBitfields OpaqueValueExprBits;
  };

public:
  // Only allow allocation of Stmts using the allocator in ASTContext
  // or by doing a placement new.
  void* operator new(size_t bytes, const ASTContext& C,
                     unsigned alignment = 8);

  void* operator new(size_t bytes, const ASTContext* C,
                     unsigned alignment = 8) {
    return operator new(bytes, *C, alignment);
  }

  void *operator new(size_t bytes, void *mem) noexcept { return mem; }

  void operator delete(void *, const ASTContext &, unsigned) noexcept {}
  void operator delete(void *, const ASTContext *, unsigned) noexcept {}
  void operator delete(void *, size_t) noexcept {}
  void operator delete(void *, void *) noexcept {}

public:
  /// A placeholder type used to construct an empty shell of a
  /// type, that will be filled in later (e.g., by some
  /// de-serialization).
  struct EmptyShell {};

  /// The likelihood of a branch being taken.
  enum Likelihood {
    LH_Unlikely = -1, ///< Branch has the [[unlikely]] attribute.
    LH_None,          ///< No attribute set or branches of the IfStmt have
                      ///< the same attribute.
    LH_Likely         ///< Branch has the [[likely]] attribute.
  };

protected:
  /// Iterator for iterating over Stmt * arrays that contain only T *.
  ///
  /// This is needed because AST nodes use Stmt* arrays to store
  /// references to children (to be compatible with StmtIterator).
  template<typename T, typename TPtr = T *, typename StmtPtr = Stmt *>
  struct CastIterator
      : llvm::iterator_adaptor_base<CastIterator<T, TPtr, StmtPtr>, StmtPtr *,
                                    std::random_access_iterator_tag, TPtr> {
    using Base = typename CastIterator::iterator_adaptor_base;

    CastIterator() : Base(nullptr) {}
    CastIterator(StmtPtr *I) : Base(I) {}

    typename Base::value_type operator*() const {
      return cast_or_null<T>(*this->I);
    }
  };

  /// Const iterator for iterating over Stmt * arrays that contain only T *.
  template <typename T>
  using ConstCastIterator = CastIterator<T, const T *const, const Stmt *const>;

  using ExprIterator = CastIterator<Expr>;
  using ConstExprIterator = ConstCastIterator<Expr>;

private:
  /// Whether statistic collection is enabled.
  static bool StatisticsEnabled;

protected:
  /// Construct an empty statement.
  explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {}

public:
  Stmt() = delete;
  Stmt(const Stmt &) = delete;
  Stmt(Stmt &&) = delete;
  Stmt &operator=(const Stmt &) = delete;
  Stmt &operator=(Stmt &&) = delete;

  Stmt(StmtClass SC) {
    static_assert(sizeof(*this) <= 8,
                  "changing bitfields changed sizeof(Stmt)");
    static_assert(sizeof(*this) % alignof(void *) == 0,
                  "Insufficient alignment!");
    StmtBits.sClass = SC;
    if (StatisticsEnabled) Stmt::addStmtClass(SC);
  }

  StmtClass getStmtClass() const {
    return static_cast<StmtClass>(StmtBits.sClass);
  }

  const char *getStmtClassName() const;

  /// SourceLocation tokens are not useful in isolation - they are low level
  /// value objects created/interpreted by SourceManager. We assume AST
  /// clients will have a pointer to the respective SourceManager.
  SourceRange getSourceRange() const LLVM_READONLY;
  SourceLocation getBeginLoc() const LLVM_READONLY;
  SourceLocation getEndLoc() const LLVM_READONLY;

  // global temp stats (until we have a per-module visitor)
  static void addStmtClass(const StmtClass s);
  static void EnableStatistics();
  static void PrintStats();

  /// \returns the likelihood of a set of attributes.
  static Likelihood getLikelihood(ArrayRef<const Attr *> Attrs);

  /// \returns the likelihood of a statement.
  static Likelihood getLikelihood(const Stmt *S);

  /// \returns the likelihood attribute of a statement.
  static const Attr *getLikelihoodAttr(const Stmt *S);

  /// \returns the likelihood of the 'then' branch of an 'if' statement. The
  /// 'else' branch is required to determine whether both branches specify the
  /// same likelihood, which affects the result.
  static Likelihood getLikelihood(const Stmt *Then, const Stmt *Else);

  /// \returns whether the likelihood of the branches of an if statement are
  /// conflicting. When the first element is \c true there's a conflict and
  /// the Attr's are the conflicting attributes of the Then and Else Stmt.
  static std::tuple<bool, const Attr *, const Attr *>
  determineLikelihoodConflict(const Stmt *Then, const Stmt *Else);

  /// Dumps the specified AST fragment and all subtrees to
  /// \c llvm::errs().
  void dump() const;
  void dump(raw_ostream &OS, const ASTContext &Context) const;

  /// \return Unique reproducible object identifier
  int64_t getID(const ASTContext &Context) const;

  /// dumpColor - same as dump(), but forces color highlighting.
  void dumpColor() const;

  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
  /// back to its original source language syntax.
  void dumpPretty(const ASTContext &Context) const;
  void printPretty(raw_ostream &OS, PrinterHelper *Helper,
                   const PrintingPolicy &Policy, unsigned Indentation = 0,
                   StringRef NewlineSymbol = "\n",
                   const ASTContext *Context = nullptr) const;
  void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper,
                             const PrintingPolicy &Policy,
                             unsigned Indentation = 0,
                             StringRef NewlineSymbol = "\n",
                             const ASTContext *Context = nullptr) const;

  /// Pretty-prints in JSON format.
  void printJson(raw_ostream &Out, PrinterHelper *Helper,
                 const PrintingPolicy &Policy, bool AddQuotes) const;

  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
  void viewAST() const;

  /// Skip no-op (attributed, compound) container stmts and skip captured
  /// stmt at the top, if \a IgnoreCaptured is true.
  Stmt *IgnoreContainers(bool IgnoreCaptured = false);
  const Stmt *IgnoreContainers(bool IgnoreCaptured = false) const {
    return const_cast<Stmt *>(this)->IgnoreContainers(IgnoreCaptured);
  }

  const Stmt *stripLabelLikeStatements() const;
  Stmt *stripLabelLikeStatements() {
    return const_cast<Stmt*>(
      const_cast<const Stmt*>(this)->stripLabelLikeStatements());
  }

  /// Child Iterators: All subclasses must implement 'children'
  /// to permit easy iteration over the substatements/subexpressions of an
  /// AST node.  This permits easy iteration over all nodes in the AST.
  using child_iterator = StmtIterator;
  using const_child_iterator = ConstStmtIterator;

  using child_range = llvm::iterator_range<child_iterator>;
  using const_child_range = llvm::iterator_range<const_child_iterator>;

  child_range children();

  const_child_range children() const {
    auto Children = const_cast<Stmt *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_iterator child_begin() { return children().begin(); }
  child_iterator child_end() { return children().end(); }

  const_child_iterator child_begin() const { return children().begin(); }
  const_child_iterator child_end() const { return children().end(); }

  /// Produce a unique representation of the given statement.
  ///
  /// \param ID once the profiling operation is complete, will contain
  /// the unique representation of the given statement.
  ///
  /// \param Context the AST context in which the statement resides
  ///
  /// \param Canonical whether the profile should be based on the canonical
  /// representation of this statement (e.g., where non-type template
  /// parameters are identified by index/level rather than their
  /// declaration pointers) or the exact representation of the statement as
  /// written in the source.
  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
               bool Canonical) const;

  /// Calculate a unique representation for a statement that is
  /// stable across compiler invocations.
  ///
  /// \param ID profile information will be stored in ID.
  ///
  /// \param Hash an ODRHash object which will be called where pointers would
  /// have been used in the Profile function.
  void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash& Hash) const;
};

/// DeclStmt - Adaptor class for mixing declarations with statements and
/// expressions. For example, CompoundStmt mixes statements, expressions
/// and declarations (variables, types). Another example is ForStmt, where
/// the first statement can be an expression or a declaration.
class DeclStmt : public Stmt {
  DeclGroupRef DG;
  SourceLocation StartLoc, EndLoc;

public:
  DeclStmt(DeclGroupRef dg, SourceLocation startLoc, SourceLocation endLoc)
      : Stmt(DeclStmtClass), DG(dg), StartLoc(startLoc), EndLoc(endLoc) {}

  /// Build an empty declaration statement.
  explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) {}

  /// isSingleDecl - This method returns true if this DeclStmt refers
  /// to a single Decl.
  bool isSingleDecl() const { return DG.isSingleDecl(); }

  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
  Decl *getSingleDecl() { return DG.getSingleDecl(); }

  const DeclGroupRef getDeclGroup() const { return DG; }
  DeclGroupRef getDeclGroup() { return DG; }
  void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }

  void setStartLoc(SourceLocation L) { StartLoc = L; }
  SourceLocation getEndLoc() const { return EndLoc; }
  void setEndLoc(SourceLocation L) { EndLoc = L; }

  SourceLocation getBeginLoc() const LLVM_READONLY { return StartLoc; }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == DeclStmtClass;
  }

  // Iterators over subexpressions.
  child_range children() {
    return child_range(child_iterator(DG.begin(), DG.end()),
                       child_iterator(DG.end(), DG.end()));
  }

  const_child_range children() const {
    auto Children = const_cast<DeclStmt *>(this)->children();
    return const_child_range(Children);
  }

  using decl_iterator = DeclGroupRef::iterator;
  using const_decl_iterator = DeclGroupRef::const_iterator;
  using decl_range = llvm::iterator_range<decl_iterator>;
  using decl_const_range = llvm::iterator_range<const_decl_iterator>;

  decl_range decls() { return decl_range(decl_begin(), decl_end()); }

  decl_const_range decls() const {
    return decl_const_range(decl_begin(), decl_end());
  }

  decl_iterator decl_begin() { return DG.begin(); }
  decl_iterator decl_end() { return DG.end(); }
  const_decl_iterator decl_begin() const { return DG.begin(); }
  const_decl_iterator decl_end() const { return DG.end(); }

  using reverse_decl_iterator = std::reverse_iterator<decl_iterator>;

  reverse_decl_iterator decl_rbegin() {
    return reverse_decl_iterator(decl_end());
  }

  reverse_decl_iterator decl_rend() {
    return reverse_decl_iterator(decl_begin());
  }
};

/// NullStmt - This is the null statement ";": C99 6.8.3p3.
///
class NullStmt : public Stmt {
public:
  NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
      : Stmt(NullStmtClass) {
    NullStmtBits.HasLeadingEmptyMacro = hasLeadingEmptyMacro;
    setSemiLoc(L);
  }

  /// Build an empty null statement.
  explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) {}

  SourceLocation getSemiLoc() const { return NullStmtBits.SemiLoc; }
  void setSemiLoc(SourceLocation L) { NullStmtBits.SemiLoc = L; }

  bool hasLeadingEmptyMacro() const {
    return NullStmtBits.HasLeadingEmptyMacro;
  }

  SourceLocation getBeginLoc() const { return getSemiLoc(); }
  SourceLocation getEndLoc() const { return getSemiLoc(); }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == NullStmtClass;
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }
};

/// CompoundStmt - This represents a group of statements like { stmt stmt }.
class CompoundStmt final
    : public Stmt,
      private llvm::TrailingObjects<CompoundStmt, Stmt *, FPOptionsOverride> {
  friend class ASTStmtReader;
  friend TrailingObjects;

  /// The location of the opening "{".
  SourceLocation LBraceLoc;

  /// The location of the closing "}".
  SourceLocation RBraceLoc;

  CompoundStmt(ArrayRef<Stmt *> Stmts, FPOptionsOverride FPFeatures,
               SourceLocation LB, SourceLocation RB);
  explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}

  void setStmts(ArrayRef<Stmt *> Stmts);

  /// Set FPOptionsOverride in trailing storage. Used only by Serialization.
  void setStoredFPFeatures(FPOptionsOverride F) {
    assert(hasStoredFPFeatures());
    *getTrailingObjects<FPOptionsOverride>() = F;
  }

  size_t numTrailingObjects(OverloadToken<Stmt *>) const {
    return CompoundStmtBits.NumStmts;
  }

public:
  static CompoundStmt *Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
                              FPOptionsOverride FPFeatures, SourceLocation LB,
                              SourceLocation RB);

  // Build an empty compound statement with a location.
  explicit CompoundStmt(SourceLocation Loc)
      : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(Loc) {
    CompoundStmtBits.NumStmts = 0;
    CompoundStmtBits.HasFPFeatures = 0;
  }

  // Build an empty compound statement.
  static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts,
                                   bool HasFPFeatures);

  bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
  unsigned size() const { return CompoundStmtBits.NumStmts; }

  bool hasStoredFPFeatures() const { return CompoundStmtBits.HasFPFeatures; }

  /// Get FPOptionsOverride from trailing storage.
  FPOptionsOverride getStoredFPFeatures() const {
    assert(hasStoredFPFeatures());
    return *getTrailingObjects<FPOptionsOverride>();
  }

  using body_iterator = Stmt **;
  using body_range = llvm::iterator_range<body_iterator>;

  body_range body() { return body_range(body_begin(), body_end()); }
  body_iterator body_begin() { return getTrailingObjects<Stmt *>(); }
  body_iterator body_end() { return body_begin() + size(); }
  Stmt *body_front() { return !body_empty() ? body_begin()[0] : nullptr; }

  Stmt *body_back() {
    return !body_empty() ? body_begin()[size() - 1] : nullptr;
  }

  using const_body_iterator = Stmt *const *;
  using body_const_range = llvm::iterator_range<const_body_iterator>;

  body_const_range body() const {
    return body_const_range(body_begin(), body_end());
  }

  const_body_iterator body_begin() const {
    return getTrailingObjects<Stmt *>();
  }

  const_body_iterator body_end() const { return body_begin() + size(); }

  const Stmt *body_front() const {
    return !body_empty() ? body_begin()[0] : nullptr;
  }

  const Stmt *body_back() const {
    return !body_empty() ? body_begin()[size() - 1] : nullptr;
  }

  using reverse_body_iterator = std::reverse_iterator<body_iterator>;

  reverse_body_iterator body_rbegin() {
    return reverse_body_iterator(body_end());
  }

  reverse_body_iterator body_rend() {
    return reverse_body_iterator(body_begin());
  }

  using const_reverse_body_iterator =
      std::reverse_iterator<const_body_iterator>;

  const_reverse_body_iterator body_rbegin() const {
    return const_reverse_body_iterator(body_end());
  }

  const_reverse_body_iterator body_rend() const {
    return const_reverse_body_iterator(body_begin());
  }

  // Get the Stmt that StmtExpr would consider to be the result of this
  // compound statement. This is used by StmtExpr to properly emulate the GCC
  // compound expression extension, which ignores trailing NullStmts when
  // getting the result of the expression.
  // i.e. ({ 5;;; })
  //           ^^ ignored
  // If we don't find something that isn't a NullStmt, just return the last
  // Stmt.
  Stmt *getStmtExprResult() {
    for (auto *B : llvm::reverse(body())) {
      if (!isa<NullStmt>(B))
        return B;
    }
    return body_back();
  }

  const Stmt *getStmtExprResult() const {
    return const_cast<CompoundStmt *>(this)->getStmtExprResult();
  }

  SourceLocation getBeginLoc() const { return LBraceLoc; }
  SourceLocation getEndLoc() const { return RBraceLoc; }

  SourceLocation getLBracLoc() const { return LBraceLoc; }
  SourceLocation getRBracLoc() const { return RBraceLoc; }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == CompoundStmtClass;
  }

  // Iterators
  child_range children() { return child_range(body_begin(), body_end()); }

  const_child_range children() const {
    return const_child_range(body_begin(), body_end());
  }
};

// SwitchCase is the base class for CaseStmt and DefaultStmt,
class SwitchCase : public Stmt {
protected:
  /// The location of the ":".
  SourceLocation ColonLoc;

  // The location of the "case" or "default" keyword. Stored in SwitchCaseBits.
  // SourceLocation KeywordLoc;

  /// A pointer to the following CaseStmt or DefaultStmt class,
  /// used by SwitchStmt.
  SwitchCase *NextSwitchCase = nullptr;

  SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
      : Stmt(SC), ColonLoc(ColonLoc) {
    setKeywordLoc(KWLoc);
  }

  SwitchCase(StmtClass SC, EmptyShell) : Stmt(SC) {}

public:
  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }

  SourceLocation getKeywordLoc() const { return SwitchCaseBits.KeywordLoc; }
  void setKeywordLoc(SourceLocation L) { SwitchCaseBits.KeywordLoc = L; }
  SourceLocation getColonLoc() const { return ColonLoc; }
  void setColonLoc(SourceLocation L) { ColonLoc = L; }

  inline Stmt *getSubStmt();
  const Stmt *getSubStmt() const {
    return const_cast<SwitchCase *>(this)->getSubStmt();
  }

  SourceLocation getBeginLoc() const { return getKeywordLoc(); }
  inline SourceLocation getEndLoc() const LLVM_READONLY;

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == CaseStmtClass ||
           T->getStmtClass() == DefaultStmtClass;
  }
};

/// CaseStmt - Represent a case statement. It can optionally be a GNU case
/// statement of the form LHS ... RHS representing a range of cases.
class CaseStmt final
    : public SwitchCase,
      private llvm::TrailingObjects<CaseStmt, Stmt *, SourceLocation> {
  friend TrailingObjects;

  // CaseStmt is followed by several trailing objects, some of which optional.
  // Note that it would be more convenient to put the optional trailing objects
  // at the end but this would impact children().
  // The trailing objects are in order:
  //
  // * A "Stmt *" for the LHS of the case statement. Always present.
  //
  // * A "Stmt *" for the RHS of the case statement. This is a GNU extension
  //   which allow ranges in cases statement of the form LHS ... RHS.
  //   Present if and only if caseStmtIsGNURange() is true.
  //
  // * A "Stmt *" for the substatement of the case statement. Always present.
  //
  // * A SourceLocation for the location of the ... if this is a case statement
  //   with a range. Present if and only if caseStmtIsGNURange() is true.
  enum { LhsOffset = 0, SubStmtOffsetFromRhs = 1 };
  enum { NumMandatoryStmtPtr = 2 };

  unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
    return NumMandatoryStmtPtr + caseStmtIsGNURange();
  }

  unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
    return caseStmtIsGNURange();
  }

  unsigned lhsOffset() const { return LhsOffset; }
  unsigned rhsOffset() const { return LhsOffset + caseStmtIsGNURange(); }
  unsigned subStmtOffset() const { return rhsOffset() + SubStmtOffsetFromRhs; }

  /// Build a case statement assuming that the storage for the
  /// trailing objects has been properly allocated.
  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
           SourceLocation ellipsisLoc, SourceLocation colonLoc)
      : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
    // Handle GNU case statements of the form LHS ... RHS.
    bool IsGNURange = rhs != nullptr;
    SwitchCaseBits.CaseStmtIsGNURange = IsGNURange;
    setLHS(lhs);
    setSubStmt(nullptr);
    if (IsGNURange) {
      setRHS(rhs);
      setEllipsisLoc(ellipsisLoc);
    }
  }

  /// Build an empty switch case statement.
  explicit CaseStmt(EmptyShell Empty, bool CaseStmtIsGNURange)
      : SwitchCase(CaseStmtClass, Empty) {
    SwitchCaseBits.CaseStmtIsGNURange = CaseStmtIsGNURange;
  }

public:
  /// Build a case statement.
  static CaseStmt *Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
                          SourceLocation caseLoc, SourceLocation ellipsisLoc,
                          SourceLocation colonLoc);

  /// Build an empty case statement.
  static CaseStmt *CreateEmpty(const ASTContext &Ctx, bool CaseStmtIsGNURange);

  /// True if this case statement is of the form case LHS ... RHS, which
  /// is a GNU extension. In this case the RHS can be obtained with getRHS()
  /// and the location of the ellipsis can be obtained with getEllipsisLoc().
  bool caseStmtIsGNURange() const { return SwitchCaseBits.CaseStmtIsGNURange; }

  SourceLocation getCaseLoc() const { return getKeywordLoc(); }
  void setCaseLoc(SourceLocation L) { setKeywordLoc(L); }

  /// Get the location of the ... in a case statement of the form LHS ... RHS.
  SourceLocation getEllipsisLoc() const {
    return caseStmtIsGNURange() ? *getTrailingObjects<SourceLocation>()
                                : SourceLocation();
  }

  /// Set the location of the ... in a case statement of the form LHS ... RHS.
  /// Assert that this case statement is of this form.
  void setEllipsisLoc(SourceLocation L) {
    assert(
        caseStmtIsGNURange() &&
        "setEllipsisLoc but this is not a case stmt of the form LHS ... RHS!");
    *getTrailingObjects<SourceLocation>() = L;
  }

  Expr *getLHS() {
    return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[lhsOffset()]);
  }

  const Expr *getLHS() const {
    return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[lhsOffset()]);
  }

  void setLHS(Expr *Val) {
    getTrailingObjects<Stmt *>()[lhsOffset()] = reinterpret_cast<Stmt *>(Val);
  }

  Expr *getRHS() {
    return caseStmtIsGNURange() ? reinterpret_cast<Expr *>(
                                      getTrailingObjects<Stmt *>()[rhsOffset()])
                                : nullptr;
  }

  const Expr *getRHS() const {
    return caseStmtIsGNURange() ? reinterpret_cast<Expr *>(
                                      getTrailingObjects<Stmt *>()[rhsOffset()])
                                : nullptr;
  }

  void setRHS(Expr *Val) {
    assert(caseStmtIsGNURange() &&
           "setRHS but this is not a case stmt of the form LHS ... RHS!");
    getTrailingObjects<Stmt *>()[rhsOffset()] = reinterpret_cast<Stmt *>(Val);
  }

  Stmt *getSubStmt() { return getTrailingObjects<Stmt *>()[subStmtOffset()]; }
  const Stmt *getSubStmt() const {
    return getTrailingObjects<Stmt *>()[subStmtOffset()];
  }

  void setSubStmt(Stmt *S) {
    getTrailingObjects<Stmt *>()[subStmtOffset()] = S;
  }

  SourceLocation getBeginLoc() const { return getKeywordLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY {
    // Handle deeply nested case statements with iteration instead of recursion.
    const CaseStmt *CS = this;
    while (const auto *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
      CS = CS2;

    return CS->getSubStmt()->getEndLoc();
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == CaseStmtClass;
  }

  // Iterators
  child_range children() {
    return child_range(getTrailingObjects<Stmt *>(),
                       getTrailingObjects<Stmt *>() +
                           numTrailingObjects(OverloadToken<Stmt *>()));
  }

  const_child_range children() const {
    return const_child_range(getTrailingObjects<Stmt *>(),
                             getTrailingObjects<Stmt *>() +
                                 numTrailingObjects(OverloadToken<Stmt *>()));
  }
};

class DefaultStmt : public SwitchCase {
  Stmt *SubStmt;

public:
  DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt)
      : SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}

  /// Build an empty default statement.
  explicit DefaultStmt(EmptyShell Empty)
      : SwitchCase(DefaultStmtClass, Empty) {}

  Stmt *getSubStmt() { return SubStmt; }
  const Stmt *getSubStmt() const { return SubStmt; }
  void setSubStmt(Stmt *S) { SubStmt = S; }

  SourceLocation getDefaultLoc() const { return getKeywordLoc(); }
  void setDefaultLoc(SourceLocation L) { setKeywordLoc(L); }

  SourceLocation getBeginLoc() const { return getKeywordLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY {
    return SubStmt->getEndLoc();
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == DefaultStmtClass;
  }

  // Iterators
  child_range children() { return child_range(&SubStmt, &SubStmt + 1); }

  const_child_range children() const {
    return const_child_range(&SubStmt, &SubStmt + 1);
  }
};

SourceLocation SwitchCase::getEndLoc() const {
  if (const auto *CS = dyn_cast<CaseStmt>(this))
    return CS->getEndLoc();
  else if (const auto *DS = dyn_cast<DefaultStmt>(this))
    return DS->getEndLoc();
  llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
}

Stmt *SwitchCase::getSubStmt() {
  if (auto *CS = dyn_cast<CaseStmt>(this))
    return CS->getSubStmt();
  else if (auto *DS = dyn_cast<DefaultStmt>(this))
    return DS->getSubStmt();
  llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
}

/// Represents a statement that could possibly have a value and type. This
/// covers expression-statements, as well as labels and attributed statements.
///
/// Value statements have a special meaning when they are the last non-null
/// statement in a GNU statement expression, where they determine the value
/// of the statement expression.
class ValueStmt : public Stmt {
protected:
  using Stmt::Stmt;

public:
  const Expr *getExprStmt() const;
  Expr *getExprStmt() {
    const ValueStmt *ConstThis = this;
    return const_cast<Expr*>(ConstThis->getExprStmt());
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() >= firstValueStmtConstant &&
           T->getStmtClass() <= lastValueStmtConstant;
  }
};

/// LabelStmt - Represents a label, which has a substatement.  For example:
///    foo: return;
class LabelStmt : public ValueStmt {
  LabelDecl *TheDecl;
  Stmt *SubStmt;
  bool SideEntry = false;

public:
  /// Build a label statement.
  LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
      : ValueStmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) {
    setIdentLoc(IL);
  }

  /// Build an empty label statement.
  explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {}

  SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; }
  void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; }

  LabelDecl *getDecl() const { return TheDecl; }
  void setDecl(LabelDecl *D) { TheDecl = D; }

  const char *getName() const;
  Stmt *getSubStmt() { return SubStmt; }

  const Stmt *getSubStmt() const { return SubStmt; }
  void setSubStmt(Stmt *SS) { SubStmt = SS; }

  SourceLocation getBeginLoc() const { return getIdentLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY { return SubStmt->getEndLoc();}

  child_range children() { return child_range(&SubStmt, &SubStmt + 1); }

  const_child_range children() const {
    return const_child_range(&SubStmt, &SubStmt + 1);
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == LabelStmtClass;
  }
  bool isSideEntry() const { return SideEntry; }
  void setSideEntry(bool SE) { SideEntry = SE; }
};

/// Represents an attribute applied to a statement.
///
/// Represents an attribute applied to a statement. For example:
///   [[omp::for(...)]] for (...) { ... }
class AttributedStmt final
    : public ValueStmt,
      private llvm::TrailingObjects<AttributedStmt, const Attr *> {
  friend class ASTStmtReader;
  friend TrailingObjects;

  Stmt *SubStmt;

  AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs,
                 Stmt *SubStmt)
      : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) {
    AttributedStmtBits.NumAttrs = Attrs.size();
    AttributedStmtBits.AttrLoc = Loc;
    std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
  }

  explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
      : ValueStmt(AttributedStmtClass, Empty) {
    AttributedStmtBits.NumAttrs = NumAttrs;
    AttributedStmtBits.AttrLoc = SourceLocation{};
    std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
  }

  const Attr *const *getAttrArrayPtr() const {
    return getTrailingObjects<const Attr *>();
  }
  const Attr **getAttrArrayPtr() { return getTrailingObjects<const Attr *>(); }

public:
  static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
                                ArrayRef<const Attr *> Attrs, Stmt *SubStmt);

  // Build an empty attributed statement.
  static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);

  SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; }
  ArrayRef<const Attr *> getAttrs() const {
    return llvm::makeArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs);
  }

  Stmt *getSubStmt() { return SubStmt; }
  const Stmt *getSubStmt() const { return SubStmt; }

  SourceLocation getBeginLoc() const { return getAttrLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY { return SubStmt->getEndLoc();}

  child_range children() { return child_range(&SubStmt, &SubStmt + 1); }

  const_child_range children() const {
    return const_child_range(&SubStmt, &SubStmt + 1);
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == AttributedStmtClass;
  }
};

/// IfStmt - This represents an if/then/else.
class IfStmt final
    : public Stmt,
      private llvm::TrailingObjects<IfStmt, Stmt *, SourceLocation> {
  friend TrailingObjects;

  // IfStmt is followed by several trailing objects, some of which optional.
  // Note that it would be more convenient to put the optional trailing
  // objects at then end but this would change the order of the children.
  // The trailing objects are in order:
  //
  // * A "Stmt *" for the init statement.
  //    Present if and only if hasInitStorage().
  //
  // * A "Stmt *" for the condition variable.
  //    Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
  //
  // * A "Stmt *" for the condition.
  //    Always present. This is in fact a "Expr *".
  //
  // * A "Stmt *" for the then statement.
  //    Always present.
  //
  // * A "Stmt *" for the else statement.
  //    Present if and only if hasElseStorage().
  //
  // * A "SourceLocation" for the location of the "else".
  //    Present if and only if hasElseStorage().
  enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 };
  enum { NumMandatoryStmtPtr = 2 };
  SourceLocation LParenLoc;
  SourceLocation RParenLoc;

  unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
    return NumMandatoryStmtPtr + hasElseStorage() + hasVarStorage() +
           hasInitStorage();
  }

  unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
    return hasElseStorage();
  }

  unsigned initOffset() const { return InitOffset; }
  unsigned varOffset() const { return InitOffset + hasInitStorage(); }
  unsigned condOffset() const {
    return InitOffset + hasInitStorage() + hasVarStorage();
  }
  unsigned thenOffset() const { return condOffset() + ThenOffsetFromCond; }
  unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; }

  /// Build an if/then/else statement.
  IfStmt(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind,
         Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc,
         SourceLocation RParenLoc, Stmt *Then, SourceLocation EL, Stmt *Else);

  /// Build an empty if/then/else statement.
  explicit IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit);

public:
  /// Create an IfStmt.
  static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL,
                        IfStatementKind Kind, Stmt *Init, VarDecl *Var,
                        Expr *Cond, SourceLocation LPL, SourceLocation RPL,
                        Stmt *Then, SourceLocation EL = SourceLocation(),
                        Stmt *Else = nullptr);

  /// Create an empty IfStmt optionally with storage for an else statement,
  /// condition variable and init expression.
  static IfStmt *CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
                             bool HasInit);

  /// True if this IfStmt has the storage for an init statement.
  bool hasInitStorage() const { return IfStmtBits.HasInit; }

  /// True if this IfStmt has storage for a variable declaration.
  bool hasVarStorage() const { return IfStmtBits.HasVar; }

  /// True if this IfStmt has storage for an else statement.
  bool hasElseStorage() const { return IfStmtBits.HasElse; }

  Expr *getCond() {
    return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
  }

  const Expr *getCond() const {
    return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
  }

  void setCond(Expr *Cond) {
    getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
  }

  Stmt *getThen() { return getTrailingObjects<Stmt *>()[thenOffset()]; }
  const Stmt *getThen() const {
    return getTrailingObjects<Stmt *>()[thenOffset()];
  }

  void setThen(Stmt *Then) {
    getTrailingObjects<Stmt *>()[thenOffset()] = Then;
  }

  Stmt *getElse() {
    return hasElseStorage() ? getTrailingObjects<Stmt *>()[elseOffset()]
                            : nullptr;
  }

  const Stmt *getElse() const {
    return hasElseStorage() ? getTrailingObjects<Stmt *>()[elseOffset()]
                            : nullptr;
  }

  void setElse(Stmt *Else) {
    assert(hasElseStorage() &&
           "This if statement has no storage for an else statement!");
    getTrailingObjects<Stmt *>()[elseOffset()] = Else;
  }

  /// Retrieve the variable declared in this "if" statement, if any.
  ///
  /// In the following example, "x" is the condition variable.
  /// \code
  /// if (int x = foo()) {
  ///   printf("x is %d", x);
  /// }
  /// \endcode
  VarDecl *getConditionVariable();
  const VarDecl *getConditionVariable() const {
    return const_cast<IfStmt *>(this)->getConditionVariable();
  }

  /// Set the condition variable for this if statement.
  /// The if statement must have storage for the condition variable.
  void setConditionVariable(const ASTContext &Ctx, VarDecl *V);

  /// If this IfStmt has a condition variable, return the faux DeclStmt
  /// associated with the creation of that condition variable.
  DeclStmt *getConditionVariableDeclStmt() {
    return hasVarStorage() ? static_cast<DeclStmt *>(
                                 getTrailingObjects<Stmt *>()[varOffset()])
                           : nullptr;
  }

  const DeclStmt *getConditionVariableDeclStmt() const {
    return hasVarStorage() ? static_cast<DeclStmt *>(
                                 getTrailingObjects<Stmt *>()[varOffset()])
                           : nullptr;
  }

  Stmt *getInit() {
    return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
                            : nullptr;
  }

  const Stmt *getInit() const {
    return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
                            : nullptr;
  }

  void setInit(Stmt *Init) {
    assert(hasInitStorage() &&
           "This if statement has no storage for an init statement!");
    getTrailingObjects<Stmt *>()[initOffset()] = Init;
  }

  SourceLocation getIfLoc() const { return IfStmtBits.IfLoc; }
  void setIfLoc(SourceLocation IfLoc) { IfStmtBits.IfLoc = IfLoc; }

  SourceLocation getElseLoc() const {
    return hasElseStorage() ? *getTrailingObjects<SourceLocation>()
                            : SourceLocation();
  }

  void setElseLoc(SourceLocation ElseLoc) {
    assert(hasElseStorage() &&
           "This if statement has no storage for an else statement!");
    *getTrailingObjects<SourceLocation>() = ElseLoc;
  }

  bool isConsteval() const {
    return getStatementKind() == IfStatementKind::ConstevalNonNegated ||
           getStatementKind() == IfStatementKind::ConstevalNegated;
  }

  bool isNonNegatedConsteval() const {
    return getStatementKind() == IfStatementKind::ConstevalNonNegated;
  }

  bool isNegatedConsteval() const {
    return getStatementKind() == IfStatementKind::ConstevalNegated;
  }

  bool isConstexpr() const {
    return getStatementKind() == IfStatementKind::Constexpr;
  }

  void setStatementKind(IfStatementKind Kind) {
    IfStmtBits.Kind = static_cast<unsigned>(Kind);
  }

  IfStatementKind getStatementKind() const {
    return static_cast<IfStatementKind>(IfStmtBits.Kind);
  }

  /// If this is an 'if constexpr', determine which substatement will be taken.
  /// Otherwise, or if the condition is value-dependent, returns None.
  Optional<const Stmt*> getNondiscardedCase(const ASTContext &Ctx) const;
  Optional<Stmt *> getNondiscardedCase(const ASTContext &Ctx);

  bool isObjCAvailabilityCheck() const;

  SourceLocation getBeginLoc() const { return getIfLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY {
    if (getElse())
      return getElse()->getEndLoc();
    return getThen()->getEndLoc();
  }
  SourceLocation getLParenLoc() const { return LParenLoc; }
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }

  // Iterators over subexpressions.  The iterators will include iterating
  // over the initialization expression referenced by the condition variable.
  child_range children() {
    // We always store a condition, but there is none for consteval if
    // statements, so skip it.
    return child_range(getTrailingObjects<Stmt *>() +
                           (isConsteval() ? thenOffset() : 0),
                       getTrailingObjects<Stmt *>() +
                           numTrailingObjects(OverloadToken<Stmt *>()));
  }

  const_child_range children() const {
    // We always store a condition, but there is none for consteval if
    // statements, so skip it.
    return const_child_range(getTrailingObjects<Stmt *>() +
                                 (isConsteval() ? thenOffset() : 0),
                             getTrailingObjects<Stmt *>() +
                                 numTrailingObjects(OverloadToken<Stmt *>()));
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == IfStmtClass;
  }
};

/// SwitchStmt - This represents a 'switch' stmt.
class SwitchStmt final : public Stmt,
                         private llvm::TrailingObjects<SwitchStmt, Stmt *> {
  friend TrailingObjects;

  /// Points to a linked list of case and default statements.
  SwitchCase *FirstCase = nullptr;

  // SwitchStmt is followed by several trailing objects,
  // some of which optional. Note that it would be more convenient to
  // put the optional trailing objects at the end but this would change
  // the order in children().
  // The trailing objects are in order:
  //
  // * A "Stmt *" for the init statement.
  //    Present if and only if hasInitStorage().
  //
  // * A "Stmt *" for the condition variable.
  //    Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
  //
  // * A "Stmt *" for the condition.
  //    Always present. This is in fact an "Expr *".
  //
  // * A "Stmt *" for the body.
  //    Always present.
  enum { InitOffset = 0, BodyOffsetFromCond = 1 };
  enum { NumMandatoryStmtPtr = 2 };
  SourceLocation LParenLoc;
  SourceLocation RParenLoc;

  unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
    return NumMandatoryStmtPtr + hasInitStorage() + hasVarStorage();
  }

  unsigned initOffset() const { return InitOffset; }
  unsigned varOffset() const { return InitOffset + hasInitStorage(); }
  unsigned condOffset() const {
    return InitOffset + hasInitStorage() + hasVarStorage();
  }
  unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }

  /// Build a switch statement.
  SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond,
             SourceLocation LParenLoc, SourceLocation RParenLoc);

  /// Build a empty switch statement.
  explicit SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar);

public:
  /// Create a switch statement.
  static SwitchStmt *Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
                            Expr *Cond, SourceLocation LParenLoc,
                            SourceLocation RParenLoc);

  /// Create an empty switch statement optionally with storage for
  /// an init expression and a condition variable.
  static SwitchStmt *CreateEmpty(const ASTContext &Ctx, bool HasInit,
                                 bool HasVar);

  /// True if this SwitchStmt has storage for an init statement.
  bool hasInitStorage() const { return SwitchStmtBits.HasInit; }

  /// True if this SwitchStmt has storage for a condition variable.
  bool hasVarStorage() const { return SwitchStmtBits.HasVar; }

  Expr *getCond() {
    return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
  }

  const Expr *getCond() const {
    return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
  }

  void setCond(Expr *Cond) {
    getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
  }

  Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
  const Stmt *getBody() const {
    return getTrailingObjects<Stmt *>()[bodyOffset()];
  }

  void setBody(Stmt *Body) {
    getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
  }

  Stmt *getInit() {
    return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
                            : nullptr;
  }

  const Stmt *getInit() const {
    return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
                            : nullptr;
  }

  void setInit(Stmt *Init) {
    assert(hasInitStorage() &&
           "This switch statement has no storage for an init statement!");
    getTrailingObjects<Stmt *>()[initOffset()] = Init;
  }

  /// Retrieve the variable declared in this "switch" statement, if any.
  ///
  /// In the following example, "x" is the condition variable.
  /// \code
  /// switch (int x = foo()) {
  ///   case 0: break;
  ///   // ...
  /// }
  /// \endcode
  VarDecl *getConditionVariable();
  const VarDecl *getConditionVariable() const {
    return const_cast<SwitchStmt *>(this)->getConditionVariable();
  }

  /// Set the condition variable in this switch statement.
  /// The switch statement must have storage for it.
  void setConditionVariable(const ASTContext &Ctx, VarDecl *VD);

  /// If this SwitchStmt has a condition variable, return the faux DeclStmt
  /// associated with the creation of that condition variable.
  DeclStmt *getConditionVariableDeclStmt() {
    return hasVarStorage() ? static_cast<DeclStmt *>(
                                 getTrailingObjects<Stmt *>()[varOffset()])
                           : nullptr;
  }

  const DeclStmt *getConditionVariableDeclStmt() const {
    return hasVarStorage() ? static_cast<DeclStmt *>(
                                 getTrailingObjects<Stmt *>()[varOffset()])
                           : nullptr;
  }

  SwitchCase *getSwitchCaseList() { return FirstCase; }
  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
  void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }

  SourceLocation getSwitchLoc() const { return SwitchStmtBits.SwitchLoc; }
  void setSwitchLoc(SourceLocation L) { SwitchStmtBits.SwitchLoc = L; }
  SourceLocation getLParenLoc() const { return LParenLoc; }
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }

  void setBody(Stmt *S, SourceLocation SL) {
    setBody(S);
    setSwitchLoc(SL);
  }

  void addSwitchCase(SwitchCase *SC) {
    assert(!SC->getNextSwitchCase() &&
           "case/default already added to a switch");
    SC->setNextSwitchCase(FirstCase);
    FirstCase = SC;
  }

  /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
  /// switch over an enum value then all cases have been explicitly covered.
  void setAllEnumCasesCovered() { SwitchStmtBits.AllEnumCasesCovered = true; }

  /// Returns true if the SwitchStmt is a switch of an enum value and all cases
  /// have been explicitly covered.
  bool isAllEnumCasesCovered() const {
    return SwitchStmtBits.AllEnumCasesCovered;
  }

  SourceLocation getBeginLoc() const { return getSwitchLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY {
    return getBody() ? getBody()->getEndLoc()
                     : reinterpret_cast<const Stmt *>(getCond())->getEndLoc();
  }

  // Iterators
  child_range children() {
    return child_range(getTrailingObjects<Stmt *>(),
                       getTrailingObjects<Stmt *>() +
                           numTrailingObjects(OverloadToken<Stmt *>()));
  }

  const_child_range children() const {
    return const_child_range(getTrailingObjects<Stmt *>(),
                             getTrailingObjects<Stmt *>() +
                                 numTrailingObjects(OverloadToken<Stmt *>()));
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == SwitchStmtClass;
  }
};

/// WhileStmt - This represents a 'while' stmt.
class WhileStmt final : public Stmt,
                        private llvm::TrailingObjects<WhileStmt, Stmt *> {
  friend TrailingObjects;

  // WhileStmt is followed by several trailing objects,
  // some of which optional. Note that it would be more
  // convenient to put the optional trailing object at the end
  // but this would affect children().
  // The trailing objects are in order:
  //
  // * A "Stmt *" for the condition variable.
  //    Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
  //
  // * A "Stmt *" for the condition.
  //    Always present. This is in fact an "Expr *".
  //
  // * A "Stmt *" for the body.
  //    Always present.
  //
  enum { VarOffset = 0, BodyOffsetFromCond = 1 };
  enum { NumMandatoryStmtPtr = 2 };

  SourceLocation LParenLoc, RParenLoc;

  unsigned varOffset() const { return VarOffset; }
  unsigned condOffset() const { return VarOffset + hasVarStorage(); }
  unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }

  unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
    return NumMandatoryStmtPtr + hasVarStorage();
  }

  /// Build a while statement.
  WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body,
            SourceLocation WL, SourceLocation LParenLoc,
            SourceLocation RParenLoc);

  /// Build an empty while statement.
  explicit WhileStmt(EmptyShell Empty, bool HasVar);

public:
  /// Create a while statement.
  static WhileStmt *Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
                           Stmt *Body, SourceLocation WL,
                           SourceLocation LParenLoc, SourceLocation RParenLoc);

  /// Create an empty while statement optionally with storage for
  /// a condition variable.
  static WhileStmt *CreateEmpty(const ASTContext &Ctx, bool HasVar);

  /// True if this WhileStmt has storage for a condition variable.
  bool hasVarStorage() const { return WhileStmtBits.HasVar; }

  Expr *getCond() {
    return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
  }

  const Expr *getCond() const {
    return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
  }

  void setCond(Expr *Cond) {
    getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
  }

  Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
  const Stmt *getBody() const {
    return getTrailingObjects<Stmt *>()[bodyOffset()];
  }

  void setBody(Stmt *Body) {
    getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
  }

  /// Retrieve the variable declared in this "while" statement, if any.
  ///
  /// In the following example, "x" is the condition variable.
  /// \code
  /// while (int x = random()) {
  ///   // ...
  /// }
  /// \endcode
  VarDecl *getConditionVariable();
  const VarDecl *getConditionVariable() const {
    return const_cast<WhileStmt *>(this)->getConditionVariable();
  }

  /// Set the condition variable of this while statement.
  /// The while statement must have storage for it.
  void setConditionVariable(const ASTContext &Ctx, VarDecl *V);

  /// If this WhileStmt has a condition variable, return the faux DeclStmt
  /// associated with the creation of that condition variable.
  DeclStmt *getConditionVariableDeclStmt() {
    return hasVarStorage() ? static_cast<DeclStmt *>(
                                 getTrailingObjects<Stmt *>()[varOffset()])
                           : nullptr;
  }

  const DeclStmt *getConditionVariableDeclStmt() const {
    return hasVarStorage() ? static_cast<DeclStmt *>(
                                 getTrailingObjects<Stmt *>()[varOffset()])
                           : nullptr;
  }

  SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
  void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }

  SourceLocation getLParenLoc() const { return LParenLoc; }
  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setRParenLoc(SourceLocation L) { RParenLoc = L; }

  SourceLocation getBeginLoc() const { return getWhileLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY {
    return getBody()->getEndLoc();
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == WhileStmtClass;
  }

  // Iterators
  child_range children() {
    return child_range(getTrailingObjects<Stmt *>(),
                       getTrailingObjects<Stmt *>() +
                           numTrailingObjects(OverloadToken<Stmt *>()));
  }

  const_child_range children() const {
    return const_child_range(getTrailingObjects<Stmt *>(),
                             getTrailingObjects<Stmt *>() +
                                 numTrailingObjects(OverloadToken<Stmt *>()));
  }
};

/// DoStmt - This represents a 'do/while' stmt.
class DoStmt : public Stmt {
  enum { BODY, COND, END_EXPR };
  Stmt *SubExprs[END_EXPR];
  SourceLocation WhileLoc;
  SourceLocation RParenLoc; // Location of final ')' in do stmt condition.

public:
  DoStmt(Stmt *Body, Expr *Cond, SourceLocation DL, SourceLocation WL,
         SourceLocation RP)
      : Stmt(DoStmtClass), WhileLoc(WL), RParenLoc(RP) {
    setCond(Cond);
    setBody(Body);
    setDoLoc(DL);
  }

  /// Build an empty do-while statement.
  explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) {}

  Expr *getCond() { return reinterpret_cast<Expr *>(SubExprs[COND]); }
  const Expr *getCond() const {
    return reinterpret_cast<Expr *>(SubExprs[COND]);
  }

  void setCond(Expr *Cond) { SubExprs[COND] = reinterpret_cast<Stmt *>(Cond); }

  Stmt *getBody() { return SubExprs[BODY]; }
  const Stmt *getBody() const { return SubExprs[BODY]; }
  void setBody(Stmt *Body) { SubExprs[BODY] = Body; }

  SourceLocation getDoLoc() const { return DoStmtBits.DoLoc; }
  void setDoLoc(SourceLocation L) { DoStmtBits.DoLoc = L; }
  SourceLocation getWhileLoc() const { return WhileLoc; }
  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setRParenLoc(SourceLocation L) { RParenLoc = L; }

  SourceLocation getBeginLoc() const { return getDoLoc(); }
  SourceLocation getEndLoc() const { return getRParenLoc(); }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == DoStmtClass;
  }

  // Iterators
  child_range children() {
    return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
  }

  const_child_range children() const {
    return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
  }
};

/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
/// the init/cond/inc parts of the ForStmt will be null if they were not
/// specified in the source.
class ForStmt : public Stmt {
  enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
  SourceLocation LParenLoc, RParenLoc;

public:
  ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
          Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
          SourceLocation RP);

  /// Build an empty for statement.
  explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) {}

  Stmt *getInit() { return SubExprs[INIT]; }

  /// Retrieve the variable declared in this "for" statement, if any.
  ///
  /// In the following example, "y" is the condition variable.
  /// \code
  /// for (int x = random(); int y = mangle(x); ++x) {
  ///   // ...
  /// }
  /// \endcode
  VarDecl *getConditionVariable() const;
  void setConditionVariable(const ASTContext &C, VarDecl *V);

  /// If this ForStmt has a condition variable, return the faux DeclStmt
  /// associated with the creation of that condition variable.
  const DeclStmt *getConditionVariableDeclStmt() const {
    return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
  }

  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
  Stmt *getBody() { return SubExprs[BODY]; }

  const Stmt *getInit() const { return SubExprs[INIT]; }
  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
  const Stmt *getBody() const { return SubExprs[BODY]; }

  void setInit(Stmt *S) { SubExprs[INIT] = S; }
  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
  void setBody(Stmt *S) { SubExprs[BODY] = S; }

  SourceLocation getForLoc() const { return ForStmtBits.ForLoc; }
  void setForLoc(SourceLocation L) { ForStmtBits.ForLoc = L; }
  SourceLocation getLParenLoc() const { return LParenLoc; }
  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setRParenLoc(SourceLocation L) { RParenLoc = L; }

  SourceLocation getBeginLoc() const { return getForLoc(); }
  SourceLocation getEndLoc() const { return getBody()->getEndLoc(); }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == ForStmtClass;
  }

  // Iterators
  child_range children() {
    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
  }

  const_child_range children() const {
    return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
  }
};

/// GotoStmt - This represents a direct goto.
class GotoStmt : public Stmt {
  LabelDecl *Label;
  SourceLocation LabelLoc;

public:
  GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
      : Stmt(GotoStmtClass), Label(label), LabelLoc(LL) {
    setGotoLoc(GL);
  }

  /// Build an empty goto statement.
  explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) {}

  LabelDecl *getLabel() const { return Label; }
  void setLabel(LabelDecl *D) { Label = D; }

  SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
  void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
  SourceLocation getLabelLoc() const { return LabelLoc; }
  void setLabelLoc(SourceLocation L) { LabelLoc = L; }

  SourceLocation getBeginLoc() const { return getGotoLoc(); }
  SourceLocation getEndLoc() const { return getLabelLoc(); }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == GotoStmtClass;
  }

  // Iterators
  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }
};

/// IndirectGotoStmt - This represents an indirect goto.
class IndirectGotoStmt : public Stmt {
  SourceLocation StarLoc;
  Stmt *Target;

public:
  IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, Expr *target)
      : Stmt(IndirectGotoStmtClass), StarLoc(starLoc) {
    setTarget(target);
    setGotoLoc(gotoLoc);
  }

  /// Build an empty indirect goto statement.
  explicit IndirectGotoStmt(EmptyShell Empty)
      : Stmt(IndirectGotoStmtClass, Empty) {}

  void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
  SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
  void setStarLoc(SourceLocation L) { StarLoc = L; }
  SourceLocation getStarLoc() const { return StarLoc; }

  Expr *getTarget() { return reinterpret_cast<Expr *>(Target); }
  const Expr *getTarget() const {
    return reinterpret_cast<const Expr *>(Target);
  }
  void setTarget(Expr *E) { Target = reinterpret_cast<Stmt *>(E); }

  /// getConstantTarget - Returns the fixed target of this indirect
  /// goto, if one exists.
  LabelDecl *getConstantTarget();
  const LabelDecl *getConstantTarget() const {
    return const_cast<IndirectGotoStmt *>(this)->getConstantTarget();
  }

  SourceLocation getBeginLoc() const { return getGotoLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY { return Target->getEndLoc(); }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == IndirectGotoStmtClass;
  }

  // Iterators
  child_range children() { return child_range(&Target, &Target + 1); }

  const_child_range children() const {
    return const_child_range(&Target, &Target + 1);
  }
};

/// ContinueStmt - This represents a continue.
class ContinueStmt : public Stmt {
public:
  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass) {
    setContinueLoc(CL);
  }

  /// Build an empty continue statement.
  explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) {}

  SourceLocation getContinueLoc() const { return ContinueStmtBits.ContinueLoc; }
  void setContinueLoc(SourceLocation L) { ContinueStmtBits.ContinueLoc = L; }

  SourceLocation getBeginLoc() const { return getContinueLoc(); }
  SourceLocation getEndLoc() const { return getContinueLoc(); }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == ContinueStmtClass;
  }

  // Iterators
  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }
};

/// BreakStmt - This represents a break.
class BreakStmt : public Stmt {
public:
  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass) {
    setBreakLoc(BL);
  }

  /// Build an empty break statement.
  explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) {}

  SourceLocation getBreakLoc() const { return BreakStmtBits.BreakLoc; }
  void setBreakLoc(SourceLocation L) { BreakStmtBits.BreakLoc = L; }

  SourceLocation getBeginLoc() const { return getBreakLoc(); }
  SourceLocation getEndLoc() const { return getBreakLoc(); }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == BreakStmtClass;
  }

  // Iterators
  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }
};

/// ReturnStmt - This represents a return, optionally of an expression:
///   return;
///   return 4;
///
/// Note that GCC allows return with no argument in a function declared to
/// return a value, and it allows returning a value in functions declared to
/// return void.  We explicitly model this in the AST, which means you can't
/// depend on the return type of the function and the presence of an argument.
class ReturnStmt final
    : public Stmt,
      private llvm::TrailingObjects<ReturnStmt, const VarDecl *> {
  friend TrailingObjects;

  /// The return expression.
  Stmt *RetExpr;

  // ReturnStmt is followed optionally by a trailing "const VarDecl *"
  // for the NRVO candidate. Present if and only if hasNRVOCandidate().

  /// True if this ReturnStmt has storage for an NRVO candidate.
  bool hasNRVOCandidate() const { return ReturnStmtBits.HasNRVOCandidate; }

  unsigned numTrailingObjects(OverloadToken<const VarDecl *>) const {
    return hasNRVOCandidate();
  }

  /// Build a return statement.
  ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate);

  /// Build an empty return statement.
  explicit ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate);

public:
  /// Create a return statement.
  static ReturnStmt *Create(const ASTContext &Ctx, SourceLocation RL, Expr *E,
                            const VarDecl *NRVOCandidate);

  /// Create an empty return statement, optionally with
  /// storage for an NRVO candidate.
  static ReturnStmt *CreateEmpty(const ASTContext &Ctx, bool HasNRVOCandidate);

  Expr *getRetValue() { return reinterpret_cast<Expr *>(RetExpr); }
  const Expr *getRetValue() const { return reinterpret_cast<Expr *>(RetExpr); }
  void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt *>(E); }

  /// Retrieve the variable that might be used for the named return
  /// value optimization.
  ///
  /// The optimization itself can only be performed if the variable is
  /// also marked as an NRVO object.
  const VarDecl *getNRVOCandidate() const {
    return hasNRVOCandidate() ? *getTrailingObjects<const VarDecl *>()
                              : nullptr;
  }

  /// Set the variable that might be used for the named return value
  /// optimization. The return statement must have storage for it,
  /// which is the case if and only if hasNRVOCandidate() is true.
  void setNRVOCandidate(const VarDecl *Var) {
    assert(hasNRVOCandidate() &&
           "This return statement has no storage for an NRVO candidate!");
    *getTrailingObjects<const VarDecl *>() = Var;
  }

  SourceLocation getReturnLoc() const { return ReturnStmtBits.RetLoc; }
  void setReturnLoc(SourceLocation L) { ReturnStmtBits.RetLoc = L; }

  SourceLocation getBeginLoc() const { return getReturnLoc(); }
  SourceLocation getEndLoc() const LLVM_READONLY {
    return RetExpr ? RetExpr->getEndLoc() : getReturnLoc();
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == ReturnStmtClass;
  }

  // Iterators
  child_range children() {
    if (RetExpr)
      return child_range(&RetExpr, &RetExpr + 1);
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    if (RetExpr)
      return const_child_range(&RetExpr, &RetExpr + 1);
    return const_child_range(const_child_iterator(), const_child_iterator());
  }
};

/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
class AsmStmt : public Stmt {
protected:
  friend class ASTStmtReader;

  SourceLocation AsmLoc;

  /// True if the assembly statement does not have any input or output
  /// operands.
  bool IsSimple;

  /// If true, treat this inline assembly as having side effects.
  /// This assembly statement should not be optimized, deleted or moved.
  bool IsVolatile;

  unsigned NumOutputs;
  unsigned NumInputs;
  unsigned NumClobbers;

  Stmt **Exprs = nullptr;

  AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
          unsigned numoutputs, unsigned numinputs, unsigned numclobbers)
      : Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
        NumOutputs(numoutputs), NumInputs(numinputs),
        NumClobbers(numclobbers) {}

public:
  /// Build an empty inline-assembly statement.
  explicit AsmStmt(StmtClass SC, EmptyShell Empty) : Stmt(SC, Empty) {}

  SourceLocation getAsmLoc() const { return AsmLoc; }
  void setAsmLoc(SourceLocation L) { AsmLoc = L; }

  bool isSimple() const { return IsSimple; }
  void setSimple(bool V) { IsSimple = V; }

  bool isVolatile() const { return IsVolatile; }
  void setVolatile(bool V) { IsVolatile = V; }

  SourceLocation getBeginLoc() const LLVM_READONLY { return {}; }
  SourceLocation getEndLoc() const LLVM_READONLY { return {}; }

  //===--- Asm String Analysis ---===//

  /// Assemble final IR asm string.
  std::string generateAsmString(const ASTContext &C) const;

  //===--- Output operands ---===//

  unsigned getNumOutputs() const { return NumOutputs; }

  /// getOutputConstraint - Return the constraint string for the specified
  /// output operand.  All output constraints are known to be non-empty (either
  /// '=' or '+').
  StringRef getOutputConstraint(unsigned i) const;

  /// isOutputPlusConstraint - Return true if the specified output constraint
  /// is a "+" constraint (which is both an input and an output) or false if it
  /// is an "=" constraint (just an output).
  bool isOutputPlusConstraint(unsigned i) const {
    return getOutputConstraint(i)[0] == '+';
  }

  const Expr *getOutputExpr(unsigned i) const;

  /// getNumPlusOperands - Return the number of output operands that have a "+"
  /// constraint.
  unsigned getNumPlusOperands() const;

  //===--- Input operands ---===//

  unsigned getNumInputs() const { return NumInputs; }

  /// getInputConstraint - Return the specified input constraint.  Unlike output
  /// constraints, these can be empty.
  StringRef getInputConstraint(unsigned i) const;

  const Expr *getInputExpr(unsigned i) const;

  //===--- Other ---===//

  unsigned getNumClobbers() const { return NumClobbers; }
  StringRef getClobber(unsigned i) const;

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == GCCAsmStmtClass ||
      T->getStmtClass() == MSAsmStmtClass;
  }

  // Input expr iterators.

  using inputs_iterator = ExprIterator;
  using const_inputs_iterator = ConstExprIterator;
  using inputs_range = llvm::iterator_range<inputs_iterator>;
  using inputs_const_range = llvm::iterator_range<const_inputs_iterator>;

  inputs_iterator begin_inputs() {
    return &Exprs[0] + NumOutputs;
  }

  inputs_iterator end_inputs() {
    return &Exprs[0] + NumOutputs + NumInputs;
  }

  inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }

  const_inputs_iterator begin_inputs() const {
    return &Exprs[0] + NumOutputs;
  }

  const_inputs_iterator end_inputs() const {
    return &Exprs[0] + NumOutputs + NumInputs;
  }

  inputs_const_range inputs() const {
    return inputs_const_range(begin_inputs(), end_inputs());
  }

  // Output expr iterators.

  using outputs_iterator = ExprIterator;
  using const_outputs_iterator = ConstExprIterator;
  using outputs_range = llvm::iterator_range<outputs_iterator>;
  using outputs_const_range = llvm::iterator_range<const_outputs_iterator>;

  outputs_iterator begin_outputs() {
    return &Exprs[0];
  }

  outputs_iterator end_outputs() {
    return &Exprs[0] + NumOutputs;
  }

  outputs_range outputs() {
    return outputs_range(begin_outputs(), end_outputs());
  }

  const_outputs_iterator begin_outputs() const {
    return &Exprs[0];
  }

  const_outputs_iterator end_outputs() const {
    return &Exprs[0] + NumOutputs;
  }

  outputs_const_range outputs() const {
    return outputs_const_range(begin_outputs(), end_outputs());
  }

  child_range children() {
    return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
  }

  const_child_range children() const {
    return const_child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
  }
};

/// This represents a GCC inline-assembly statement extension.
class GCCAsmStmt : public AsmStmt {
  friend class ASTStmtReader;

  SourceLocation RParenLoc;
  StringLiteral *AsmStr;

  // FIXME: If we wanted to, we could allocate all of these in one big array.
  StringLiteral **Constraints = nullptr;
  StringLiteral **Clobbers = nullptr;
  IdentifierInfo **Names = nullptr;
  unsigned NumLabels = 0;

public:
  GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
             bool isvolatile, unsigned numoutputs, unsigned numinputs,
             IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
             StringLiteral *asmstr, unsigned numclobbers,
             StringLiteral **clobbers, unsigned numlabels,
             SourceLocation rparenloc);

  /// Build an empty inline-assembly statement.
  explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}

  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setRParenLoc(SourceLocation L) { RParenLoc = L; }

  //===--- Asm String Analysis ---===//

  const StringLiteral *getAsmString() const { return AsmStr; }
  StringLiteral *getAsmString() { return AsmStr; }
  void setAsmString(StringLiteral *E) { AsmStr = E; }

  /// AsmStringPiece - this is part of a decomposed asm string specification
  /// (for use with the AnalyzeAsmString function below).  An asm string is
  /// considered to be a concatenation of these parts.
  class AsmStringPiece {
  public:
    enum Kind {
      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
      Operand  // Operand reference, with optional modifier %c4.
    };

  private:
    Kind MyKind;
    std::string Str;
    unsigned OperandNo;

    // Source range for operand references.
    CharSourceRange Range;

  public:
    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
    AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
                   SourceLocation End)
        : MyKind(Operand), Str(S), OperandNo(OpNo),
          Range(CharSourceRange::getCharRange(Begin, End)) {}

    bool isString() const { return MyKind == String; }
    bool isOperand() const { return MyKind == Operand; }

    const std::string &getString() const { return Str; }

    unsigned getOperandNo() const {
      assert(isOperand());
      return OperandNo;
    }

    CharSourceRange getRange() const {
      assert(isOperand() && "Range is currently used only for Operands.");
      return Range;
    }

    /// getModifier - Get the modifier for this operand, if present.  This
    /// returns '\0' if there was no modifier.
    char getModifier() const;
  };

  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
  /// it into pieces.  If the asm string is erroneous, emit errors and return
  /// true, otherwise return false.  This handles canonicalization and
  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
  unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
                            const ASTContext &C, unsigned &DiagOffs) const;

  /// Assemble final IR asm string.
  std::string generateAsmString(const ASTContext &C) const;

  //===--- Output operands ---===//

  IdentifierInfo *getOutputIdentifier(unsigned i) const { return Names[i]; }

  StringRef getOutputName(unsigned i) const {
    if (IdentifierInfo *II = getOutputIdentifier(i))
      return II->getName();

    return {};
  }

  StringRef getOutputConstraint(unsigned i) const;

  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
    return Constraints[i];
  }
  StringLiteral *getOutputConstraintLiteral(unsigned i) {
    return Constraints[i];
  }

  Expr *getOutputExpr(unsigned i);

  const Expr *getOutputExpr(unsigned i) const {
    return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
  }

  //===--- Input operands ---===//

  IdentifierInfo *getInputIdentifier(unsigned i) const {
    return Names[i + NumOutputs];
  }

  StringRef getInputName(unsigned i) const {
    if (IdentifierInfo *II = getInputIdentifier(i))
      return II->getName();

    return {};
  }

  StringRef getInputConstraint(unsigned i) const;

  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
    return Constraints[i + NumOutputs];
  }
  StringLiteral *getInputConstraintLiteral(unsigned i) {
    return Constraints[i + NumOutputs];
  }

  Expr *getInputExpr(unsigned i);
  void setInputExpr(unsigned i, Expr *E);

  const Expr *getInputExpr(unsigned i) const {
    return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
  }

  //===--- Labels ---===//

  bool isAsmGoto() const {
    return NumLabels > 0;
  }

  unsigned getNumLabels() const {
    return NumLabels;
  }

  IdentifierInfo *getLabelIdentifier(unsigned i) const {
    return Names[i + NumOutputs + NumInputs];
  }

  AddrLabelExpr *getLabelExpr(unsigned i) const;
  StringRef getLabelName(unsigned i) const;
  using labels_iterator = CastIterator<AddrLabelExpr>;
  using const_labels_iterator = ConstCastIterator<AddrLabelExpr>;
  using labels_range = llvm::iterator_range<labels_iterator>;
  using labels_const_range = llvm::iterator_range<const_labels_iterator>;

  labels_iterator begin_labels() {
    return &Exprs[0] + NumOutputs + NumInputs;
  }

  labels_iterator end_labels() {
    return &Exprs[0] + NumOutputs + NumInputs + NumLabels;
  }

  labels_range labels() {
    return labels_range(begin_labels(), end_labels());
  }

  const_labels_iterator begin_labels() const {
    return &Exprs[0] + NumOutputs + NumInputs;
  }

  const_labels_iterator end_labels() const {
    return &Exprs[0] + NumOutputs + NumInputs + NumLabels;
  }

  labels_const_range labels() const {
    return labels_const_range(begin_labels(), end_labels());
  }

private:
  void setOutputsAndInputsAndClobbers(const ASTContext &C,
                                      IdentifierInfo **Names,
                                      StringLiteral **Constraints,
                                      Stmt **Exprs,
                                      unsigned NumOutputs,
                                      unsigned NumInputs,
                                      unsigned NumLabels,
                                      StringLiteral **Clobbers,
                                      unsigned NumClobbers);

public:
  //===--- Other ---===//

  /// getNamedOperand - Given a symbolic operand reference like %[foo],
  /// translate this into a numeric value needed to reference the same operand.
  /// This returns -1 if the operand name is invalid.
  int getNamedOperand(StringRef SymbolicName) const;

  StringRef getClobber(unsigned i) const;

  StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
  const StringLiteral *getClobberStringLiteral(unsigned i) const {
    return Clobbers[i];
  }

  SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
  SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == GCCAsmStmtClass;
  }
};

/// This represents a Microsoft inline-assembly statement extension.
class MSAsmStmt : public AsmStmt {
  friend class ASTStmtReader;

  SourceLocation LBraceLoc, EndLoc;
  StringRef AsmStr;

  unsigned NumAsmToks = 0;

  Token *AsmToks = nullptr;
  StringRef *Constraints = nullptr;
  StringRef *Clobbers = nullptr;

public:
  MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
            SourceLocation lbraceloc, bool issimple, bool isvolatile,
            ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs,
            ArrayRef<StringRef> constraints,
            ArrayRef<Expr*> exprs, StringRef asmstr,
            ArrayRef<StringRef> clobbers, SourceLocation endloc);

  /// Build an empty MS-style inline-assembly statement.
  explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty) {}

  SourceLocation getLBraceLoc() const { return LBraceLoc; }
  void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
  SourceLocation getEndLoc() const { return EndLoc; }
  void setEndLoc(SourceLocation L) { EndLoc = L; }

  bool hasBraces() const { return LBraceLoc.isValid(); }

  unsigned getNumAsmToks() { return NumAsmToks; }
  Token *getAsmToks() { return AsmToks; }

  //===--- Asm String Analysis ---===//
  StringRef getAsmString() const { return AsmStr; }

  /// Assemble final IR asm string.
  std::string generateAsmString(const ASTContext &C) const;

  //===--- Output operands ---===//

  StringRef getOutputConstraint(unsigned i) const {
    assert(i < NumOutputs);
    return Constraints[i];
  }

  Expr *getOutputExpr(unsigned i);

  const Expr *getOutputExpr(unsigned i) const {
    return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
  }

  //===--- Input operands ---===//

  StringRef getInputConstraint(unsigned i) const {
    assert(i < NumInputs);
    return Constraints[i + NumOutputs];
  }

  Expr *getInputExpr(unsigned i);
  void setInputExpr(unsigned i, Expr *E);

  const Expr *getInputExpr(unsigned i) const {
    return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
  }

  //===--- Other ---===//

  ArrayRef<StringRef> getAllConstraints() const {
    return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
  }

  ArrayRef<StringRef> getClobbers() const {
    return llvm::makeArrayRef(Clobbers, NumClobbers);
  }

  ArrayRef<Expr*> getAllExprs() const {
    return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
                              NumInputs + NumOutputs);
  }

  StringRef getClobber(unsigned i) const { return getClobbers()[i]; }

private:
  void initialize(const ASTContext &C, StringRef AsmString,
                  ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
                  ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);

public:
  SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == MSAsmStmtClass;
  }

  child_range children() {
    return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
  }

  const_child_range children() const {
    return const_child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
  }
};

class SEHExceptStmt : public Stmt {
  friend class ASTReader;
  friend class ASTStmtReader;

  SourceLocation  Loc;
  Stmt *Children[2];

  enum { FILTER_EXPR, BLOCK };

  SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block);
  explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) {}

public:
  static SEHExceptStmt* Create(const ASTContext &C,
                               SourceLocation ExceptLoc,
                               Expr *FilterExpr,
                               Stmt *Block);

  SourceLocation getBeginLoc() const LLVM_READONLY { return getExceptLoc(); }

  SourceLocation getExceptLoc() const { return Loc; }
  SourceLocation getEndLoc() const { return getBlock()->getEndLoc(); }

  Expr *getFilterExpr() const {
    return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
  }

  CompoundStmt *getBlock() const {
    return cast<CompoundStmt>(Children[BLOCK]);
  }

  child_range children() {
    return child_range(Children, Children+2);
  }

  const_child_range children() const {
    return const_child_range(Children, Children + 2);
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == SEHExceptStmtClass;
  }
};

class SEHFinallyStmt : public Stmt {
  friend class ASTReader;
  friend class ASTStmtReader;

  SourceLocation  Loc;
  Stmt *Block;

  SEHFinallyStmt(SourceLocation Loc, Stmt *Block);
  explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) {}

public:
  static SEHFinallyStmt* Create(const ASTContext &C,
                                SourceLocation FinallyLoc,
                                Stmt *Block);

  SourceLocation getBeginLoc() const LLVM_READONLY { return getFinallyLoc(); }

  SourceLocation getFinallyLoc() const { return Loc; }
  SourceLocation getEndLoc() const { return Block->getEndLoc(); }

  CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }

  child_range children() {
    return child_range(&Block,&Block+1);
  }

  const_child_range children() const {
    return const_child_range(&Block, &Block + 1);
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == SEHFinallyStmtClass;
  }
};

class SEHTryStmt : public Stmt {
  friend class ASTReader;
  friend class ASTStmtReader;

  bool IsCXXTry;
  SourceLocation  TryLoc;
  Stmt *Children[2];

  enum { TRY = 0, HANDLER = 1 };

  SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
             SourceLocation TryLoc,
             Stmt *TryBlock,
             Stmt *Handler);

  explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) {}

public:
  static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
                            SourceLocation TryLoc, Stmt *TryBlock,
                            Stmt *Handler);

  SourceLocation getBeginLoc() const LLVM_READONLY { return getTryLoc(); }

  SourceLocation getTryLoc() const { return TryLoc; }
  SourceLocation getEndLoc() const { return Children[HANDLER]->getEndLoc(); }

  bool getIsCXXTry() const { return IsCXXTry; }

  CompoundStmt* getTryBlock() const {
    return cast<CompoundStmt>(Children[TRY]);
  }

  Stmt *getHandler() const { return Children[HANDLER]; }

  /// Returns 0 if not defined
  SEHExceptStmt  *getExceptHandler() const;
  SEHFinallyStmt *getFinallyHandler() const;

  child_range children() {
    return child_range(Children, Children+2);
  }

  const_child_range children() const {
    return const_child_range(Children, Children + 2);
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == SEHTryStmtClass;
  }
};

/// Represents a __leave statement.
class SEHLeaveStmt : public Stmt {
  SourceLocation LeaveLoc;

public:
  explicit SEHLeaveStmt(SourceLocation LL)
      : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}

  /// Build an empty __leave statement.
  explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) {}

  SourceLocation getLeaveLoc() const { return LeaveLoc; }
  void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }

  SourceLocation getBeginLoc() const LLVM_READONLY { return LeaveLoc; }
  SourceLocation getEndLoc() const LLVM_READONLY { return LeaveLoc; }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == SEHLeaveStmtClass;
  }

  // Iterators
  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }
};

/// This captures a statement into a function. For example, the following
/// pragma annotated compound statement can be represented as a CapturedStmt,
/// and this compound statement is the body of an anonymous outlined function.
/// @code
/// #pragma omp parallel
/// {
///   compute();
/// }
/// @endcode
class CapturedStmt : public Stmt {
public:
  /// The different capture forms: by 'this', by reference, capture for
  /// variable-length array type etc.
  enum VariableCaptureKind {
    VCK_This,
    VCK_ByRef,
    VCK_ByCopy,
    VCK_VLAType,
  };

  /// Describes the capture of either a variable, or 'this', or
  /// variable-length array type.
  class Capture {
    llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
    SourceLocation Loc;

  public:
    friend class ASTStmtReader;

    /// Create a new capture.
    ///
    /// \param Loc The source location associated with this capture.
    ///
    /// \param Kind The kind of capture (this, ByRef, ...).
    ///
    /// \param Var The variable being captured, or null if capturing this.
    Capture(SourceLocation Loc, VariableCaptureKind Kind,
            VarDecl *Var = nullptr);

    /// Determine the kind of capture.
    VariableCaptureKind getCaptureKind() const;

    /// Retrieve the source location at which the variable or 'this' was
    /// first used.
    SourceLocation getLocation() const { return Loc; }

    /// Determine whether this capture handles the C++ 'this' pointer.
    bool capturesThis() const { return getCaptureKind() == VCK_This; }

    /// Determine whether this capture handles a variable (by reference).
    bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; }

    /// Determine whether this capture handles a variable by copy.
    bool capturesVariableByCopy() const {
      return getCaptureKind() == VCK_ByCopy;
    }

    /// Determine whether this capture handles a variable-length array
    /// type.
    bool capturesVariableArrayType() const {
      return getCaptureKind() == VCK_VLAType;
    }

    /// Retrieve the declaration of the variable being captured.
    ///
    /// This operation is only valid if this capture captures a variable.
    VarDecl *getCapturedVar() const;
  };

private:
  /// The number of variable captured, including 'this'.
  unsigned NumCaptures;

  /// The pointer part is the implicit the outlined function and the
  /// int part is the captured region kind, 'CR_Default' etc.
  llvm::PointerIntPair<CapturedDecl *, 2, CapturedRegionKind> CapDeclAndKind;

  /// The record for captured variables, a RecordDecl or CXXRecordDecl.
  RecordDecl *TheRecordDecl = nullptr;

  /// Construct a captured statement.
  CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
               ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);

  /// Construct an empty captured statement.
  CapturedStmt(EmptyShell Empty, unsigned NumCaptures);

  Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); }

  Stmt *const *getStoredStmts() const {
    return reinterpret_cast<Stmt *const *>(this + 1);
  }

  Capture *getStoredCaptures() const;

  void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }

public:
  friend class ASTStmtReader;

  static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
                              CapturedRegionKind Kind,
                              ArrayRef<Capture> Captures,
                              ArrayRef<Expr *> CaptureInits,
                              CapturedDecl *CD, RecordDecl *RD);

  static CapturedStmt *CreateDeserialized(const ASTContext &Context,
                                          unsigned NumCaptures);

  /// Retrieve the statement being captured.
  Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
  const Stmt *getCapturedStmt() const { return getStoredStmts()[NumCaptures]; }

  /// Retrieve the outlined function declaration.
  CapturedDecl *getCapturedDecl();
  const CapturedDecl *getCapturedDecl() const;

  /// Set the outlined function declaration.
  void setCapturedDecl(CapturedDecl *D);

  /// Retrieve the captured region kind.
  CapturedRegionKind getCapturedRegionKind() const;

  /// Set the captured region kind.
  void setCapturedRegionKind(CapturedRegionKind Kind);

  /// Retrieve the record declaration for captured variables.
  const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }

  /// Set the record declaration for captured variables.
  void setCapturedRecordDecl(RecordDecl *D) {
    assert(D && "null RecordDecl");
    TheRecordDecl = D;
  }

  /// True if this variable has been captured.
  bool capturesVariable(const VarDecl *Var) const;

  /// An iterator that walks over the captures.
  using capture_iterator = Capture *;
  using const_capture_iterator = const Capture *;
  using capture_range = llvm::iterator_range<capture_iterator>;
  using capture_const_range = llvm::iterator_range<const_capture_iterator>;

  capture_range captures() {
    return capture_range(capture_begin(), capture_end());
  }
  capture_const_range captures() const {
    return capture_const_range(capture_begin(), capture_end());
  }

  /// Retrieve an iterator pointing to the first capture.
  capture_iterator capture_begin() { return getStoredCaptures(); }
  const_capture_iterator capture_begin() const { return getStoredCaptures(); }

  /// Retrieve an iterator pointing past the end of the sequence of
  /// captures.
  capture_iterator capture_end() const {
    return getStoredCaptures() + NumCaptures;
  }

  /// Retrieve the number of captures, including 'this'.
  unsigned capture_size() const { return NumCaptures; }

  /// Iterator that walks over the capture initialization arguments.
  using capture_init_iterator = Expr **;
  using capture_init_range = llvm::iterator_range<capture_init_iterator>;

  /// Const iterator that walks over the capture initialization
  /// arguments.
  using const_capture_init_iterator = Expr *const *;
  using const_capture_init_range =
      llvm::iterator_range<const_capture_init_iterator>;

  capture_init_range capture_inits() {
    return capture_init_range(capture_init_begin(), capture_init_end());
  }

  const_capture_init_range capture_inits() const {
    return const_capture_init_range(capture_init_begin(), capture_init_end());
  }

  /// Retrieve the first initialization argument.
  capture_init_iterator capture_init_begin() {
    return reinterpret_cast<Expr **>(getStoredStmts());
  }

  const_capture_init_iterator capture_init_begin() const {
    return reinterpret_cast<Expr *const *>(getStoredStmts());
  }

  /// Retrieve the iterator pointing one past the last initialization
  /// argument.
  capture_init_iterator capture_init_end() {
    return capture_init_begin() + NumCaptures;
  }

  const_capture_init_iterator capture_init_end() const {
    return capture_init_begin() + NumCaptures;
  }

  SourceLocation getBeginLoc() const LLVM_READONLY {
    return getCapturedStmt()->getBeginLoc();
  }

  SourceLocation getEndLoc() const LLVM_READONLY {
    return getCapturedStmt()->getEndLoc();
  }

  SourceRange getSourceRange() const LLVM_READONLY {
    return getCapturedStmt()->getSourceRange();
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == CapturedStmtClass;
  }

  child_range children();

  const_child_range children() const;
};

} // namespace clang

#endif // LLVM_CLANG_AST_STMT_H
