//===- Initialization.h - Semantic Analysis for Initializers ----*- 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 provides supporting data types for initialization of objects.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SEMA_INITIALIZATION_H
#define LLVM_CLANG_SEMA_INITIALIZATION_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.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 "clang/Sema/Overload.h"
#include "clang/Sema/Ownership.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <cstdint>
#include <string>

namespace clang {

class CXXBaseSpecifier;
class CXXConstructorDecl;
class ObjCMethodDecl;
class Sema;

/// Describes an entity that is being initialized.
class alignas(8) InitializedEntity {
public:
  /// Specifies the kind of entity being initialized.
  enum EntityKind {
    /// The entity being initialized is a variable.
    EK_Variable,

    /// The entity being initialized is a function parameter.
    EK_Parameter,

    /// The entity being initialized is a non-type template parameter.
    EK_TemplateParameter,

    /// The entity being initialized is the result of a function call.
    EK_Result,

    /// The entity being initialized is the result of a statement expression.
    EK_StmtExprResult,

    /// The entity being initialized is an exception object that
    /// is being thrown.
    EK_Exception,

    /// The entity being initialized is a non-static data member
    /// subobject.
    EK_Member,

    /// The entity being initialized is an element of an array.
    EK_ArrayElement,

    /// The entity being initialized is an object (or array of
    /// objects) allocated via new.
    EK_New,

    /// The entity being initialized is a temporary object.
    EK_Temporary,

    /// The entity being initialized is a base member subobject.
    EK_Base,

    /// The initialization is being done by a delegating constructor.
    EK_Delegating,

    /// The entity being initialized is an element of a vector.
    /// or vector.
    EK_VectorElement,

    /// The entity being initialized is a field of block descriptor for
    /// the copied-in c++ object.
    EK_BlockElement,

    /// The entity being initialized is a field of block descriptor for the
    /// copied-in lambda object that's used in the lambda to block conversion.
    EK_LambdaToBlockConversionBlockElement,

    /// The entity being initialized is the real or imaginary part of a
    /// complex number.
    EK_ComplexElement,

    /// The entity being initialized is the field that captures a
    /// variable in a lambda.
    EK_LambdaCapture,

    /// The entity being initialized is the initializer for a compound
    /// literal.
    EK_CompoundLiteralInit,

    /// The entity being implicitly initialized back to the formal
    /// result type.
    EK_RelatedResult,

    /// The entity being initialized is a function parameter; function
    /// is member of group of audited CF APIs.
    EK_Parameter_CF_Audited,

    /// The entity being initialized is a structured binding of a
    /// decomposition declaration.
    EK_Binding,

    /// The entity being initialized is a non-static data member subobject of an
    /// object initialized via parenthesized aggregate initialization.
    EK_ParenAggInitMember,

    // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
    // enum as an index for its first %select.  When modifying this list,
    // that diagnostic text needs to be updated as well.
  };

private:
  /// The kind of entity being initialized.
  EntityKind Kind;

  /// If non-NULL, the parent entity in which this
  /// initialization occurs.
  const InitializedEntity *Parent = nullptr;

  /// The type of the object or reference being initialized.
  QualType Type;

  /// The mangling number for the next reference temporary to be created.
  mutable unsigned ManglingNumber = 0;

  struct LN {
    /// When Kind == EK_Result, EK_Exception, EK_New, the
    /// location of the 'return', 'throw', or 'new' keyword,
    /// respectively. When Kind == EK_Temporary, the location where
    /// the temporary is being created.
    SourceLocation Location;

    /// Whether the entity being initialized may end up using the
    /// named return value optimization (NRVO).
    bool NRVO;
  };

  struct VD {
    /// The VarDecl, FieldDecl, or BindingDecl being initialized.
    ValueDecl *VariableOrMember;

    /// When Kind == EK_Member, whether this is an implicit member
    /// initialization in a copy or move constructor. These can perform array
    /// copies.
    bool IsImplicitFieldInit;

    /// When Kind == EK_Member, whether this is the initial initialization
    /// check for a default member initializer.
    bool IsDefaultMemberInit;
  };

  struct C {
    /// The name of the variable being captured by an EK_LambdaCapture.
    IdentifierInfo *VarID;

    /// The source location at which the capture occurs.
    SourceLocation Location;
  };

  union {
    /// When Kind == EK_Variable, EK_Member, EK_Binding, or
    /// EK_TemplateParameter, the variable, binding, or template parameter.
    VD Variable;

    /// When Kind == EK_RelatedResult, the ObjectiveC method where
    /// result type was implicitly changed to accommodate ARC semantics.
    ObjCMethodDecl *MethodDecl;

    /// When Kind == EK_Parameter, the ParmVarDecl, with the
    /// integer indicating whether the parameter is "consumed".
    llvm::PointerIntPair<ParmVarDecl *, 1> Parameter;

    /// When Kind == EK_Temporary or EK_CompoundLiteralInit, the type
    /// source information for the temporary.
    TypeSourceInfo *TypeInfo;

    struct LN LocAndNRVO;

    /// When Kind == EK_Base, the base specifier that provides the
    /// base class. The integer specifies whether the base is an inherited
    /// virtual base.
    llvm::PointerIntPair<const CXXBaseSpecifier *, 1> Base;

    /// When Kind == EK_ArrayElement, EK_VectorElement, or
    /// EK_ComplexElement, the index of the array or vector element being
    /// initialized.
    unsigned Index;

    struct C Capture;
  };

  InitializedEntity() {};

  /// Create the initialization entity for a variable.
  InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
      : Kind(EK), Type(Var->getType()), Variable{Var, false, false} {}

