//===- 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 APValue;
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 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,

    // 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.
    unsigned 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.
    unsigned Location;
  };

  union {
    /// When Kind == EK_Variable, EK_Member or EK_Binding, the variable.
    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
    /// low bit indicating whether the parameter is "consumed".
    uintptr_t 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 lower bit specifies whether the base is an inherited
    /// virtual base.
    uintptr_t 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() = default;

  /// 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) {
    LocAndNRVO.Location = Loc.getRawEncoding();
    LocAndNRVO.NRVO = NRVO;
  }

  /// Create the initialization entity for a member subobject.
  InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
                    bool Implicit, bool DefaultMemberInit)
      : Kind(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) {
    Capture.VarID = VarID;
    Capture.Location = Loc.getRawEncoding();
  }

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,
                                               const ParmVarDecl *Parm) {
    return InitializeParameter(Context, Parm, Parm->getType());
  }

  /// Create the initialization entity for a parameter, but use
  /// another type.
  static InitializedEntity InitializeParameter(ASTContext &Context,
                                               const 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
      = (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm));
    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 = (Consumed);
    return Entity;
  }

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

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

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

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

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

  /// 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(TypeSourceInfo *TypeInfo) {
    return InitializeTemporary(TypeInfo, TypeInfo->getType());
  }

  /// 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 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.
  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);
  }

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

  /// Retrieve the base specifier.
  const CXXBaseSpecifier *getBaseSpecifier() const {
    assert(getKind() == EK_Base && "Not a base specifier");
    return reinterpret_cast<const CXXBaseSpecifier *>(Base & ~0x1);
  }

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

  /// Determine whether this is an array new with an unknown bound.
  bool isVariableLengthArrayNew() const {
    return getKind() == EK_New && dyn_cast_or_null<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 SourceLocation::getFromRawEncoding(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 SourceLocation::getFromRawEncoding(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->getName();
  }

  /// 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 SourceLocation::getFromRawEncoding(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 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_CastDerivedToBaseRValue,

    /// 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 an rvalue.
    SK_QualificationConversionRValue,

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

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

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

    /// Perform a load from a glvalue, producing an rvalue.
    SK_LValueToRValue,

    /// 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
  };

  /// 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 an lvalue of unrelated
    /// type.
    FK_NonConstLValueReferenceBindingToUnrelated,

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

    /// Reference binding drops qualifiers.
    FK_ReferenceInitDropsQualifiers,

    /// 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,
  };

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;

  /// Returns whether the last step in this initialization sequence is a
  /// narrowing conversion, defined by C++0x [dcl.init.list]p7.
  ///
  /// If this function returns true, *isInitializerConstant will be set to
  /// describe whether *Initializer was a constant expression.  If
  /// *isInitializerConstant is set to true, *ConstantValue will be set to the
  /// evaluated value of *Initializer.
  bool endsWithNarrowing(ASTContext &Ctx, const Expr *Initializer,
                         bool *isInitializerConstant,
                         APValue *ConstantValue) 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 conversion from non-atomic to atomic
  /// type.
  void AddAtomicConversionStep(QualType Ty);

  /// Add a new step that performs a load of the given type.
  ///
  /// Although the term "LValueToRValue" is conventional, this applies to both
  /// lvalues and xvalues.
  void AddLValueToRValueStep(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);

  /// Add a step to initialize by zero types defined in the
  /// cl_intel_device_side_avc_motion_estimation OpenCL extension
  void AddOCLIntelSubgroupAVCZeroInitStep(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