  /// Create the initialization entity for the result of a
  /// function, throwing an object, performing an explicit cast, or
  /// initializing a parameter for which there is no declaration.
  InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
                    bool NRVO = false)
      : Kind(Kind), Type(Type) {
    new (&LocAndNRVO) LN;
    LocAndNRVO.Location = Loc;
    LocAndNRVO.NRVO = NRVO;
  }

  /// Create the initialization entity for a member subobject.
  InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
                    bool Implicit, bool DefaultMemberInit,
                    bool IsParenAggInit = false)
      : Kind(IsParenAggInit ? EK_ParenAggInitMember : EK_Member),
        Parent(Parent), Type(Member->getType()),
        Variable{Member, Implicit, DefaultMemberInit} {}

  /// Create the initialization entity for an array element.
  InitializedEntity(ASTContext &Context, unsigned Index,
                    const InitializedEntity &Parent);

  /// Create the initialization entity for a lambda capture.
  InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
      : Kind(EK_LambdaCapture), Type(FieldType) {
    new (&Capture) C;
    Capture.VarID = VarID;
    Capture.Location = Loc;
  }

public:
  /// Create the initialization entity for a variable.
  static InitializedEntity InitializeVariable(VarDecl *Var) {
    return InitializedEntity(Var);
  }

  /// Create the initialization entity for a parameter.
  static InitializedEntity InitializeParameter(ASTContext &Context,
                                               ParmVarDecl *Parm) {
    return InitializeParameter(Context, Parm, Parm->getType());
  }

  /// Create the initialization entity for a parameter, but use
  /// another type.
  static InitializedEntity
  InitializeParameter(ASTContext &Context, ParmVarDecl *Parm, QualType Type) {
    bool Consumed = (Context.getLangOpts().ObjCAutoRefCount &&
                     Parm->hasAttr<NSConsumedAttr>());

    InitializedEntity Entity;
    Entity.Kind = EK_Parameter;
    Entity.Type =
      Context.getVariableArrayDecayedType(Type.getUnqualifiedType());
    Entity.Parent = nullptr;
    Entity.Parameter = {Parm, Consumed};
    return Entity;
  }

  /// Create the initialization entity for a parameter that is
  /// only known by its type.
  static InitializedEntity InitializeParameter(ASTContext &Context,
                                               QualType Type,
                                               bool Consumed) {
    InitializedEntity Entity;
    Entity.Kind = EK_Parameter;
    Entity.Type = Context.getVariableArrayDecayedType(Type);
    Entity.Parent = nullptr;
    Entity.Parameter = {nullptr, Consumed};
    return Entity;
  }

  /// Create the initialization entity for a template parameter.
  static InitializedEntity
  InitializeTemplateParameter(QualType T, NonTypeTemplateParmDecl *Param) {
    InitializedEntity Entity;
    Entity.Kind = EK_TemplateParameter;
    Entity.Type = T;
    Entity.Parent = nullptr;
    Entity.Variable = {Param, false, false};
    return Entity;
  }

  /// Create the initialization entity for the result of a function.
  static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
                                            QualType Type) {
    return InitializedEntity(EK_Result, ReturnLoc, Type);
  }

  static InitializedEntity InitializeStmtExprResult(SourceLocation ReturnLoc,
                                            QualType Type) {
    return InitializedEntity(EK_StmtExprResult, ReturnLoc, Type);
  }

  static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc,
                                           QualType Type) {
    return InitializedEntity(EK_BlockElement, BlockVarLoc, Type);
  }

  static InitializedEntity InitializeLambdaToBlock(SourceLocation BlockVarLoc,
                                                   QualType Type) {
    return InitializedEntity(EK_LambdaToBlockConversionBlockElement,
                             BlockVarLoc, Type);
  }

  /// Create the initialization entity for an exception object.
  static InitializedEntity InitializeException(SourceLocation ThrowLoc,
                                               QualType Type) {
    return InitializedEntity(EK_Exception, ThrowLoc, Type);
  }

  /// Create the initialization entity for an object allocated via new.
  static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
    return InitializedEntity(EK_New, NewLoc, Type);
  }

  /// Create the initialization entity for a temporary.
  static InitializedEntity InitializeTemporary(QualType Type) {
    return InitializeTemporary(nullptr, Type);
  }

  /// Create the initialization entity for a temporary.
  static InitializedEntity InitializeTemporary(ASTContext &Context,
                                               TypeSourceInfo *TypeInfo) {
    QualType Type = TypeInfo->getType();
    if (Context.getLangOpts().OpenCLCPlusPlus) {
      assert(!Type.hasAddressSpace() && "Temporary already has address space!");
      Type = Context.getAddrSpaceQualType(Type, LangAS::opencl_private);
    }

    return InitializeTemporary(TypeInfo, Type);
  }

  /// Create the initialization entity for a temporary.
  static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo,
                                               QualType Type) {
    InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
    Result.TypeInfo = TypeInfo;
    return Result;
  }

  /// Create the initialization entity for a related result.
  static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD,
                                                   QualType Type) {
    InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type);
    Result.MethodDecl = MD;
    return Result;
  }

  /// Create the initialization entity for a base class subobject.
  static InitializedEntity
  InitializeBase(ASTContext &Context, const CXXBaseSpecifier *Base,
                 bool IsInheritedVirtualBase,
                 const InitializedEntity *Parent = nullptr);

  /// Create the initialization entity for a delegated constructor.
  static InitializedEntity InitializeDelegation(QualType Type) {
    return InitializedEntity(EK_Delegating, SourceLocation(), Type);
  }

  /// Create the initialization entity for a member subobject.
  static InitializedEntity
  InitializeMember(FieldDecl *Member,
                   const InitializedEntity *Parent = nullptr,
                   bool Implicit = false) {
    return InitializedEntity(Member, Parent, Implicit, false);
  }

  /// Create the initialization entity for a member subobject.
  static InitializedEntity
  InitializeMember(IndirectFieldDecl *Member,
                   const InitializedEntity *Parent = nullptr,
                   bool Implicit = false) {
    return InitializedEntity(Member->getAnonField(), Parent, Implicit, false);
  }

  /// Create the initialization entity for a member subobject initialized via
  /// parenthesized aggregate init.
  static InitializedEntity InitializeMemberFromParenAggInit(FieldDecl *Member) {
    return InitializedEntity(Member, /*Parent=*/nullptr, /*Implicit=*/false,
                             /*DefaultMemberInit=*/false,
                             /*IsParenAggInit=*/true);
  }

  /// Create the initialization entity for a default member initializer.
  static InitializedEntity
  InitializeMemberFromDefaultMemberInitializer(FieldDecl *Member) {
    return InitializedEntity(Member, nullptr, false, true);
  }

  /// Create the initialization entity for an array element.
  static InitializedEntity InitializeElement(ASTContext &Context,
                                             unsigned Index,
                                             const InitializedEntity &Parent) {
    return InitializedEntity(Context, Index, Parent);
  }

  /// Create the initialization entity for a structured binding.
  static InitializedEntity InitializeBinding(VarDecl *Binding) {
    return InitializedEntity(Binding, EK_Binding);
  }

  /// Create the initialization entity for a lambda capture.
  ///
  /// \p VarID The name of the entity being captured, or nullptr for 'this'.
  static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID,
                                                   QualType FieldType,
                                                   SourceLocation Loc) {
    return InitializedEntity(VarID, FieldType, Loc);
  }

  /// Create the entity for a compound literal initializer.
  static InitializedEntity InitializeCompoundLiteralInit(TypeSourceInfo *TSI) {
    InitializedEntity Result(EK_CompoundLiteralInit, SourceLocation(),
                             TSI->getType());
    Result.TypeInfo = TSI;
    return Result;
  }

  /// Determine the kind of initialization.
  EntityKind getKind() const { return Kind; }

  /// Retrieve the parent of the entity being initialized, when
  /// the initialization itself is occurring within the context of a
  /// larger initialization.
  const InitializedEntity *getParent() const { return Parent; }

  /// Retrieve type being initialized.
  QualType getType() const { return Type; }

  /// Retrieve complete type-source information for the object being
  /// constructed, if known.
  TypeSourceInfo *getTypeSourceInfo() const {
    if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit)
      return TypeInfo;

    return nullptr;
  }

  /// Retrieve the name of the entity being initialized.
  DeclarationName getName() const;

  /// Retrieve the variable, parameter, or field being
  /// initialized.
  ValueDecl *getDecl() const;

  /// Retrieve the ObjectiveC method being initialized.
  ObjCMethodDecl *getMethodDecl() const { return MethodDecl; }

  /// Determine whether this initialization allows the named return
  /// value optimization, which also applies to thrown objects.
  bool allowsNRVO() const;

  bool isParameterKind() const {
    return (getKind() == EK_Parameter  ||
            getKind() == EK_Parameter_CF_Audited);
  }

  bool isParamOrTemplateParamKind() const {
    return isParameterKind() || getKind() == EK_TemplateParameter;
  }

  /// Determine whether this initialization consumes the
  /// parameter.
  bool isParameterConsumed() const {
    assert(isParameterKind() && "Not a parameter");
    return Parameter.getInt();
  }

  /// Retrieve the base specifier.
  const CXXBaseSpecifier *getBaseSpecifier() const {
    assert(getKind() == EK_Base && "Not a base specifier");
    return Base.getPointer();
  }

  /// Return whether the base is an inherited virtual base.
  bool isInheritedVirtualBase() const {
    assert(getKind() == EK_Base && "Not a base specifier");
    return Base.getInt();
  }

  /// Determine whether this is an array new with an unknown bound.
  bool isVariableLengthArrayNew() const {
    return getKind() == EK_New && isa_and_nonnull<IncompleteArrayType>(
                                      getType()->getAsArrayTypeUnsafe());
  }

  /// Is this the implicit initialization of a member of a class from
  /// a defaulted constructor?
  bool isImplicitMemberInitializer() const {
    return getKind() == EK_Member && Variable.IsImplicitFieldInit;
  }

  /// Is this the default member initializer of a member (specified inside
  /// the class definition)?
  bool isDefaultMemberInitializer() const {
    return getKind() == EK_Member && Variable.IsDefaultMemberInit;
  }

  /// Determine the location of the 'return' keyword when initializing
  /// the result of a function call.
  SourceLocation getReturnLoc() const {
    assert(getKind() == EK_Result && "No 'return' location!");
    return LocAndNRVO.Location;
  }

  /// Determine the location of the 'throw' keyword when initializing
  /// an exception object.
  SourceLocation getThrowLoc() const {
    assert(getKind() == EK_Exception && "No 'throw' location!");
    return LocAndNRVO.Location;
  }

  /// If this is an array, vector, or complex number element, get the
  /// element's index.
  unsigned getElementIndex() const {
    assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
           getKind() == EK_ComplexElement);
    return Index;
  }

  /// If this is already the initializer for an array or vector
  /// element, sets the element index.
  void setElementIndex(unsigned Index) {
    assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
           getKind() == EK_ComplexElement);
    this->Index = Index;
  }

  /// For a lambda capture, return the capture's name.
  StringRef getCapturedVarName() const {
    assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
    return Capture.VarID ? Capture.VarID->getName() : "this";
  }

  /// Determine the location of the capture when initializing
  /// field from a captured variable in a lambda.
  SourceLocation getCaptureLoc() const {
    assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
    return Capture.Location;
  }

  void setParameterCFAudited() {
    Kind = EK_Parameter_CF_Audited;
  }

  unsigned allocateManglingNumber() const { return ++ManglingNumber; }

  /// Dump a representation of the initialized entity to standard error,
  /// for debugging purposes.
  void dump() const;

private:
  unsigned dumpImpl(raw_ostream &OS) const;
};

/// Describes the kind of initialization being performed, along with
/// location information for tokens related to the initialization (equal sign,
/// parentheses).
class InitializationKind {
public:
  /// The kind of initialization being performed.
  enum InitKind {
    /// Direct initialization
    IK_Direct,

    /// Direct list-initialization
    IK_DirectList,

    /// Copy initialization
    IK_Copy,

    /// Default initialization
    IK_Default,

    /// Value initialization
    IK_Value
  };

private:
  /// The context of the initialization.
  enum InitContext {
    /// Normal context
    IC_Normal,

    /// Normal context, but allows explicit conversion functionss
    IC_ExplicitConvs,

    /// Implicit context (value initialization)
    IC_Implicit,

    /// Static cast context
    IC_StaticCast,

    /// C-style cast context
    IC_CStyleCast,

    /// Functional cast context
    IC_FunctionalCast
  };

  /// The kind of initialization being performed.
  InitKind Kind : 8;

  /// The context of the initialization.
  InitContext Context : 8;

  /// The source locations involved in the initialization.
  SourceLocation Locations[3];

  InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1,
                     SourceLocation Loc2, SourceLocation Loc3)
      : Kind(Kind), Context(Context) {
    Locations[0] = Loc1;
    Locations[1] = Loc2;
    Locations[2] = Loc3;
  }

public:
  /// Create a direct initialization.
  static InitializationKind CreateDirect(SourceLocation InitLoc,
                                         SourceLocation LParenLoc,
                                         SourceLocation RParenLoc) {
    return InitializationKind(IK_Direct, IC_Normal,
                              InitLoc, LParenLoc, RParenLoc);
  }

  static InitializationKind CreateDirectList(SourceLocation InitLoc) {
    return InitializationKind(IK_DirectList, IC_Normal, InitLoc, InitLoc,
                              InitLoc);
  }

  static InitializationKind CreateDirectList(SourceLocation InitLoc,
                                             SourceLocation LBraceLoc,
                                             SourceLocation RBraceLoc) {
    return InitializationKind(IK_DirectList, IC_Normal, InitLoc, LBraceLoc,
                              RBraceLoc);
  }

  /// Create a direct initialization due to a cast that isn't a C-style
  /// or functional cast.
  static InitializationKind CreateCast(SourceRange TypeRange) {
    return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(),
                              TypeRange.getBegin(), TypeRange.getEnd());
  }

  /// Create a direct initialization for a C-style cast.
  static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
                                             SourceRange TypeRange,
                                             bool InitList) {
    // C++ cast syntax doesn't permit init lists, but C compound literals are
    // exactly that.
    return InitializationKind(InitList ? IK_DirectList : IK_Direct,
                              IC_CStyleCast, StartLoc, TypeRange.getBegin(),
                              TypeRange.getEnd());
  }

  /// Create a direct initialization for a functional cast.
  static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
                                                 bool InitList) {
    return InitializationKind(InitList ? IK_DirectList : IK_Direct,
                              IC_FunctionalCast, TypeRange.getBegin(),
                              TypeRange.getBegin(), TypeRange.getEnd());
  }

  /// Create a copy initialization.
  static InitializationKind CreateCopy(SourceLocation InitLoc,
                                       SourceLocation EqualLoc,
                                       bool AllowExplicitConvs = false) {
    return InitializationKind(IK_Copy,
                              AllowExplicitConvs? IC_ExplicitConvs : IC_Normal,
                              InitLoc, EqualLoc, EqualLoc);
  }

  /// Create a default initialization.
  static InitializationKind CreateDefault(SourceLocation InitLoc) {
    return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
  }

  /// Create a value initialization.
  static InitializationKind CreateValue(SourceLocation InitLoc,
                                        SourceLocation LParenLoc,
                                        SourceLocation RParenLoc,
                                        bool isImplicit = false) {
    return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
                              InitLoc, LParenLoc, RParenLoc);
  }

  /// Create an initialization from an initializer (which, for direct
  /// initialization from a parenthesized list, will be a ParenListExpr).
  static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit,
                                          Expr *Init) {
    if (!Init) return CreateDefault(Loc);
    if (!DirectInit)
      return CreateCopy(Loc, Init->getBeginLoc());
    if (isa<InitListExpr>(Init))
      return CreateDirectList(Loc, Init->getBeginLoc(), Init->getEndLoc());
    return CreateDirect(Loc, Init->getBeginLoc(), Init->getEndLoc());
  }

  /// Determine the initialization kind.
  InitKind getKind() const {
    return Kind;
  }

  /// Determine whether this initialization is an explicit cast.
  bool isExplicitCast() const {
    return Context >= IC_StaticCast;
  }

  /// Determine whether this initialization is a static cast.
  bool isStaticCast() const { return Context == IC_StaticCast; }

  /// Determine whether this initialization is a C-style cast.
  bool isCStyleOrFunctionalCast() const {
    return Context >= IC_CStyleCast;
  }

  /// Determine whether this is a C-style cast.
  bool isCStyleCast() const {
    return Context == IC_CStyleCast;
  }

  /// Determine whether this is a functional-style cast.
  bool isFunctionalCast() const {
    return Context == IC_FunctionalCast;
  }

  /// Determine whether this initialization is an implicit
  /// value-initialization, e.g., as occurs during aggregate
  /// initialization.
  bool isImplicitValueInit() const { return Context == IC_Implicit; }

  /// Retrieve the location at which initialization is occurring.
  SourceLocation getLocation() const { return Locations[0]; }

  /// Retrieve the source range that covers the initialization.
  SourceRange getRange() const {
    return SourceRange(Locations[0], Locations[2]);
  }

  /// Retrieve the location of the equal sign for copy initialization
  /// (if present).
  SourceLocation getEqualLoc() const {
    assert(Kind == IK_Copy && "Only copy initialization has an '='");
    return Locations[1];
  }

  bool isCopyInit() const { return Kind == IK_Copy; }

  /// Retrieve whether this initialization allows the use of explicit
  ///        constructors.
  bool AllowExplicit() const { return !isCopyInit(); }

  /// Retrieve whether this initialization allows the use of explicit
  /// conversion functions when binding a reference. If the reference is the
  /// first parameter in a copy or move constructor, such conversions are
  /// permitted even though we are performing copy-initialization.
  bool allowExplicitConversionFunctionsInRefBinding() const {
    return !isCopyInit() || Context == IC_ExplicitConvs;
  }

  /// Determine whether this initialization has a source range containing the
  /// locations of open and closing parentheses or braces.
  bool hasParenOrBraceRange() const {
    return Kind == IK_Direct || Kind == IK_Value || Kind == IK_DirectList;
  }

  /// Retrieve the source range containing the locations of the open
  /// and closing parentheses or braces for value, direct, and direct list
  /// initializations.
  SourceRange getParenOrBraceRange() const {
    assert(hasParenOrBraceRange() && "Only direct, value, and direct-list "
                                     "initialization have parentheses or "
                                     "braces");
    return SourceRange(Locations[1], Locations[2]);
  }
};

/// Describes the sequence of initializations required to initialize
/// a given object or reference with a set of arguments.
class InitializationSequence {
public:
  /// Describes the kind of initialization sequence computed.
  enum SequenceKind {
    /// A failed initialization sequence. The failure kind tells what
    /// happened.
    FailedSequence = 0,

    /// A dependent initialization, which could not be
    /// type-checked due to the presence of dependent types or
    /// dependently-typed expressions.
    DependentSequence,

    /// A normal sequence.
    NormalSequence
  };

  /// Describes the kind of a particular step in an initialization
  /// sequence.
  enum StepKind {
    /// Resolve the address of an overloaded function to a specific
    /// function declaration.
    SK_ResolveAddressOfOverloadedFunction,

    /// Perform a derived-to-base cast, producing an rvalue.
    SK_CastDerivedToBasePRValue,

    /// Perform a derived-to-base cast, producing an xvalue.
    SK_CastDerivedToBaseXValue,

    /// Perform a derived-to-base cast, producing an lvalue.
    SK_CastDerivedToBaseLValue,

    /// Reference binding to an lvalue.
    SK_BindReference,

    /// Reference binding to a temporary.
    SK_BindReferenceToTemporary,

    /// An optional copy of a temporary object to another
    /// temporary object, which is permitted (but not required) by
    /// C++98/03 but not C++0x.
    SK_ExtraneousCopyToTemporary,

    /// Direct-initialization from a reference-related object in the
    /// final stage of class copy-initialization.
    SK_FinalCopy,

    /// Perform a user-defined conversion, either via a conversion
    /// function or via a constructor.
    SK_UserConversion,

    /// Perform a qualification conversion, producing a prvalue.
    SK_QualificationConversionPRValue,

    /// Perform a qualification conversion, producing an xvalue.
    SK_QualificationConversionXValue,

    /// Perform a qualification conversion, producing an lvalue.
    SK_QualificationConversionLValue,

    /// Perform a function reference conversion, see [dcl.init.ref]p4.
    SK_FunctionReferenceConversion,

    /// Perform a conversion adding _Atomic to a type.
    SK_AtomicConversion,

    /// Perform an implicit conversion sequence.
    SK_ConversionSequence,

    /// Perform an implicit conversion sequence without narrowing.
    SK_ConversionSequenceNoNarrowing,

    /// Perform list-initialization without a constructor.
    SK_ListInitialization,

    /// Unwrap the single-element initializer list for a reference.
    SK_UnwrapInitList,

    /// Rewrap the single-element initializer list for a reference.
    SK_RewrapInitList,

    /// Perform initialization via a constructor.
    SK_ConstructorInitialization,

    /// Perform initialization via a constructor, taking arguments from
    /// a single InitListExpr.
    SK_ConstructorInitializationFromList,

    /// Zero-initialize the object
    SK_ZeroInitialization,

    /// C assignment
    SK_CAssignment,

    /// Initialization by string
    SK_StringInit,

    /// An initialization that "converts" an Objective-C object
    /// (not a point to an object) to another Objective-C object type.
    SK_ObjCObjectConversion,

    /// Array indexing for initialization by elementwise copy.
    SK_ArrayLoopIndex,

    /// Array initialization by elementwise copy.
    SK_ArrayLoopInit,

    /// Array initialization (from an array rvalue).
    SK_ArrayInit,

    /// Array initialization (from an array rvalue) as a GNU extension.
    SK_GNUArrayInit,

    /// Array initialization from a parenthesized initializer list.
    /// This is a GNU C++ extension.
    SK_ParenthesizedArrayInit,

    /// Pass an object by indirect copy-and-restore.
    SK_PassByIndirectCopyRestore,

    /// Pass an object by indirect restore.
    SK_PassByIndirectRestore,

    /// Produce an Objective-C object pointer.
    SK_ProduceObjCObject,

    /// Construct a std::initializer_list from an initializer list.
    SK_StdInitializerList,

    /// Perform initialization via a constructor taking a single
    /// std::initializer_list argument.
    SK_StdInitializerListConstructorCall,

    /// Initialize an OpenCL sampler from an integer.
    SK_OCLSamplerInit,

    /// Initialize an opaque OpenCL type (event_t, queue_t, etc.) with zero
    SK_OCLZeroOpaqueType,

    /// Initialize an aggreagate with parenthesized list of values.
    /// This is a C++20 feature.
    SK_ParenthesizedListInit
  };

  /// A single step in the initialization sequence.
  class Step {
  public:
    /// The kind of conversion or initialization step we are taking.
    StepKind Kind;

    // The type that results from this initialization.
    QualType Type;

    struct F {
      bool HadMultipleCandidates;
      FunctionDecl *Function;
      DeclAccessPair FoundDecl;
    };

    union {
      /// When Kind == SK_ResolvedOverloadedFunction or Kind ==
      /// SK_UserConversion, the function that the expression should be
      /// resolved to or the conversion function to call, respectively.
      /// When Kind == SK_ConstructorInitialization or SK_ListConstruction,
      /// the constructor to be called.
      ///
      /// Always a FunctionDecl, plus a Boolean flag telling if it was
      /// selected from an overloaded set having size greater than 1.
      /// For conversion decls, the naming class is the source type.
      /// For construct decls, the naming class is the target type.
      struct F Function;

      /// When Kind = SK_ConversionSequence, the implicit conversion
      /// sequence.
      ImplicitConversionSequence *ICS;

      /// When Kind = SK_RewrapInitList, the syntactic form of the
      /// wrapping list.
      InitListExpr *WrappingSyntacticList;
    };

    void Destroy();
  };

private:
  /// The kind of initialization sequence computed.
  enum SequenceKind SequenceKind;

  /// Steps taken by this initialization.
  SmallVector<Step, 4> Steps;

public:
  /// Describes why initialization failed.
  enum FailureKind {
    /// Too many initializers provided for a reference.
    FK_TooManyInitsForReference,

    /// Reference initialized from a parenthesized initializer list.
    FK_ParenthesizedListInitForReference,

    /// Array must be initialized with an initializer list.
    FK_ArrayNeedsInitList,

    /// Array must be initialized with an initializer list or a
    /// string literal.
    FK_ArrayNeedsInitListOrStringLiteral,

    /// Array must be initialized with an initializer list or a
    /// wide string literal.
    FK_ArrayNeedsInitListOrWideStringLiteral,

    /// Initializing a wide char array with narrow string literal.
    FK_NarrowStringIntoWideCharArray,

    /// Initializing char array with wide string literal.
    FK_WideStringIntoCharArray,

    /// Initializing wide char array with incompatible wide string
    /// literal.
    FK_IncompatWideStringIntoWideChar,

    /// Initializing char8_t array with plain string literal.
    FK_PlainStringIntoUTF8Char,

    /// Initializing char array with UTF-8 string literal.
    FK_UTF8StringIntoPlainChar,

    /// Array type mismatch.
    FK_ArrayTypeMismatch,

    /// Non-constant array initializer
    FK_NonConstantArrayInit,

    /// Cannot resolve the address of an overloaded function.
    FK_AddressOfOverloadFailed,

    /// Overloading due to reference initialization failed.
    FK_ReferenceInitOverloadFailed,

    /// Non-const lvalue reference binding to a temporary.
    FK_NonConstLValueReferenceBindingToTemporary,

    /// Non-const lvalue reference binding to a bit-field.
    FK_NonConstLValueReferenceBindingToBitfield,

    /// Non-const lvalue reference binding to a vector element.
    FK_NonConstLValueReferenceBindingToVectorElement,

    /// Non-const lvalue reference binding to a matrix element.
    FK_NonConstLValueReferenceBindingToMatrixElement,

    /// Non-const lvalue reference binding to an lvalue of unrelated
    /// type.
    FK_NonConstLValueReferenceBindingToUnrelated,

    /// Rvalue reference binding to an lvalue.
    FK_RValueReferenceBindingToLValue,

    /// Reference binding drops qualifiers.
    FK_ReferenceInitDropsQualifiers,

    /// Reference with mismatching address space binding to temporary.
    FK_ReferenceAddrspaceMismatchTemporary,

    /// Reference binding failed.
    FK_ReferenceInitFailed,

    /// Implicit conversion failed.
    FK_ConversionFailed,

    /// Implicit conversion failed.
    FK_ConversionFromPropertyFailed,

    /// Too many initializers for scalar
    FK_TooManyInitsForScalar,

    /// Scalar initialized from a parenthesized initializer list.
    FK_ParenthesizedListInitForScalar,

    /// Reference initialization from an initializer list
    FK_ReferenceBindingToInitList,

    /// Initialization of some unused destination type with an
    /// initializer list.
    FK_InitListBadDestinationType,

    /// Overloading for a user-defined conversion failed.
    FK_UserConversionOverloadFailed,

    /// Overloading for initialization by constructor failed.
    FK_ConstructorOverloadFailed,

    /// Overloading for list-initialization by constructor failed.
    FK_ListConstructorOverloadFailed,

    /// Default-initialization of a 'const' object.
    FK_DefaultInitOfConst,

    /// Initialization of an incomplete type.
    FK_Incomplete,

    /// Variable-length array must not have an initializer.
    FK_VariableLengthArrayHasInitializer,

    /// List initialization failed at some point.
    FK_ListInitializationFailed,

    /// Initializer has a placeholder type which cannot be
    /// resolved by initialization.
    FK_PlaceholderType,

    /// Trying to take the address of a function that doesn't support
    /// having its address taken.
    FK_AddressOfUnaddressableFunction,

    /// List-copy-initialization chose an explicit constructor.
    FK_ExplicitConstructor,

    /// Parenthesized list initialization failed at some point.
    /// This is a C++20 feature.
    FK_ParenthesizedListInitFailed,

    // A designated initializer was provided for a non-aggregate type.
    FK_DesignatedInitForNonAggregate,
  };

private:
  /// The reason why initialization failed.
  FailureKind Failure;

  /// The failed result of overload resolution.
  OverloadingResult FailedOverloadResult;

  /// The candidate set created when initialization failed.
  OverloadCandidateSet FailedCandidateSet;

  /// The incomplete type that caused a failure.
  QualType FailedIncompleteType;

  /// The fixit that needs to be applied to make this initialization
  /// succeed.
  std::string ZeroInitializationFixit;
  SourceLocation ZeroInitializationFixitLoc;

public:
  /// Call for initializations are invalid but that would be valid
  /// zero initialzations if Fixit was applied.
  void SetZeroInitializationFixit(const std::string& Fixit, SourceLocation L) {
    ZeroInitializationFixit = Fixit;
    ZeroInitializationFixitLoc = L;
  }

private:
  /// Prints a follow-up note that highlights the location of
  /// the initialized entity, if it's remote.
  void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);

public:
  /// Try to perform initialization of the given entity, creating a
  /// record of the steps required to perform the initialization.
  ///
  /// The generated initialization sequence will either contain enough
  /// information to diagnose
  ///
  /// \param S the semantic analysis object.
  ///
  /// \param Entity the entity being initialized.
  ///
  /// \param Kind the kind of initialization being performed.
  ///
  /// \param Args the argument(s) provided for initialization.
  ///
  /// \param TopLevelOfInitList true if we are initializing from an expression
  ///        at the top level inside an initializer list. This disallows
  ///        narrowing conversions in C++11 onwards.
  /// \param TreatUnavailableAsInvalid true if we want to treat unavailable
  ///        as invalid.
  InitializationSequence(Sema &S,
                         const InitializedEntity &Entity,
                         const InitializationKind &Kind,
                         MultiExprArg Args,
                         bool TopLevelOfInitList = false,
                         bool TreatUnavailableAsInvalid = true);
  void InitializeFrom(Sema &S, const InitializedEntity &Entity,
                      const InitializationKind &Kind, MultiExprArg Args,
                      bool TopLevelOfInitList, bool TreatUnavailableAsInvalid);

  ~InitializationSequence();

  /// Perform the actual initialization of the given entity based on
  /// the computed initialization sequence.
  ///
  /// \param S the semantic analysis object.
  ///
  /// \param Entity the entity being initialized.
  ///
  /// \param Kind the kind of initialization being performed.
  ///
  /// \param Args the argument(s) provided for initialization, ownership of
  /// which is transferred into the routine.
  ///
  /// \param ResultType if non-NULL, will be set to the type of the
  /// initialized object, which is the type of the declaration in most
  /// cases. However, when the initialized object is a variable of
  /// incomplete array type and the initializer is an initializer
  /// list, this type will be set to the completed array type.
  ///
  /// \returns an expression that performs the actual object initialization, if
  /// the initialization is well-formed. Otherwise, emits diagnostics
  /// and returns an invalid expression.
  ExprResult Perform(Sema &S,
                     const InitializedEntity &Entity,
                     const InitializationKind &Kind,
                     MultiExprArg Args,
                     QualType *ResultType = nullptr);

  /// Diagnose an potentially-invalid initialization sequence.
  ///
  /// \returns true if the initialization sequence was ill-formed,
  /// false otherwise.
  bool Diagnose(Sema &S,
                const InitializedEntity &Entity,
                const InitializationKind &Kind,
                ArrayRef<Expr *> Args);

  /// Determine the kind of initialization sequence computed.
  enum SequenceKind getKind() const { return SequenceKind; }

  /// Set the kind of sequence computed.
  void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }

  /// Determine whether the initialization sequence is valid.
  explicit operator bool() const { return !Failed(); }

  /// Determine whether the initialization sequence is invalid.
  bool Failed() const { return SequenceKind == FailedSequence; }

  using step_iterator = SmallVectorImpl<Step>::const_iterator;

  step_iterator step_begin() const { return Steps.begin(); }
  step_iterator step_end()   const { return Steps.end(); }

  using step_range = llvm::iterator_range<step_iterator>;

  step_range steps() const { return {step_begin(), step_end()}; }

  /// Determine whether this initialization is a direct reference
  /// binding (C++ [dcl.init.ref]).
  bool isDirectReferenceBinding() const;

  /// Determine whether this initialization failed due to an ambiguity.
  bool isAmbiguous() const;

  /// Determine whether this initialization is direct call to a
  /// constructor.
  bool isConstructorInitialization() const;

  /// Add a new step in the initialization that resolves the address
  /// of an overloaded function to a specific function declaration.
  ///
  /// \param Function the function to which the overloaded function reference
  /// resolves.
  void AddAddressOverloadResolutionStep(FunctionDecl *Function,
                                        DeclAccessPair Found,
                                        bool HadMultipleCandidates);

  /// Add a new step in the initialization that performs a derived-to-
  /// base cast.
  ///
  /// \param BaseType the base type to which we will be casting.
  ///
  /// \param Category Indicates whether the result will be treated as an
  /// rvalue, an xvalue, or an lvalue.
  void AddDerivedToBaseCastStep(QualType BaseType,
                                ExprValueKind Category);

  /// Add a new step binding a reference to an object.
  ///
  /// \param BindingTemporary True if we are binding a reference to a temporary
  /// object (thereby extending its lifetime); false if we are binding to an
  /// lvalue or an lvalue treated as an rvalue.
  void AddReferenceBindingStep(QualType T, bool BindingTemporary);

  /// Add a new step that makes an extraneous copy of the input
  /// to a temporary of the same class type.
  ///
  /// This extraneous copy only occurs during reference binding in
  /// C++98/03, where we are permitted (but not required) to introduce
  /// an extra copy. At a bare minimum, we must check that we could
  /// call the copy constructor, and produce a diagnostic if the copy
  /// constructor is inaccessible or no copy constructor matches.
  //
  /// \param T The type of the temporary being created.
  void AddExtraneousCopyToTemporary(QualType T);

  /// Add a new step that makes a copy of the input to an object of
  /// the given type, as the final step in class copy-initialization.
  void AddFinalCopy(QualType T);

  /// Add a new step invoking a conversion function, which is either
  /// a constructor or a conversion function.
  void AddUserConversionStep(FunctionDecl *Function,
                             DeclAccessPair FoundDecl,
                             QualType T,
                             bool HadMultipleCandidates);

  /// Add a new step that performs a qualification conversion to the
  /// given type.
  void AddQualificationConversionStep(QualType Ty,
                                     ExprValueKind Category);

  /// Add a new step that performs a function reference conversion to the
  /// given type.
  void AddFunctionReferenceConversionStep(QualType Ty);

  /// Add a new step that performs conversion from non-atomic to atomic
  /// type.
  void AddAtomicConversionStep(QualType Ty);

  /// Add a new step that applies an implicit conversion sequence.
  void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
                                 QualType T, bool TopLevelOfInitList = false);

  /// Add a list-initialization step.
  void AddListInitializationStep(QualType T);

  /// Add a constructor-initialization step.
  ///
  /// \param FromInitList The constructor call is syntactically an initializer
  /// list.
  /// \param AsInitList The constructor is called as an init list constructor.
  void AddConstructorInitializationStep(DeclAccessPair FoundDecl,
                                        CXXConstructorDecl *Constructor,
                                        QualType T,
                                        bool HadMultipleCandidates,
                                        bool FromInitList, bool AsInitList);

  /// Add a zero-initialization step.
  void AddZeroInitializationStep(QualType T);

  /// Add a C assignment step.
  //
  // FIXME: It isn't clear whether this should ever be needed;
  // ideally, we would handle everything needed in C in the common
  // path. However, that isn't the case yet.
  void AddCAssignmentStep(QualType T);

  /// Add a string init step.
  void AddStringInitStep(QualType T);

  /// Add an Objective-C object conversion step, which is
  /// always a no-op.
  void AddObjCObjectConversionStep(QualType T);

  /// Add an array initialization loop step.
  void AddArrayInitLoopStep(QualType T, QualType EltTy);

  /// Add an array initialization step.
  void AddArrayInitStep(QualType T, bool IsGNUExtension);

  /// Add a parenthesized array initialization step.
  void AddParenthesizedArrayInitStep(QualType T);

  /// Add a step to pass an object by indirect copy-restore.
  void AddPassByIndirectCopyRestoreStep(QualType T, bool shouldCopy);

  /// Add a step to "produce" an Objective-C object (by
  /// retaining it).
  void AddProduceObjCObjectStep(QualType T);

  /// Add a step to construct a std::initializer_list object from an
  /// initializer list.
  void AddStdInitializerListConstructionStep(QualType T);

  /// Add a step to initialize an OpenCL sampler from an integer
  /// constant.
  void AddOCLSamplerInitStep(QualType T);

  /// Add a step to initialzie an OpenCL opaque type (event_t, queue_t, etc.)
  /// from a zero constant.
  void AddOCLZeroOpaqueTypeStep(QualType T);

  void AddParenthesizedListInitStep(QualType T);

  /// Add steps to unwrap a initializer list for a reference around a
  /// single element and rewrap it at the end.
  void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);

  /// Note that this initialization sequence failed.
  void SetFailed(FailureKind Failure) {
    SequenceKind = FailedSequence;
    this->Failure = Failure;
    assert((Failure != FK_Incomplete || !FailedIncompleteType.isNull()) &&
           "Incomplete type failure requires a type!");
  }

  /// Note that this initialization sequence failed due to failed
  /// overload resolution.
  void SetOverloadFailure(FailureKind Failure, OverloadingResult Result);

  /// Retrieve a reference to the candidate set when overload
  /// resolution fails.
  OverloadCandidateSet &getFailedCandidateSet() {
    return FailedCandidateSet;
  }

  /// Get the overloading result, for when the initialization
  /// sequence failed due to a bad overload.
  OverloadingResult getFailedOverloadResult() const {
    return FailedOverloadResult;
  }

  /// Note that this initialization sequence failed due to an
  /// incomplete type.
  void setIncompleteTypeFailure(QualType IncompleteType) {
    FailedIncompleteType = IncompleteType;
    SetFailed(FK_Incomplete);
  }

  /// Determine why initialization failed.
  FailureKind getFailureKind() const {
    assert(Failed() && "Not an initialization failure!");
    return Failure;
  }

  /// Dump a representation of this initialization sequence to
  /// the given stream, for debugging purposes.
  void dump(raw_ostream &OS) const;

  /// Dump a representation of this initialization sequence to
  /// standard error, for debugging purposes.
  void dump() const;
};

} // namespace clang

#endif // LLVM_CLANG_SEMA_INITIALIZATION_H
