10b57cec5SDimitry Andric //===- Initialization.h - Semantic Analysis for Initializers ----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file provides supporting data types for initialization of objects.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CLANG_SEMA_INITIALIZATION_H
140b57cec5SDimitry Andric #define LLVM_CLANG_SEMA_INITIALIZATION_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
170b57cec5SDimitry Andric #include "clang/AST/Attr.h"
180b57cec5SDimitry Andric #include "clang/AST/Decl.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclAccessPair.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclarationName.h"
210b57cec5SDimitry Andric #include "clang/AST/Expr.h"
220b57cec5SDimitry Andric #include "clang/AST/Type.h"
230b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
240b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
250b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
260b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
270b57cec5SDimitry Andric #include "clang/Basic/Specifiers.h"
280b57cec5SDimitry Andric #include "clang/Sema/Overload.h"
290b57cec5SDimitry Andric #include "clang/Sema/Ownership.h"
300b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
310b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
320b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
330b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
340b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
350b57cec5SDimitry Andric #include <cassert>
360b57cec5SDimitry Andric #include <cstdint>
370b57cec5SDimitry Andric #include <string>
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric namespace clang {
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric class CXXBaseSpecifier;
420b57cec5SDimitry Andric class CXXConstructorDecl;
430b57cec5SDimitry Andric class ObjCMethodDecl;
440b57cec5SDimitry Andric class Sema;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric /// Describes an entity that is being initialized.
470b57cec5SDimitry Andric class alignas(8) InitializedEntity {
480b57cec5SDimitry Andric public:
490b57cec5SDimitry Andric   /// Specifies the kind of entity being initialized.
500b57cec5SDimitry Andric   enum EntityKind {
510b57cec5SDimitry Andric     /// The entity being initialized is a variable.
520b57cec5SDimitry Andric     EK_Variable,
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric     /// The entity being initialized is a function parameter.
550b57cec5SDimitry Andric     EK_Parameter,
560b57cec5SDimitry Andric 
57e8d8bef9SDimitry Andric     /// The entity being initialized is a non-type template parameter.
58e8d8bef9SDimitry Andric     EK_TemplateParameter,
59e8d8bef9SDimitry Andric 
600b57cec5SDimitry Andric     /// The entity being initialized is the result of a function call.
610b57cec5SDimitry Andric     EK_Result,
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric     /// The entity being initialized is the result of a statement expression.
640b57cec5SDimitry Andric     EK_StmtExprResult,
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric     /// The entity being initialized is an exception object that
670b57cec5SDimitry Andric     /// is being thrown.
680b57cec5SDimitry Andric     EK_Exception,
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric     /// The entity being initialized is a non-static data member
710b57cec5SDimitry Andric     /// subobject.
720b57cec5SDimitry Andric     EK_Member,
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric     /// The entity being initialized is an element of an array.
750b57cec5SDimitry Andric     EK_ArrayElement,
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric     /// The entity being initialized is an object (or array of
780b57cec5SDimitry Andric     /// objects) allocated via new.
790b57cec5SDimitry Andric     EK_New,
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric     /// The entity being initialized is a temporary object.
820b57cec5SDimitry Andric     EK_Temporary,
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric     /// The entity being initialized is a base member subobject.
850b57cec5SDimitry Andric     EK_Base,
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric     /// The initialization is being done by a delegating constructor.
880b57cec5SDimitry Andric     EK_Delegating,
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric     /// The entity being initialized is an element of a vector.
910b57cec5SDimitry Andric     /// or vector.
920b57cec5SDimitry Andric     EK_VectorElement,
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric     /// The entity being initialized is a field of block descriptor for
950b57cec5SDimitry Andric     /// the copied-in c++ object.
960b57cec5SDimitry Andric     EK_BlockElement,
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric     /// The entity being initialized is a field of block descriptor for the
990b57cec5SDimitry Andric     /// copied-in lambda object that's used in the lambda to block conversion.
1000b57cec5SDimitry Andric     EK_LambdaToBlockConversionBlockElement,
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric     /// The entity being initialized is the real or imaginary part of a
1030b57cec5SDimitry Andric     /// complex number.
1040b57cec5SDimitry Andric     EK_ComplexElement,
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric     /// The entity being initialized is the field that captures a
1070b57cec5SDimitry Andric     /// variable in a lambda.
1080b57cec5SDimitry Andric     EK_LambdaCapture,
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric     /// The entity being initialized is the initializer for a compound
1110b57cec5SDimitry Andric     /// literal.
1120b57cec5SDimitry Andric     EK_CompoundLiteralInit,
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric     /// The entity being implicitly initialized back to the formal
1150b57cec5SDimitry Andric     /// result type.
1160b57cec5SDimitry Andric     EK_RelatedResult,
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric     /// The entity being initialized is a function parameter; function
1190b57cec5SDimitry Andric     /// is member of group of audited CF APIs.
1200b57cec5SDimitry Andric     EK_Parameter_CF_Audited,
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric     /// The entity being initialized is a structured binding of a
1230b57cec5SDimitry Andric     /// decomposition declaration.
1240b57cec5SDimitry Andric     EK_Binding,
1250b57cec5SDimitry Andric 
1262efbaac7SDimitry Andric     /// The entity being initialized is a non-static data member subobject of an
1272efbaac7SDimitry Andric     /// object initialized via parenthesized aggregate initialization.
1282efbaac7SDimitry Andric     EK_ParenAggInitMember,
1292efbaac7SDimitry Andric 
1300b57cec5SDimitry Andric     // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
1310b57cec5SDimitry Andric     // enum as an index for its first %select.  When modifying this list,
1320b57cec5SDimitry Andric     // that diagnostic text needs to be updated as well.
1330b57cec5SDimitry Andric   };
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric private:
1360b57cec5SDimitry Andric   /// The kind of entity being initialized.
1370b57cec5SDimitry Andric   EntityKind Kind;
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   /// If non-NULL, the parent entity in which this
1400b57cec5SDimitry Andric   /// initialization occurs.
1410b57cec5SDimitry Andric   const InitializedEntity *Parent = nullptr;
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   /// The type of the object or reference being initialized.
1440b57cec5SDimitry Andric   QualType Type;
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   /// The mangling number for the next reference temporary to be created.
1470b57cec5SDimitry Andric   mutable unsigned ManglingNumber = 0;
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   struct LN {
1500b57cec5SDimitry Andric     /// When Kind == EK_Result, EK_Exception, EK_New, the
1510b57cec5SDimitry Andric     /// location of the 'return', 'throw', or 'new' keyword,
1520b57cec5SDimitry Andric     /// respectively. When Kind == EK_Temporary, the location where
1530b57cec5SDimitry Andric     /// the temporary is being created.
154e8d8bef9SDimitry Andric     SourceLocation Location;
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric     /// Whether the entity being initialized may end up using the
1570b57cec5SDimitry Andric     /// named return value optimization (NRVO).
1580b57cec5SDimitry Andric     bool NRVO;
1590b57cec5SDimitry Andric   };
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   struct VD {
1620b57cec5SDimitry Andric     /// The VarDecl, FieldDecl, or BindingDecl being initialized.
1630b57cec5SDimitry Andric     ValueDecl *VariableOrMember;
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric     /// When Kind == EK_Member, whether this is an implicit member
1660b57cec5SDimitry Andric     /// initialization in a copy or move constructor. These can perform array
1670b57cec5SDimitry Andric     /// copies.
1680b57cec5SDimitry Andric     bool IsImplicitFieldInit;
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric     /// When Kind == EK_Member, whether this is the initial initialization
1710b57cec5SDimitry Andric     /// check for a default member initializer.
1720b57cec5SDimitry Andric     bool IsDefaultMemberInit;
1730b57cec5SDimitry Andric   };
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   struct C {
1760b57cec5SDimitry Andric     /// The name of the variable being captured by an EK_LambdaCapture.
1770b57cec5SDimitry Andric     IdentifierInfo *VarID;
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric     /// The source location at which the capture occurs.
180e8d8bef9SDimitry Andric     SourceLocation Location;
1810b57cec5SDimitry Andric   };
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   union {
184e8d8bef9SDimitry Andric     /// When Kind == EK_Variable, EK_Member, EK_Binding, or
185e8d8bef9SDimitry Andric     /// EK_TemplateParameter, the variable, binding, or template parameter.
1860b57cec5SDimitry Andric     VD Variable;
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric     /// When Kind == EK_RelatedResult, the ObjectiveC method where
1890b57cec5SDimitry Andric     /// result type was implicitly changed to accommodate ARC semantics.
1900b57cec5SDimitry Andric     ObjCMethodDecl *MethodDecl;
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric     /// When Kind == EK_Parameter, the ParmVarDecl, with the
193fe6060f1SDimitry Andric     /// integer indicating whether the parameter is "consumed".
194fe6060f1SDimitry Andric     llvm::PointerIntPair<ParmVarDecl *, 1> Parameter;
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric     /// When Kind == EK_Temporary or EK_CompoundLiteralInit, the type
1970b57cec5SDimitry Andric     /// source information for the temporary.
1980b57cec5SDimitry Andric     TypeSourceInfo *TypeInfo;
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric     struct LN LocAndNRVO;
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric     /// When Kind == EK_Base, the base specifier that provides the
203fe6060f1SDimitry Andric     /// base class. The integer specifies whether the base is an inherited
2040b57cec5SDimitry Andric     /// virtual base.
205fe6060f1SDimitry Andric     llvm::PointerIntPair<const CXXBaseSpecifier *, 1> Base;
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric     /// When Kind == EK_ArrayElement, EK_VectorElement, or
2080b57cec5SDimitry Andric     /// EK_ComplexElement, the index of the array or vector element being
2090b57cec5SDimitry Andric     /// initialized.
2100b57cec5SDimitry Andric     unsigned Index;
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric     struct C Capture;
2130b57cec5SDimitry Andric   };
2140b57cec5SDimitry Andric 
InitializedEntity()215e8d8bef9SDimitry Andric   InitializedEntity() {};
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   /// Create the initialization entity for a variable.
2180b57cec5SDimitry Andric   InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
Kind(EK)2190b57cec5SDimitry Andric       : Kind(EK), Type(Var->getType()), Variable{Var, false, false} {}
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   /// Create the initialization entity for the result of a
2220b57cec5SDimitry Andric   /// function, throwing an object, performing an explicit cast, or
2230b57cec5SDimitry Andric   /// initializing a parameter for which there is no declaration.
2240b57cec5SDimitry Andric   InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
2250b57cec5SDimitry Andric                     bool NRVO = false)
Kind(Kind)2260b57cec5SDimitry Andric       : Kind(Kind), Type(Type) {
227e8d8bef9SDimitry Andric     new (&LocAndNRVO) LN;
228e8d8bef9SDimitry Andric     LocAndNRVO.Location = Loc;
2290b57cec5SDimitry Andric     LocAndNRVO.NRVO = NRVO;
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   /// Create the initialization entity for a member subobject.
2330b57cec5SDimitry Andric   InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
2342efbaac7SDimitry Andric                     bool Implicit, bool DefaultMemberInit,
2352efbaac7SDimitry Andric                     bool IsParenAggInit = false)
2362efbaac7SDimitry Andric       : Kind(IsParenAggInit ? EK_ParenAggInitMember : EK_Member),
2372efbaac7SDimitry Andric         Parent(Parent), Type(Member->getType()),
2380b57cec5SDimitry Andric         Variable{Member, Implicit, DefaultMemberInit} {}
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   /// Create the initialization entity for an array element.
2410b57cec5SDimitry Andric   InitializedEntity(ASTContext &Context, unsigned Index,
2420b57cec5SDimitry Andric                     const InitializedEntity &Parent);
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   /// Create the initialization entity for a lambda capture.
InitializedEntity(IdentifierInfo * VarID,QualType FieldType,SourceLocation Loc)2450b57cec5SDimitry Andric   InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
2460b57cec5SDimitry Andric       : Kind(EK_LambdaCapture), Type(FieldType) {
247e8d8bef9SDimitry Andric     new (&Capture) C;
2480b57cec5SDimitry Andric     Capture.VarID = VarID;
249e8d8bef9SDimitry Andric     Capture.Location = Loc;
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric public:
2530b57cec5SDimitry Andric   /// Create the initialization entity for a variable.
InitializeVariable(VarDecl * Var)2540b57cec5SDimitry Andric   static InitializedEntity InitializeVariable(VarDecl *Var) {
2550b57cec5SDimitry Andric     return InitializedEntity(Var);
2560b57cec5SDimitry Andric   }
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   /// Create the initialization entity for a parameter.
InitializeParameter(ASTContext & Context,ParmVarDecl * Parm)2590b57cec5SDimitry Andric   static InitializedEntity InitializeParameter(ASTContext &Context,
260fe6060f1SDimitry Andric                                                ParmVarDecl *Parm) {
2610b57cec5SDimitry Andric     return InitializeParameter(Context, Parm, Parm->getType());
2620b57cec5SDimitry Andric   }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   /// Create the initialization entity for a parameter, but use
2650b57cec5SDimitry Andric   /// another type.
266fe6060f1SDimitry Andric   static InitializedEntity
InitializeParameter(ASTContext & Context,ParmVarDecl * Parm,QualType Type)267fe6060f1SDimitry Andric   InitializeParameter(ASTContext &Context, ParmVarDecl *Parm, QualType Type) {
2680b57cec5SDimitry Andric     bool Consumed = (Context.getLangOpts().ObjCAutoRefCount &&
2690b57cec5SDimitry Andric                      Parm->hasAttr<NSConsumedAttr>());
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric     InitializedEntity Entity;
2720b57cec5SDimitry Andric     Entity.Kind = EK_Parameter;
2730b57cec5SDimitry Andric     Entity.Type =
2740b57cec5SDimitry Andric       Context.getVariableArrayDecayedType(Type.getUnqualifiedType());
2750b57cec5SDimitry Andric     Entity.Parent = nullptr;
276fe6060f1SDimitry Andric     Entity.Parameter = {Parm, Consumed};
2770b57cec5SDimitry Andric     return Entity;
2780b57cec5SDimitry Andric   }
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   /// Create the initialization entity for a parameter that is
2810b57cec5SDimitry Andric   /// only known by its type.
InitializeParameter(ASTContext & Context,QualType Type,bool Consumed)2820b57cec5SDimitry Andric   static InitializedEntity InitializeParameter(ASTContext &Context,
2830b57cec5SDimitry Andric                                                QualType Type,
2840b57cec5SDimitry Andric                                                bool Consumed) {
2850b57cec5SDimitry Andric     InitializedEntity Entity;
2860b57cec5SDimitry Andric     Entity.Kind = EK_Parameter;
2870b57cec5SDimitry Andric     Entity.Type = Context.getVariableArrayDecayedType(Type);
2880b57cec5SDimitry Andric     Entity.Parent = nullptr;
289fe6060f1SDimitry Andric     Entity.Parameter = {nullptr, Consumed};
2900b57cec5SDimitry Andric     return Entity;
2910b57cec5SDimitry Andric   }
2920b57cec5SDimitry Andric 
293e8d8bef9SDimitry Andric   /// Create the initialization entity for a template parameter.
294e8d8bef9SDimitry Andric   static InitializedEntity
InitializeTemplateParameter(QualType T,NonTypeTemplateParmDecl * Param)295e8d8bef9SDimitry Andric   InitializeTemplateParameter(QualType T, NonTypeTemplateParmDecl *Param) {
296e8d8bef9SDimitry Andric     InitializedEntity Entity;
297e8d8bef9SDimitry Andric     Entity.Kind = EK_TemplateParameter;
298e8d8bef9SDimitry Andric     Entity.Type = T;
299e8d8bef9SDimitry Andric     Entity.Parent = nullptr;
300e8d8bef9SDimitry Andric     Entity.Variable = {Param, false, false};
301e8d8bef9SDimitry Andric     return Entity;
302e8d8bef9SDimitry Andric   }
303e8d8bef9SDimitry Andric 
3040b57cec5SDimitry Andric   /// Create the initialization entity for the result of a function.
InitializeResult(SourceLocation ReturnLoc,QualType Type)3050b57cec5SDimitry Andric   static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
30628a41182SDimitry Andric                                             QualType Type) {
30728a41182SDimitry Andric     return InitializedEntity(EK_Result, ReturnLoc, Type);
3080b57cec5SDimitry Andric   }
3090b57cec5SDimitry Andric 
InitializeStmtExprResult(SourceLocation ReturnLoc,QualType Type)3100b57cec5SDimitry Andric   static InitializedEntity InitializeStmtExprResult(SourceLocation ReturnLoc,
3110b57cec5SDimitry Andric                                             QualType Type) {
3120b57cec5SDimitry Andric     return InitializedEntity(EK_StmtExprResult, ReturnLoc, Type);
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
InitializeBlock(SourceLocation BlockVarLoc,QualType Type)3150b57cec5SDimitry Andric   static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc,
31628a41182SDimitry Andric                                            QualType Type) {
31728a41182SDimitry Andric     return InitializedEntity(EK_BlockElement, BlockVarLoc, Type);
3180b57cec5SDimitry Andric   }
3190b57cec5SDimitry Andric 
InitializeLambdaToBlock(SourceLocation BlockVarLoc,QualType Type)3200b57cec5SDimitry Andric   static InitializedEntity InitializeLambdaToBlock(SourceLocation BlockVarLoc,
32128a41182SDimitry Andric                                                    QualType Type) {
3220b57cec5SDimitry Andric     return InitializedEntity(EK_LambdaToBlockConversionBlockElement,
32328a41182SDimitry Andric                              BlockVarLoc, Type);
3240b57cec5SDimitry Andric   }
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   /// Create the initialization entity for an exception object.
InitializeException(SourceLocation ThrowLoc,QualType Type)3270b57cec5SDimitry Andric   static InitializedEntity InitializeException(SourceLocation ThrowLoc,
32828a41182SDimitry Andric                                                QualType Type) {
32928a41182SDimitry Andric     return InitializedEntity(EK_Exception, ThrowLoc, Type);
3300b57cec5SDimitry Andric   }
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   /// Create the initialization entity for an object allocated via new.
InitializeNew(SourceLocation NewLoc,QualType Type)3330b57cec5SDimitry Andric   static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
3340b57cec5SDimitry Andric     return InitializedEntity(EK_New, NewLoc, Type);
3350b57cec5SDimitry Andric   }
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   /// Create the initialization entity for a temporary.
InitializeTemporary(QualType Type)3380b57cec5SDimitry Andric   static InitializedEntity InitializeTemporary(QualType Type) {
3390b57cec5SDimitry Andric     return InitializeTemporary(nullptr, Type);
3400b57cec5SDimitry Andric   }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   /// Create the initialization entity for a temporary.
InitializeTemporary(ASTContext & Context,TypeSourceInfo * TypeInfo)343349cc55cSDimitry Andric   static InitializedEntity InitializeTemporary(ASTContext &Context,
344349cc55cSDimitry Andric                                                TypeSourceInfo *TypeInfo) {
345349cc55cSDimitry Andric     QualType Type = TypeInfo->getType();
346349cc55cSDimitry Andric     if (Context.getLangOpts().OpenCLCPlusPlus) {
347349cc55cSDimitry Andric       assert(!Type.hasAddressSpace() && "Temporary already has address space!");
348349cc55cSDimitry Andric       Type = Context.getAddrSpaceQualType(Type, LangAS::opencl_private);
349349cc55cSDimitry Andric     }
350349cc55cSDimitry Andric 
351349cc55cSDimitry Andric     return InitializeTemporary(TypeInfo, Type);
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   /// Create the initialization entity for a temporary.
InitializeTemporary(TypeSourceInfo * TypeInfo,QualType Type)3550b57cec5SDimitry Andric   static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo,
3560b57cec5SDimitry Andric                                                QualType Type) {
3570b57cec5SDimitry Andric     InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
3580b57cec5SDimitry Andric     Result.TypeInfo = TypeInfo;
3590b57cec5SDimitry Andric     return Result;
3600b57cec5SDimitry Andric   }
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric   /// Create the initialization entity for a related result.
InitializeRelatedResult(ObjCMethodDecl * MD,QualType Type)3630b57cec5SDimitry Andric   static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD,
3640b57cec5SDimitry Andric                                                    QualType Type) {
3650b57cec5SDimitry Andric     InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type);
3660b57cec5SDimitry Andric     Result.MethodDecl = MD;
3670b57cec5SDimitry Andric     return Result;
3680b57cec5SDimitry Andric   }
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric   /// Create the initialization entity for a base class subobject.
3710b57cec5SDimitry Andric   static InitializedEntity
3720b57cec5SDimitry Andric   InitializeBase(ASTContext &Context, const CXXBaseSpecifier *Base,
3730b57cec5SDimitry Andric                  bool IsInheritedVirtualBase,
3740b57cec5SDimitry Andric                  const InitializedEntity *Parent = nullptr);
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   /// Create the initialization entity for a delegated constructor.
InitializeDelegation(QualType Type)3770b57cec5SDimitry Andric   static InitializedEntity InitializeDelegation(QualType Type) {
3780b57cec5SDimitry Andric     return InitializedEntity(EK_Delegating, SourceLocation(), Type);
3790b57cec5SDimitry Andric   }
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric   /// Create the initialization entity for a member subobject.
3820b57cec5SDimitry Andric   static InitializedEntity
3830b57cec5SDimitry Andric   InitializeMember(FieldDecl *Member,
3840b57cec5SDimitry Andric                    const InitializedEntity *Parent = nullptr,
3850b57cec5SDimitry Andric                    bool Implicit = false) {
3860b57cec5SDimitry Andric     return InitializedEntity(Member, Parent, Implicit, false);
3870b57cec5SDimitry Andric   }
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric   /// Create the initialization entity for a member subobject.
3900b57cec5SDimitry Andric   static InitializedEntity
3910b57cec5SDimitry Andric   InitializeMember(IndirectFieldDecl *Member,
3920b57cec5SDimitry Andric                    const InitializedEntity *Parent = nullptr,
3930b57cec5SDimitry Andric                    bool Implicit = false) {
3940b57cec5SDimitry Andric     return InitializedEntity(Member->getAnonField(), Parent, Implicit, false);
3950b57cec5SDimitry Andric   }
3960b57cec5SDimitry Andric 
3972efbaac7SDimitry Andric   /// Create the initialization entity for a member subobject initialized via
3982efbaac7SDimitry Andric   /// parenthesized aggregate init.
InitializeMemberFromParenAggInit(FieldDecl * Member)3992efbaac7SDimitry Andric   static InitializedEntity InitializeMemberFromParenAggInit(FieldDecl *Member) {
4002efbaac7SDimitry Andric     return InitializedEntity(Member, /*Parent=*/nullptr, /*Implicit=*/false,
4012efbaac7SDimitry Andric                              /*DefaultMemberInit=*/false,
4022efbaac7SDimitry Andric                              /*IsParenAggInit=*/true);
4032efbaac7SDimitry Andric   }
4042efbaac7SDimitry Andric 
4050b57cec5SDimitry Andric   /// Create the initialization entity for a default member initializer.
4060b57cec5SDimitry Andric   static InitializedEntity
InitializeMemberFromDefaultMemberInitializer(FieldDecl * Member)4070b57cec5SDimitry Andric   InitializeMemberFromDefaultMemberInitializer(FieldDecl *Member) {
4080b57cec5SDimitry Andric     return InitializedEntity(Member, nullptr, false, true);
4090b57cec5SDimitry Andric   }
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric   /// Create the initialization entity for an array element.
InitializeElement(ASTContext & Context,unsigned Index,const InitializedEntity & Parent)4120b57cec5SDimitry Andric   static InitializedEntity InitializeElement(ASTContext &Context,
4130b57cec5SDimitry Andric                                              unsigned Index,
4140b57cec5SDimitry Andric                                              const InitializedEntity &Parent) {
4150b57cec5SDimitry Andric     return InitializedEntity(Context, Index, Parent);
4160b57cec5SDimitry Andric   }
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   /// Create the initialization entity for a structured binding.
InitializeBinding(VarDecl * Binding)4190b57cec5SDimitry Andric   static InitializedEntity InitializeBinding(VarDecl *Binding) {
4200b57cec5SDimitry Andric     return InitializedEntity(Binding, EK_Binding);
4210b57cec5SDimitry Andric   }
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   /// Create the initialization entity for a lambda capture.
4240b57cec5SDimitry Andric   ///
4250b57cec5SDimitry Andric   /// \p VarID The name of the entity being captured, or nullptr for 'this'.
InitializeLambdaCapture(IdentifierInfo * VarID,QualType FieldType,SourceLocation Loc)4260b57cec5SDimitry Andric   static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID,
4270b57cec5SDimitry Andric                                                    QualType FieldType,
4280b57cec5SDimitry Andric                                                    SourceLocation Loc) {
4290b57cec5SDimitry Andric     return InitializedEntity(VarID, FieldType, Loc);
4300b57cec5SDimitry Andric   }
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   /// Create the entity for a compound literal initializer.
InitializeCompoundLiteralInit(TypeSourceInfo * TSI)4330b57cec5SDimitry Andric   static InitializedEntity InitializeCompoundLiteralInit(TypeSourceInfo *TSI) {
4340b57cec5SDimitry Andric     InitializedEntity Result(EK_CompoundLiteralInit, SourceLocation(),
4350b57cec5SDimitry Andric                              TSI->getType());
4360b57cec5SDimitry Andric     Result.TypeInfo = TSI;
4370b57cec5SDimitry Andric     return Result;
4380b57cec5SDimitry Andric   }
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric   /// Determine the kind of initialization.
getKind()4410b57cec5SDimitry Andric   EntityKind getKind() const { return Kind; }
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric   /// Retrieve the parent of the entity being initialized, when
4440b57cec5SDimitry Andric   /// the initialization itself is occurring within the context of a
4450b57cec5SDimitry Andric   /// larger initialization.
getParent()4460b57cec5SDimitry Andric   const InitializedEntity *getParent() const { return Parent; }
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric   /// Retrieve type being initialized.
getType()4490b57cec5SDimitry Andric   QualType getType() const { return Type; }
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   /// Retrieve complete type-source information for the object being
4520b57cec5SDimitry Andric   /// constructed, if known.
getTypeSourceInfo()4530b57cec5SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() const {
4540b57cec5SDimitry Andric     if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit)
4550b57cec5SDimitry Andric       return TypeInfo;
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric     return nullptr;
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   /// Retrieve the name of the entity being initialized.
4610b57cec5SDimitry Andric   DeclarationName getName() const;
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   /// Retrieve the variable, parameter, or field being
4640b57cec5SDimitry Andric   /// initialized.
4650b57cec5SDimitry Andric   ValueDecl *getDecl() const;
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric   /// Retrieve the ObjectiveC method being initialized.
getMethodDecl()4680b57cec5SDimitry Andric   ObjCMethodDecl *getMethodDecl() const { return MethodDecl; }
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   /// Determine whether this initialization allows the named return
4710b57cec5SDimitry Andric   /// value optimization, which also applies to thrown objects.
4720b57cec5SDimitry Andric   bool allowsNRVO() const;
4730b57cec5SDimitry Andric 
isParameterKind()4740b57cec5SDimitry Andric   bool isParameterKind() const {
4750b57cec5SDimitry Andric     return (getKind() == EK_Parameter  ||
4760b57cec5SDimitry Andric             getKind() == EK_Parameter_CF_Audited);
4770b57cec5SDimitry Andric   }
4780b57cec5SDimitry Andric 
isParamOrTemplateParamKind()479e8d8bef9SDimitry Andric   bool isParamOrTemplateParamKind() const {
480e8d8bef9SDimitry Andric     return isParameterKind() || getKind() == EK_TemplateParameter;
481e8d8bef9SDimitry Andric   }
482e8d8bef9SDimitry Andric 
4830b57cec5SDimitry Andric   /// Determine whether this initialization consumes the
4840b57cec5SDimitry Andric   /// parameter.
isParameterConsumed()4850b57cec5SDimitry Andric   bool isParameterConsumed() const {
4860b57cec5SDimitry Andric     assert(isParameterKind() && "Not a parameter");
487fe6060f1SDimitry Andric     return Parameter.getInt();
4880b57cec5SDimitry Andric   }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   /// Retrieve the base specifier.
getBaseSpecifier()4910b57cec5SDimitry Andric   const CXXBaseSpecifier *getBaseSpecifier() const {
4920b57cec5SDimitry Andric     assert(getKind() == EK_Base && "Not a base specifier");
493fe6060f1SDimitry Andric     return Base.getPointer();
4940b57cec5SDimitry Andric   }
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric   /// Return whether the base is an inherited virtual base.
isInheritedVirtualBase()4970b57cec5SDimitry Andric   bool isInheritedVirtualBase() const {
4980b57cec5SDimitry Andric     assert(getKind() == EK_Base && "Not a base specifier");
499fe6060f1SDimitry Andric     return Base.getInt();
5000b57cec5SDimitry Andric   }
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   /// Determine whether this is an array new with an unknown bound.
isVariableLengthArrayNew()5030b57cec5SDimitry Andric   bool isVariableLengthArrayNew() const {
504349cc55cSDimitry Andric     return getKind() == EK_New && isa_and_nonnull<IncompleteArrayType>(
5050b57cec5SDimitry Andric                                       getType()->getAsArrayTypeUnsafe());
5060b57cec5SDimitry Andric   }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   /// Is this the implicit initialization of a member of a class from
5090b57cec5SDimitry Andric   /// a defaulted constructor?
isImplicitMemberInitializer()5100b57cec5SDimitry Andric   bool isImplicitMemberInitializer() const {
5110b57cec5SDimitry Andric     return getKind() == EK_Member && Variable.IsImplicitFieldInit;
5120b57cec5SDimitry Andric   }
5130b57cec5SDimitry Andric 
5140b57cec5SDimitry Andric   /// Is this the default member initializer of a member (specified inside
5150b57cec5SDimitry Andric   /// the class definition)?
isDefaultMemberInitializer()5160b57cec5SDimitry Andric   bool isDefaultMemberInitializer() const {
5170b57cec5SDimitry Andric     return getKind() == EK_Member && Variable.IsDefaultMemberInit;
5180b57cec5SDimitry Andric   }
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric   /// Determine the location of the 'return' keyword when initializing
5210b57cec5SDimitry Andric   /// the result of a function call.
getReturnLoc()5220b57cec5SDimitry Andric   SourceLocation getReturnLoc() const {
5230b57cec5SDimitry Andric     assert(getKind() == EK_Result && "No 'return' location!");
524e8d8bef9SDimitry Andric     return LocAndNRVO.Location;
5250b57cec5SDimitry Andric   }
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric   /// Determine the location of the 'throw' keyword when initializing
5280b57cec5SDimitry Andric   /// an exception object.
getThrowLoc()5290b57cec5SDimitry Andric   SourceLocation getThrowLoc() const {
5300b57cec5SDimitry Andric     assert(getKind() == EK_Exception && "No 'throw' location!");
531e8d8bef9SDimitry Andric     return LocAndNRVO.Location;
5320b57cec5SDimitry Andric   }
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric   /// If this is an array, vector, or complex number element, get the
5350b57cec5SDimitry Andric   /// element's index.
getElementIndex()5360b57cec5SDimitry Andric   unsigned getElementIndex() const {
5370b57cec5SDimitry Andric     assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
5380b57cec5SDimitry Andric            getKind() == EK_ComplexElement);
5390b57cec5SDimitry Andric     return Index;
5400b57cec5SDimitry Andric   }
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric   /// If this is already the initializer for an array or vector
5430b57cec5SDimitry Andric   /// element, sets the element index.
setElementIndex(unsigned Index)5440b57cec5SDimitry Andric   void setElementIndex(unsigned Index) {
5450b57cec5SDimitry Andric     assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
5460b57cec5SDimitry Andric            getKind() == EK_ComplexElement);
5470b57cec5SDimitry Andric     this->Index = Index;
5480b57cec5SDimitry Andric   }
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric   /// For a lambda capture, return the capture's name.
getCapturedVarName()5510b57cec5SDimitry Andric   StringRef getCapturedVarName() const {
5520b57cec5SDimitry Andric     assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
5530b57cec5SDimitry Andric     return Capture.VarID ? Capture.VarID->getName() : "this";
5540b57cec5SDimitry Andric   }
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric   /// Determine the location of the capture when initializing
5570b57cec5SDimitry Andric   /// field from a captured variable in a lambda.
getCaptureLoc()5580b57cec5SDimitry Andric   SourceLocation getCaptureLoc() const {
5590b57cec5SDimitry Andric     assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
560e8d8bef9SDimitry Andric     return Capture.Location;
5610b57cec5SDimitry Andric   }
5620b57cec5SDimitry Andric 
setParameterCFAudited()5630b57cec5SDimitry Andric   void setParameterCFAudited() {
5640b57cec5SDimitry Andric     Kind = EK_Parameter_CF_Audited;
5650b57cec5SDimitry Andric   }
5660b57cec5SDimitry Andric 
allocateManglingNumber()5670b57cec5SDimitry Andric   unsigned allocateManglingNumber() const { return ++ManglingNumber; }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   /// Dump a representation of the initialized entity to standard error,
5700b57cec5SDimitry Andric   /// for debugging purposes.
5710b57cec5SDimitry Andric   void dump() const;
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric private:
5740b57cec5SDimitry Andric   unsigned dumpImpl(raw_ostream &OS) const;
5750b57cec5SDimitry Andric };
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric /// Describes the kind of initialization being performed, along with
5780b57cec5SDimitry Andric /// location information for tokens related to the initialization (equal sign,
5790b57cec5SDimitry Andric /// parentheses).
5800b57cec5SDimitry Andric class InitializationKind {
5810b57cec5SDimitry Andric public:
5820b57cec5SDimitry Andric   /// The kind of initialization being performed.
5830b57cec5SDimitry Andric   enum InitKind {
5840b57cec5SDimitry Andric     /// Direct initialization
5850b57cec5SDimitry Andric     IK_Direct,
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric     /// Direct list-initialization
5880b57cec5SDimitry Andric     IK_DirectList,
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric     /// Copy initialization
5910b57cec5SDimitry Andric     IK_Copy,
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric     /// Default initialization
5940b57cec5SDimitry Andric     IK_Default,
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric     /// Value initialization
5970b57cec5SDimitry Andric     IK_Value
5980b57cec5SDimitry Andric   };
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric private:
6010b57cec5SDimitry Andric   /// The context of the initialization.
6020b57cec5SDimitry Andric   enum InitContext {
6030b57cec5SDimitry Andric     /// Normal context
6040b57cec5SDimitry Andric     IC_Normal,
6050b57cec5SDimitry Andric 
6060b57cec5SDimitry Andric     /// Normal context, but allows explicit conversion functionss
6070b57cec5SDimitry Andric     IC_ExplicitConvs,
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric     /// Implicit context (value initialization)
6100b57cec5SDimitry Andric     IC_Implicit,
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric     /// Static cast context
6130b57cec5SDimitry Andric     IC_StaticCast,
6140b57cec5SDimitry Andric 
6150b57cec5SDimitry Andric     /// C-style cast context
6160b57cec5SDimitry Andric     IC_CStyleCast,
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric     /// Functional cast context
6190b57cec5SDimitry Andric     IC_FunctionalCast
6200b57cec5SDimitry Andric   };
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric   /// The kind of initialization being performed.
6230b57cec5SDimitry Andric   InitKind Kind : 8;
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric   /// The context of the initialization.
6260b57cec5SDimitry Andric   InitContext Context : 8;
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric   /// The source locations involved in the initialization.
6290b57cec5SDimitry Andric   SourceLocation Locations[3];
6300b57cec5SDimitry Andric 
InitializationKind(InitKind Kind,InitContext Context,SourceLocation Loc1,SourceLocation Loc2,SourceLocation Loc3)6310b57cec5SDimitry Andric   InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1,
6320b57cec5SDimitry Andric                      SourceLocation Loc2, SourceLocation Loc3)
6330b57cec5SDimitry Andric       : Kind(Kind), Context(Context) {
6340b57cec5SDimitry Andric     Locations[0] = Loc1;
6350b57cec5SDimitry Andric     Locations[1] = Loc2;
6360b57cec5SDimitry Andric     Locations[2] = Loc3;
6370b57cec5SDimitry Andric   }
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric public:
6400b57cec5SDimitry Andric   /// Create a direct initialization.
CreateDirect(SourceLocation InitLoc,SourceLocation LParenLoc,SourceLocation RParenLoc)6410b57cec5SDimitry Andric   static InitializationKind CreateDirect(SourceLocation InitLoc,
6420b57cec5SDimitry Andric                                          SourceLocation LParenLoc,
6430b57cec5SDimitry Andric                                          SourceLocation RParenLoc) {
6440b57cec5SDimitry Andric     return InitializationKind(IK_Direct, IC_Normal,
6450b57cec5SDimitry Andric                               InitLoc, LParenLoc, RParenLoc);
6460b57cec5SDimitry Andric   }
6470b57cec5SDimitry Andric 
CreateDirectList(SourceLocation InitLoc)6480b57cec5SDimitry Andric   static InitializationKind CreateDirectList(SourceLocation InitLoc) {
6490b57cec5SDimitry Andric     return InitializationKind(IK_DirectList, IC_Normal, InitLoc, InitLoc,
6500b57cec5SDimitry Andric                               InitLoc);
6510b57cec5SDimitry Andric   }
6520b57cec5SDimitry Andric 
CreateDirectList(SourceLocation InitLoc,SourceLocation LBraceLoc,SourceLocation RBraceLoc)6530b57cec5SDimitry Andric   static InitializationKind CreateDirectList(SourceLocation InitLoc,
6540b57cec5SDimitry Andric                                              SourceLocation LBraceLoc,
6550b57cec5SDimitry Andric                                              SourceLocation RBraceLoc) {
6560b57cec5SDimitry Andric     return InitializationKind(IK_DirectList, IC_Normal, InitLoc, LBraceLoc,
6570b57cec5SDimitry Andric                               RBraceLoc);
6580b57cec5SDimitry Andric   }
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   /// Create a direct initialization due to a cast that isn't a C-style
6610b57cec5SDimitry Andric   /// or functional cast.
CreateCast(SourceRange TypeRange)6620b57cec5SDimitry Andric   static InitializationKind CreateCast(SourceRange TypeRange) {
6630b57cec5SDimitry Andric     return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(),
6640b57cec5SDimitry Andric                               TypeRange.getBegin(), TypeRange.getEnd());
6650b57cec5SDimitry Andric   }
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric   /// Create a direct initialization for a C-style cast.
CreateCStyleCast(SourceLocation StartLoc,SourceRange TypeRange,bool InitList)6680b57cec5SDimitry Andric   static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
6690b57cec5SDimitry Andric                                              SourceRange TypeRange,
6700b57cec5SDimitry Andric                                              bool InitList) {
6710b57cec5SDimitry Andric     // C++ cast syntax doesn't permit init lists, but C compound literals are
6720b57cec5SDimitry Andric     // exactly that.
6730b57cec5SDimitry Andric     return InitializationKind(InitList ? IK_DirectList : IK_Direct,
6740b57cec5SDimitry Andric                               IC_CStyleCast, StartLoc, TypeRange.getBegin(),
6750b57cec5SDimitry Andric                               TypeRange.getEnd());
6760b57cec5SDimitry Andric   }
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric   /// Create a direct initialization for a functional cast.
CreateFunctionalCast(SourceRange TypeRange,bool InitList)6790b57cec5SDimitry Andric   static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
6800b57cec5SDimitry Andric                                                  bool InitList) {
6810b57cec5SDimitry Andric     return InitializationKind(InitList ? IK_DirectList : IK_Direct,
6820b57cec5SDimitry Andric                               IC_FunctionalCast, TypeRange.getBegin(),
6830b57cec5SDimitry Andric                               TypeRange.getBegin(), TypeRange.getEnd());
6840b57cec5SDimitry Andric   }
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric   /// Create a copy initialization.
6870b57cec5SDimitry Andric   static InitializationKind CreateCopy(SourceLocation InitLoc,
6880b57cec5SDimitry Andric                                        SourceLocation EqualLoc,
6890b57cec5SDimitry Andric                                        bool AllowExplicitConvs = false) {
6900b57cec5SDimitry Andric     return InitializationKind(IK_Copy,
6910b57cec5SDimitry Andric                               AllowExplicitConvs? IC_ExplicitConvs : IC_Normal,
6920b57cec5SDimitry Andric                               InitLoc, EqualLoc, EqualLoc);
6930b57cec5SDimitry Andric   }
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric   /// Create a default initialization.
CreateDefault(SourceLocation InitLoc)6960b57cec5SDimitry Andric   static InitializationKind CreateDefault(SourceLocation InitLoc) {
6970b57cec5SDimitry Andric     return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
6980b57cec5SDimitry Andric   }
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   /// Create a value initialization.
7010b57cec5SDimitry Andric   static InitializationKind CreateValue(SourceLocation InitLoc,
7020b57cec5SDimitry Andric                                         SourceLocation LParenLoc,
7030b57cec5SDimitry Andric                                         SourceLocation RParenLoc,
7040b57cec5SDimitry Andric                                         bool isImplicit = false) {
7050b57cec5SDimitry Andric     return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
7060b57cec5SDimitry Andric                               InitLoc, LParenLoc, RParenLoc);
7070b57cec5SDimitry Andric   }
7080b57cec5SDimitry Andric 
7090b57cec5SDimitry Andric   /// Create an initialization from an initializer (which, for direct
7100b57cec5SDimitry Andric   /// initialization from a parenthesized list, will be a ParenListExpr).
CreateForInit(SourceLocation Loc,bool DirectInit,Expr * Init)7110b57cec5SDimitry Andric   static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit,
7120b57cec5SDimitry Andric                                           Expr *Init) {
7130b57cec5SDimitry Andric     if (!Init) return CreateDefault(Loc);
7140b57cec5SDimitry Andric     if (!DirectInit)
7150b57cec5SDimitry Andric       return CreateCopy(Loc, Init->getBeginLoc());
7160b57cec5SDimitry Andric     if (isa<InitListExpr>(Init))
7170b57cec5SDimitry Andric       return CreateDirectList(Loc, Init->getBeginLoc(), Init->getEndLoc());
7180b57cec5SDimitry Andric     return CreateDirect(Loc, Init->getBeginLoc(), Init->getEndLoc());
7190b57cec5SDimitry Andric   }
7200b57cec5SDimitry Andric 
7210b57cec5SDimitry Andric   /// Determine the initialization kind.
getKind()7220b57cec5SDimitry Andric   InitKind getKind() const {
7230b57cec5SDimitry Andric     return Kind;
7240b57cec5SDimitry Andric   }
7250b57cec5SDimitry Andric 
7260b57cec5SDimitry Andric   /// Determine whether this initialization is an explicit cast.
isExplicitCast()7270b57cec5SDimitry Andric   bool isExplicitCast() const {
7280b57cec5SDimitry Andric     return Context >= IC_StaticCast;
7290b57cec5SDimitry Andric   }
7300b57cec5SDimitry Andric 
7315ffd83dbSDimitry Andric   /// Determine whether this initialization is a static cast.
isStaticCast()7325ffd83dbSDimitry Andric   bool isStaticCast() const { return Context == IC_StaticCast; }
7335ffd83dbSDimitry Andric 
7340b57cec5SDimitry Andric   /// Determine whether this initialization is a C-style cast.
isCStyleOrFunctionalCast()7350b57cec5SDimitry Andric   bool isCStyleOrFunctionalCast() const {
7360b57cec5SDimitry Andric     return Context >= IC_CStyleCast;
7370b57cec5SDimitry Andric   }
7380b57cec5SDimitry Andric 
7390b57cec5SDimitry Andric   /// Determine whether this is a C-style cast.
isCStyleCast()7400b57cec5SDimitry Andric   bool isCStyleCast() const {
7410b57cec5SDimitry Andric     return Context == IC_CStyleCast;
7420b57cec5SDimitry Andric   }
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric   /// Determine whether this is a functional-style cast.
isFunctionalCast()7450b57cec5SDimitry Andric   bool isFunctionalCast() const {
7460b57cec5SDimitry Andric     return Context == IC_FunctionalCast;
7470b57cec5SDimitry Andric   }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric   /// Determine whether this initialization is an implicit
7500b57cec5SDimitry Andric   /// value-initialization, e.g., as occurs during aggregate
7510b57cec5SDimitry Andric   /// initialization.
isImplicitValueInit()7520b57cec5SDimitry Andric   bool isImplicitValueInit() const { return Context == IC_Implicit; }
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric   /// Retrieve the location at which initialization is occurring.
getLocation()7550b57cec5SDimitry Andric   SourceLocation getLocation() const { return Locations[0]; }
7560b57cec5SDimitry Andric 
7570b57cec5SDimitry Andric   /// Retrieve the source range that covers the initialization.
getRange()7580b57cec5SDimitry Andric   SourceRange getRange() const {
7590b57cec5SDimitry Andric     return SourceRange(Locations[0], Locations[2]);
7600b57cec5SDimitry Andric   }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric   /// Retrieve the location of the equal sign for copy initialization
7630b57cec5SDimitry Andric   /// (if present).
getEqualLoc()7640b57cec5SDimitry Andric   SourceLocation getEqualLoc() const {
7650b57cec5SDimitry Andric     assert(Kind == IK_Copy && "Only copy initialization has an '='");
7660b57cec5SDimitry Andric     return Locations[1];
7670b57cec5SDimitry Andric   }
7680b57cec5SDimitry Andric 
isCopyInit()7690b57cec5SDimitry Andric   bool isCopyInit() const { return Kind == IK_Copy; }
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   /// Retrieve whether this initialization allows the use of explicit
7720b57cec5SDimitry Andric   ///        constructors.
AllowExplicit()7730b57cec5SDimitry Andric   bool AllowExplicit() const { return !isCopyInit(); }
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric   /// Retrieve whether this initialization allows the use of explicit
7760b57cec5SDimitry Andric   /// conversion functions when binding a reference. If the reference is the
7770b57cec5SDimitry Andric   /// first parameter in a copy or move constructor, such conversions are
7780b57cec5SDimitry Andric   /// permitted even though we are performing copy-initialization.
allowExplicitConversionFunctionsInRefBinding()7790b57cec5SDimitry Andric   bool allowExplicitConversionFunctionsInRefBinding() const {
7800b57cec5SDimitry Andric     return !isCopyInit() || Context == IC_ExplicitConvs;
7810b57cec5SDimitry Andric   }
7820b57cec5SDimitry Andric 
7830b57cec5SDimitry Andric   /// Determine whether this initialization has a source range containing the
7840b57cec5SDimitry Andric   /// locations of open and closing parentheses or braces.
hasParenOrBraceRange()7850b57cec5SDimitry Andric   bool hasParenOrBraceRange() const {
7860b57cec5SDimitry Andric     return Kind == IK_Direct || Kind == IK_Value || Kind == IK_DirectList;
7870b57cec5SDimitry Andric   }
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric   /// Retrieve the source range containing the locations of the open
7900b57cec5SDimitry Andric   /// and closing parentheses or braces for value, direct, and direct list
7910b57cec5SDimitry Andric   /// initializations.
getParenOrBraceRange()7920b57cec5SDimitry Andric   SourceRange getParenOrBraceRange() const {
7930b57cec5SDimitry Andric     assert(hasParenOrBraceRange() && "Only direct, value, and direct-list "
7940b57cec5SDimitry Andric                                      "initialization have parentheses or "
7950b57cec5SDimitry Andric                                      "braces");
7960b57cec5SDimitry Andric     return SourceRange(Locations[1], Locations[2]);
7970b57cec5SDimitry Andric   }
7980b57cec5SDimitry Andric };
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric /// Describes the sequence of initializations required to initialize
8010b57cec5SDimitry Andric /// a given object or reference with a set of arguments.
8020b57cec5SDimitry Andric class InitializationSequence {
8030b57cec5SDimitry Andric public:
8040b57cec5SDimitry Andric   /// Describes the kind of initialization sequence computed.
8050b57cec5SDimitry Andric   enum SequenceKind {
8060b57cec5SDimitry Andric     /// A failed initialization sequence. The failure kind tells what
8070b57cec5SDimitry Andric     /// happened.
8080b57cec5SDimitry Andric     FailedSequence = 0,
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric     /// A dependent initialization, which could not be
8110b57cec5SDimitry Andric     /// type-checked due to the presence of dependent types or
8120b57cec5SDimitry Andric     /// dependently-typed expressions.
8130b57cec5SDimitry Andric     DependentSequence,
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric     /// A normal sequence.
8160b57cec5SDimitry Andric     NormalSequence
8170b57cec5SDimitry Andric   };
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   /// Describes the kind of a particular step in an initialization
8200b57cec5SDimitry Andric   /// sequence.
8210b57cec5SDimitry Andric   enum StepKind {
8220b57cec5SDimitry Andric     /// Resolve the address of an overloaded function to a specific
8230b57cec5SDimitry Andric     /// function declaration.
8240b57cec5SDimitry Andric     SK_ResolveAddressOfOverloadedFunction,
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric     /// Perform a derived-to-base cast, producing an rvalue.
827fe6060f1SDimitry Andric     SK_CastDerivedToBasePRValue,
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric     /// Perform a derived-to-base cast, producing an xvalue.
8300b57cec5SDimitry Andric     SK_CastDerivedToBaseXValue,
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric     /// Perform a derived-to-base cast, producing an lvalue.
8330b57cec5SDimitry Andric     SK_CastDerivedToBaseLValue,
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric     /// Reference binding to an lvalue.
8360b57cec5SDimitry Andric     SK_BindReference,
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric     /// Reference binding to a temporary.
8390b57cec5SDimitry Andric     SK_BindReferenceToTemporary,
8400b57cec5SDimitry Andric 
8410b57cec5SDimitry Andric     /// An optional copy of a temporary object to another
8420b57cec5SDimitry Andric     /// temporary object, which is permitted (but not required) by
8430b57cec5SDimitry Andric     /// C++98/03 but not C++0x.
8440b57cec5SDimitry Andric     SK_ExtraneousCopyToTemporary,
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric     /// Direct-initialization from a reference-related object in the
8470b57cec5SDimitry Andric     /// final stage of class copy-initialization.
8480b57cec5SDimitry Andric     SK_FinalCopy,
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric     /// Perform a user-defined conversion, either via a conversion
8510b57cec5SDimitry Andric     /// function or via a constructor.
8520b57cec5SDimitry Andric     SK_UserConversion,
8530b57cec5SDimitry Andric 
854fe6060f1SDimitry Andric     /// Perform a qualification conversion, producing a prvalue.
855fe6060f1SDimitry Andric     SK_QualificationConversionPRValue,
8560b57cec5SDimitry Andric 
8570b57cec5SDimitry Andric     /// Perform a qualification conversion, producing an xvalue.
8580b57cec5SDimitry Andric     SK_QualificationConversionXValue,
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric     /// Perform a qualification conversion, producing an lvalue.
8610b57cec5SDimitry Andric     SK_QualificationConversionLValue,
8620b57cec5SDimitry Andric 
863e8d8bef9SDimitry Andric     /// Perform a function reference conversion, see [dcl.init.ref]p4.
864e8d8bef9SDimitry Andric     SK_FunctionReferenceConversion,
865e8d8bef9SDimitry Andric 
8660b57cec5SDimitry Andric     /// Perform a conversion adding _Atomic to a type.
8670b57cec5SDimitry Andric     SK_AtomicConversion,
8680b57cec5SDimitry Andric 
8690b57cec5SDimitry Andric     /// Perform an implicit conversion sequence.
8700b57cec5SDimitry Andric     SK_ConversionSequence,
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric     /// Perform an implicit conversion sequence without narrowing.
8730b57cec5SDimitry Andric     SK_ConversionSequenceNoNarrowing,
8740b57cec5SDimitry Andric 
8750b57cec5SDimitry Andric     /// Perform list-initialization without a constructor.
8760b57cec5SDimitry Andric     SK_ListInitialization,
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric     /// Unwrap the single-element initializer list for a reference.
8790b57cec5SDimitry Andric     SK_UnwrapInitList,
8800b57cec5SDimitry Andric 
8810b57cec5SDimitry Andric     /// Rewrap the single-element initializer list for a reference.
8820b57cec5SDimitry Andric     SK_RewrapInitList,
8830b57cec5SDimitry Andric 
8840b57cec5SDimitry Andric     /// Perform initialization via a constructor.
8850b57cec5SDimitry Andric     SK_ConstructorInitialization,
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric     /// Perform initialization via a constructor, taking arguments from
8880b57cec5SDimitry Andric     /// a single InitListExpr.
8890b57cec5SDimitry Andric     SK_ConstructorInitializationFromList,
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric     /// Zero-initialize the object
8920b57cec5SDimitry Andric     SK_ZeroInitialization,
8930b57cec5SDimitry Andric 
8940b57cec5SDimitry Andric     /// C assignment
8950b57cec5SDimitry Andric     SK_CAssignment,
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric     /// Initialization by string
8980b57cec5SDimitry Andric     SK_StringInit,
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric     /// An initialization that "converts" an Objective-C object
9010b57cec5SDimitry Andric     /// (not a point to an object) to another Objective-C object type.
9020b57cec5SDimitry Andric     SK_ObjCObjectConversion,
9030b57cec5SDimitry Andric 
9040b57cec5SDimitry Andric     /// Array indexing for initialization by elementwise copy.
9050b57cec5SDimitry Andric     SK_ArrayLoopIndex,
9060b57cec5SDimitry Andric 
9070b57cec5SDimitry Andric     /// Array initialization by elementwise copy.
9080b57cec5SDimitry Andric     SK_ArrayLoopInit,
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric     /// Array initialization (from an array rvalue).
9110b57cec5SDimitry Andric     SK_ArrayInit,
9120b57cec5SDimitry Andric 
9130b57cec5SDimitry Andric     /// Array initialization (from an array rvalue) as a GNU extension.
9140b57cec5SDimitry Andric     SK_GNUArrayInit,
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric     /// Array initialization from a parenthesized initializer list.
9170b57cec5SDimitry Andric     /// This is a GNU C++ extension.
9180b57cec5SDimitry Andric     SK_ParenthesizedArrayInit,
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric     /// Pass an object by indirect copy-and-restore.
9210b57cec5SDimitry Andric     SK_PassByIndirectCopyRestore,
9220b57cec5SDimitry Andric 
9230b57cec5SDimitry Andric     /// Pass an object by indirect restore.
9240b57cec5SDimitry Andric     SK_PassByIndirectRestore,
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric     /// Produce an Objective-C object pointer.
9270b57cec5SDimitry Andric     SK_ProduceObjCObject,
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric     /// Construct a std::initializer_list from an initializer list.
9300b57cec5SDimitry Andric     SK_StdInitializerList,
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric     /// Perform initialization via a constructor taking a single
9330b57cec5SDimitry Andric     /// std::initializer_list argument.
9340b57cec5SDimitry Andric     SK_StdInitializerListConstructorCall,
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric     /// Initialize an OpenCL sampler from an integer.
9370b57cec5SDimitry Andric     SK_OCLSamplerInit,
9380b57cec5SDimitry Andric 
9390b57cec5SDimitry Andric     /// Initialize an opaque OpenCL type (event_t, queue_t, etc.) with zero
940bdd1243dSDimitry Andric     SK_OCLZeroOpaqueType,
941bdd1243dSDimitry Andric 
942bdd1243dSDimitry Andric     /// Initialize an aggreagate with parenthesized list of values.
943bdd1243dSDimitry Andric     /// This is a C++20 feature.
944bdd1243dSDimitry Andric     SK_ParenthesizedListInit
9450b57cec5SDimitry Andric   };
9460b57cec5SDimitry Andric 
9470b57cec5SDimitry Andric   /// A single step in the initialization sequence.
9480b57cec5SDimitry Andric   class Step {
9490b57cec5SDimitry Andric   public:
9500b57cec5SDimitry Andric     /// The kind of conversion or initialization step we are taking.
9510b57cec5SDimitry Andric     StepKind Kind;
9520b57cec5SDimitry Andric 
9530b57cec5SDimitry Andric     // The type that results from this initialization.
9540b57cec5SDimitry Andric     QualType Type;
9550b57cec5SDimitry Andric 
9560b57cec5SDimitry Andric     struct F {
9570b57cec5SDimitry Andric       bool HadMultipleCandidates;
9580b57cec5SDimitry Andric       FunctionDecl *Function;
9590b57cec5SDimitry Andric       DeclAccessPair FoundDecl;
9600b57cec5SDimitry Andric     };
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric     union {
9630b57cec5SDimitry Andric       /// When Kind == SK_ResolvedOverloadedFunction or Kind ==
9640b57cec5SDimitry Andric       /// SK_UserConversion, the function that the expression should be
9650b57cec5SDimitry Andric       /// resolved to or the conversion function to call, respectively.
9660b57cec5SDimitry Andric       /// When Kind == SK_ConstructorInitialization or SK_ListConstruction,
9670b57cec5SDimitry Andric       /// the constructor to be called.
9680b57cec5SDimitry Andric       ///
9690b57cec5SDimitry Andric       /// Always a FunctionDecl, plus a Boolean flag telling if it was
9700b57cec5SDimitry Andric       /// selected from an overloaded set having size greater than 1.
9710b57cec5SDimitry Andric       /// For conversion decls, the naming class is the source type.
9720b57cec5SDimitry Andric       /// For construct decls, the naming class is the target type.
9730b57cec5SDimitry Andric       struct F Function;
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric       /// When Kind = SK_ConversionSequence, the implicit conversion
9760b57cec5SDimitry Andric       /// sequence.
9770b57cec5SDimitry Andric       ImplicitConversionSequence *ICS;
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric       /// When Kind = SK_RewrapInitList, the syntactic form of the
9800b57cec5SDimitry Andric       /// wrapping list.
9810b57cec5SDimitry Andric       InitListExpr *WrappingSyntacticList;
9820b57cec5SDimitry Andric     };
9830b57cec5SDimitry Andric 
9840b57cec5SDimitry Andric     void Destroy();
9850b57cec5SDimitry Andric   };
9860b57cec5SDimitry Andric 
9870b57cec5SDimitry Andric private:
9880b57cec5SDimitry Andric   /// The kind of initialization sequence computed.
9890b57cec5SDimitry Andric   enum SequenceKind SequenceKind;
9900b57cec5SDimitry Andric 
9910b57cec5SDimitry Andric   /// Steps taken by this initialization.
9920b57cec5SDimitry Andric   SmallVector<Step, 4> Steps;
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric public:
9950b57cec5SDimitry Andric   /// Describes why initialization failed.
9960b57cec5SDimitry Andric   enum FailureKind {
9970b57cec5SDimitry Andric     /// Too many initializers provided for a reference.
9980b57cec5SDimitry Andric     FK_TooManyInitsForReference,
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric     /// Reference initialized from a parenthesized initializer list.
10010b57cec5SDimitry Andric     FK_ParenthesizedListInitForReference,
10020b57cec5SDimitry Andric 
10030b57cec5SDimitry Andric     /// Array must be initialized with an initializer list.
10040b57cec5SDimitry Andric     FK_ArrayNeedsInitList,
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric     /// Array must be initialized with an initializer list or a
10070b57cec5SDimitry Andric     /// string literal.
10080b57cec5SDimitry Andric     FK_ArrayNeedsInitListOrStringLiteral,
10090b57cec5SDimitry Andric 
10100b57cec5SDimitry Andric     /// Array must be initialized with an initializer list or a
10110b57cec5SDimitry Andric     /// wide string literal.
10120b57cec5SDimitry Andric     FK_ArrayNeedsInitListOrWideStringLiteral,
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric     /// Initializing a wide char array with narrow string literal.
10150b57cec5SDimitry Andric     FK_NarrowStringIntoWideCharArray,
10160b57cec5SDimitry Andric 
10170b57cec5SDimitry Andric     /// Initializing char array with wide string literal.
10180b57cec5SDimitry Andric     FK_WideStringIntoCharArray,
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric     /// Initializing wide char array with incompatible wide string
10210b57cec5SDimitry Andric     /// literal.
10220b57cec5SDimitry Andric     FK_IncompatWideStringIntoWideChar,
10230b57cec5SDimitry Andric 
10240b57cec5SDimitry Andric     /// Initializing char8_t array with plain string literal.
10250b57cec5SDimitry Andric     FK_PlainStringIntoUTF8Char,
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric     /// Initializing char array with UTF-8 string literal.
10280b57cec5SDimitry Andric     FK_UTF8StringIntoPlainChar,
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric     /// Array type mismatch.
10310b57cec5SDimitry Andric     FK_ArrayTypeMismatch,
10320b57cec5SDimitry Andric 
10330b57cec5SDimitry Andric     /// Non-constant array initializer
10340b57cec5SDimitry Andric     FK_NonConstantArrayInit,
10350b57cec5SDimitry Andric 
10360b57cec5SDimitry Andric     /// Cannot resolve the address of an overloaded function.
10370b57cec5SDimitry Andric     FK_AddressOfOverloadFailed,
10380b57cec5SDimitry Andric 
10390b57cec5SDimitry Andric     /// Overloading due to reference initialization failed.
10400b57cec5SDimitry Andric     FK_ReferenceInitOverloadFailed,
10410b57cec5SDimitry Andric 
10420b57cec5SDimitry Andric     /// Non-const lvalue reference binding to a temporary.
10430b57cec5SDimitry Andric     FK_NonConstLValueReferenceBindingToTemporary,
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric     /// Non-const lvalue reference binding to a bit-field.
10460b57cec5SDimitry Andric     FK_NonConstLValueReferenceBindingToBitfield,
10470b57cec5SDimitry Andric 
10480b57cec5SDimitry Andric     /// Non-const lvalue reference binding to a vector element.
10490b57cec5SDimitry Andric     FK_NonConstLValueReferenceBindingToVectorElement,
10500b57cec5SDimitry Andric 
10515ffd83dbSDimitry Andric     /// Non-const lvalue reference binding to a matrix element.
10525ffd83dbSDimitry Andric     FK_NonConstLValueReferenceBindingToMatrixElement,
10535ffd83dbSDimitry Andric 
10540b57cec5SDimitry Andric     /// Non-const lvalue reference binding to an lvalue of unrelated
10550b57cec5SDimitry Andric     /// type.
10560b57cec5SDimitry Andric     FK_NonConstLValueReferenceBindingToUnrelated,
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric     /// Rvalue reference binding to an lvalue.
10590b57cec5SDimitry Andric     FK_RValueReferenceBindingToLValue,
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric     /// Reference binding drops qualifiers.
10620b57cec5SDimitry Andric     FK_ReferenceInitDropsQualifiers,
10630b57cec5SDimitry Andric 
10640b57cec5SDimitry Andric     /// Reference with mismatching address space binding to temporary.
10650b57cec5SDimitry Andric     FK_ReferenceAddrspaceMismatchTemporary,
10660b57cec5SDimitry Andric 
10670b57cec5SDimitry Andric     /// Reference binding failed.
10680b57cec5SDimitry Andric     FK_ReferenceInitFailed,
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric     /// Implicit conversion failed.
10710b57cec5SDimitry Andric     FK_ConversionFailed,
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric     /// Implicit conversion failed.
10740b57cec5SDimitry Andric     FK_ConversionFromPropertyFailed,
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric     /// Too many initializers for scalar
10770b57cec5SDimitry Andric     FK_TooManyInitsForScalar,
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric     /// Scalar initialized from a parenthesized initializer list.
10800b57cec5SDimitry Andric     FK_ParenthesizedListInitForScalar,
10810b57cec5SDimitry Andric 
10820b57cec5SDimitry Andric     /// Reference initialization from an initializer list
10830b57cec5SDimitry Andric     FK_ReferenceBindingToInitList,
10840b57cec5SDimitry Andric 
10850b57cec5SDimitry Andric     /// Initialization of some unused destination type with an
10860b57cec5SDimitry Andric     /// initializer list.
10870b57cec5SDimitry Andric     FK_InitListBadDestinationType,
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric     /// Overloading for a user-defined conversion failed.
10900b57cec5SDimitry Andric     FK_UserConversionOverloadFailed,
10910b57cec5SDimitry Andric 
10920b57cec5SDimitry Andric     /// Overloading for initialization by constructor failed.
10930b57cec5SDimitry Andric     FK_ConstructorOverloadFailed,
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric     /// Overloading for list-initialization by constructor failed.
10960b57cec5SDimitry Andric     FK_ListConstructorOverloadFailed,
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric     /// Default-initialization of a 'const' object.
10990b57cec5SDimitry Andric     FK_DefaultInitOfConst,
11000b57cec5SDimitry Andric 
11010b57cec5SDimitry Andric     /// Initialization of an incomplete type.
11020b57cec5SDimitry Andric     FK_Incomplete,
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric     /// Variable-length array must not have an initializer.
11050b57cec5SDimitry Andric     FK_VariableLengthArrayHasInitializer,
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric     /// List initialization failed at some point.
11080b57cec5SDimitry Andric     FK_ListInitializationFailed,
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric     /// Initializer has a placeholder type which cannot be
11110b57cec5SDimitry Andric     /// resolved by initialization.
11120b57cec5SDimitry Andric     FK_PlaceholderType,
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric     /// Trying to take the address of a function that doesn't support
11150b57cec5SDimitry Andric     /// having its address taken.
11160b57cec5SDimitry Andric     FK_AddressOfUnaddressableFunction,
11170b57cec5SDimitry Andric 
11180b57cec5SDimitry Andric     /// List-copy-initialization chose an explicit constructor.
11190b57cec5SDimitry Andric     FK_ExplicitConstructor,
1120bdd1243dSDimitry Andric 
1121bdd1243dSDimitry Andric     /// Parenthesized list initialization failed at some point.
1122bdd1243dSDimitry Andric     /// This is a C++20 feature.
1123bdd1243dSDimitry Andric     FK_ParenthesizedListInitFailed,
112406c3fb27SDimitry Andric 
112506c3fb27SDimitry Andric     // A designated initializer was provided for a non-aggregate type.
112606c3fb27SDimitry Andric     FK_DesignatedInitForNonAggregate,
11270b57cec5SDimitry Andric   };
11280b57cec5SDimitry Andric 
11290b57cec5SDimitry Andric private:
11300b57cec5SDimitry Andric   /// The reason why initialization failed.
11310b57cec5SDimitry Andric   FailureKind Failure;
11320b57cec5SDimitry Andric 
11330b57cec5SDimitry Andric   /// The failed result of overload resolution.
11340b57cec5SDimitry Andric   OverloadingResult FailedOverloadResult;
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   /// The candidate set created when initialization failed.
11370b57cec5SDimitry Andric   OverloadCandidateSet FailedCandidateSet;
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric   /// The incomplete type that caused a failure.
11400b57cec5SDimitry Andric   QualType FailedIncompleteType;
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric   /// The fixit that needs to be applied to make this initialization
11430b57cec5SDimitry Andric   /// succeed.
11440b57cec5SDimitry Andric   std::string ZeroInitializationFixit;
11450b57cec5SDimitry Andric   SourceLocation ZeroInitializationFixitLoc;
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric public:
11480b57cec5SDimitry Andric   /// Call for initializations are invalid but that would be valid
11490b57cec5SDimitry Andric   /// zero initialzations if Fixit was applied.
SetZeroInitializationFixit(const std::string & Fixit,SourceLocation L)11500b57cec5SDimitry Andric   void SetZeroInitializationFixit(const std::string& Fixit, SourceLocation L) {
11510b57cec5SDimitry Andric     ZeroInitializationFixit = Fixit;
11520b57cec5SDimitry Andric     ZeroInitializationFixitLoc = L;
11530b57cec5SDimitry Andric   }
11540b57cec5SDimitry Andric 
11550b57cec5SDimitry Andric private:
11560b57cec5SDimitry Andric   /// Prints a follow-up note that highlights the location of
11570b57cec5SDimitry Andric   /// the initialized entity, if it's remote.
11580b57cec5SDimitry Andric   void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
11590b57cec5SDimitry Andric 
11600b57cec5SDimitry Andric public:
11610b57cec5SDimitry Andric   /// Try to perform initialization of the given entity, creating a
11620b57cec5SDimitry Andric   /// record of the steps required to perform the initialization.
11630b57cec5SDimitry Andric   ///
11640b57cec5SDimitry Andric   /// The generated initialization sequence will either contain enough
11650b57cec5SDimitry Andric   /// information to diagnose
11660b57cec5SDimitry Andric   ///
11670b57cec5SDimitry Andric   /// \param S the semantic analysis object.
11680b57cec5SDimitry Andric   ///
11690b57cec5SDimitry Andric   /// \param Entity the entity being initialized.
11700b57cec5SDimitry Andric   ///
11710b57cec5SDimitry Andric   /// \param Kind the kind of initialization being performed.
11720b57cec5SDimitry Andric   ///
11730b57cec5SDimitry Andric   /// \param Args the argument(s) provided for initialization.
11740b57cec5SDimitry Andric   ///
11750b57cec5SDimitry Andric   /// \param TopLevelOfInitList true if we are initializing from an expression
11760b57cec5SDimitry Andric   ///        at the top level inside an initializer list. This disallows
11770b57cec5SDimitry Andric   ///        narrowing conversions in C++11 onwards.
11780b57cec5SDimitry Andric   /// \param TreatUnavailableAsInvalid true if we want to treat unavailable
11790b57cec5SDimitry Andric   ///        as invalid.
11800b57cec5SDimitry Andric   InitializationSequence(Sema &S,
11810b57cec5SDimitry Andric                          const InitializedEntity &Entity,
11820b57cec5SDimitry Andric                          const InitializationKind &Kind,
11830b57cec5SDimitry Andric                          MultiExprArg Args,
11840b57cec5SDimitry Andric                          bool TopLevelOfInitList = false,
11850b57cec5SDimitry Andric                          bool TreatUnavailableAsInvalid = true);
11860b57cec5SDimitry Andric   void InitializeFrom(Sema &S, const InitializedEntity &Entity,
11870b57cec5SDimitry Andric                       const InitializationKind &Kind, MultiExprArg Args,
11880b57cec5SDimitry Andric                       bool TopLevelOfInitList, bool TreatUnavailableAsInvalid);
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric   ~InitializationSequence();
11910b57cec5SDimitry Andric 
11920b57cec5SDimitry Andric   /// Perform the actual initialization of the given entity based on
11930b57cec5SDimitry Andric   /// the computed initialization sequence.
11940b57cec5SDimitry Andric   ///
11950b57cec5SDimitry Andric   /// \param S the semantic analysis object.
11960b57cec5SDimitry Andric   ///
11970b57cec5SDimitry Andric   /// \param Entity the entity being initialized.
11980b57cec5SDimitry Andric   ///
11990b57cec5SDimitry Andric   /// \param Kind the kind of initialization being performed.
12000b57cec5SDimitry Andric   ///
12010b57cec5SDimitry Andric   /// \param Args the argument(s) provided for initialization, ownership of
12020b57cec5SDimitry Andric   /// which is transferred into the routine.
12030b57cec5SDimitry Andric   ///
12040b57cec5SDimitry Andric   /// \param ResultType if non-NULL, will be set to the type of the
12050b57cec5SDimitry Andric   /// initialized object, which is the type of the declaration in most
12060b57cec5SDimitry Andric   /// cases. However, when the initialized object is a variable of
12070b57cec5SDimitry Andric   /// incomplete array type and the initializer is an initializer
12080b57cec5SDimitry Andric   /// list, this type will be set to the completed array type.
12090b57cec5SDimitry Andric   ///
12100b57cec5SDimitry Andric   /// \returns an expression that performs the actual object initialization, if
12110b57cec5SDimitry Andric   /// the initialization is well-formed. Otherwise, emits diagnostics
12120b57cec5SDimitry Andric   /// and returns an invalid expression.
12130b57cec5SDimitry Andric   ExprResult Perform(Sema &S,
12140b57cec5SDimitry Andric                      const InitializedEntity &Entity,
12150b57cec5SDimitry Andric                      const InitializationKind &Kind,
12160b57cec5SDimitry Andric                      MultiExprArg Args,
12170b57cec5SDimitry Andric                      QualType *ResultType = nullptr);
12180b57cec5SDimitry Andric 
12190b57cec5SDimitry Andric   /// Diagnose an potentially-invalid initialization sequence.
12200b57cec5SDimitry Andric   ///
12210b57cec5SDimitry Andric   /// \returns true if the initialization sequence was ill-formed,
12220b57cec5SDimitry Andric   /// false otherwise.
12230b57cec5SDimitry Andric   bool Diagnose(Sema &S,
12240b57cec5SDimitry Andric                 const InitializedEntity &Entity,
12250b57cec5SDimitry Andric                 const InitializationKind &Kind,
12260b57cec5SDimitry Andric                 ArrayRef<Expr *> Args);
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric   /// Determine the kind of initialization sequence computed.
getKind()12290b57cec5SDimitry Andric   enum SequenceKind getKind() const { return SequenceKind; }
12300b57cec5SDimitry Andric 
12310b57cec5SDimitry Andric   /// Set the kind of sequence computed.
setSequenceKind(enum SequenceKind SK)12320b57cec5SDimitry Andric   void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric   /// Determine whether the initialization sequence is valid.
12350b57cec5SDimitry Andric   explicit operator bool() const { return !Failed(); }
12360b57cec5SDimitry Andric 
12370b57cec5SDimitry Andric   /// Determine whether the initialization sequence is invalid.
Failed()12380b57cec5SDimitry Andric   bool Failed() const { return SequenceKind == FailedSequence; }
12390b57cec5SDimitry Andric 
12400b57cec5SDimitry Andric   using step_iterator = SmallVectorImpl<Step>::const_iterator;
12410b57cec5SDimitry Andric 
step_begin()12420b57cec5SDimitry Andric   step_iterator step_begin() const { return Steps.begin(); }
step_end()12430b57cec5SDimitry Andric   step_iterator step_end()   const { return Steps.end(); }
12440b57cec5SDimitry Andric 
12450b57cec5SDimitry Andric   using step_range = llvm::iterator_range<step_iterator>;
12460b57cec5SDimitry Andric 
steps()12470b57cec5SDimitry Andric   step_range steps() const { return {step_begin(), step_end()}; }
12480b57cec5SDimitry Andric 
12490b57cec5SDimitry Andric   /// Determine whether this initialization is a direct reference
12500b57cec5SDimitry Andric   /// binding (C++ [dcl.init.ref]).
12510b57cec5SDimitry Andric   bool isDirectReferenceBinding() const;
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric   /// Determine whether this initialization failed due to an ambiguity.
12540b57cec5SDimitry Andric   bool isAmbiguous() const;
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric   /// Determine whether this initialization is direct call to a
12570b57cec5SDimitry Andric   /// constructor.
12580b57cec5SDimitry Andric   bool isConstructorInitialization() const;
12590b57cec5SDimitry Andric 
12600b57cec5SDimitry Andric   /// Add a new step in the initialization that resolves the address
12610b57cec5SDimitry Andric   /// of an overloaded function to a specific function declaration.
12620b57cec5SDimitry Andric   ///
12630b57cec5SDimitry Andric   /// \param Function the function to which the overloaded function reference
12640b57cec5SDimitry Andric   /// resolves.
12650b57cec5SDimitry Andric   void AddAddressOverloadResolutionStep(FunctionDecl *Function,
12660b57cec5SDimitry Andric                                         DeclAccessPair Found,
12670b57cec5SDimitry Andric                                         bool HadMultipleCandidates);
12680b57cec5SDimitry Andric 
12690b57cec5SDimitry Andric   /// Add a new step in the initialization that performs a derived-to-
12700b57cec5SDimitry Andric   /// base cast.
12710b57cec5SDimitry Andric   ///
12720b57cec5SDimitry Andric   /// \param BaseType the base type to which we will be casting.
12730b57cec5SDimitry Andric   ///
12740b57cec5SDimitry Andric   /// \param Category Indicates whether the result will be treated as an
12750b57cec5SDimitry Andric   /// rvalue, an xvalue, or an lvalue.
12760b57cec5SDimitry Andric   void AddDerivedToBaseCastStep(QualType BaseType,
12770b57cec5SDimitry Andric                                 ExprValueKind Category);
12780b57cec5SDimitry Andric 
12790b57cec5SDimitry Andric   /// Add a new step binding a reference to an object.
12800b57cec5SDimitry Andric   ///
12810b57cec5SDimitry Andric   /// \param BindingTemporary True if we are binding a reference to a temporary
12820b57cec5SDimitry Andric   /// object (thereby extending its lifetime); false if we are binding to an
12830b57cec5SDimitry Andric   /// lvalue or an lvalue treated as an rvalue.
12840b57cec5SDimitry Andric   void AddReferenceBindingStep(QualType T, bool BindingTemporary);
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric   /// Add a new step that makes an extraneous copy of the input
12870b57cec5SDimitry Andric   /// to a temporary of the same class type.
12880b57cec5SDimitry Andric   ///
12890b57cec5SDimitry Andric   /// This extraneous copy only occurs during reference binding in
12900b57cec5SDimitry Andric   /// C++98/03, where we are permitted (but not required) to introduce
12910b57cec5SDimitry Andric   /// an extra copy. At a bare minimum, we must check that we could
12920b57cec5SDimitry Andric   /// call the copy constructor, and produce a diagnostic if the copy
12930b57cec5SDimitry Andric   /// constructor is inaccessible or no copy constructor matches.
12940b57cec5SDimitry Andric   //
12950b57cec5SDimitry Andric   /// \param T The type of the temporary being created.
12960b57cec5SDimitry Andric   void AddExtraneousCopyToTemporary(QualType T);
12970b57cec5SDimitry Andric 
12980b57cec5SDimitry Andric   /// Add a new step that makes a copy of the input to an object of
12990b57cec5SDimitry Andric   /// the given type, as the final step in class copy-initialization.
13000b57cec5SDimitry Andric   void AddFinalCopy(QualType T);
13010b57cec5SDimitry Andric 
13020b57cec5SDimitry Andric   /// Add a new step invoking a conversion function, which is either
13030b57cec5SDimitry Andric   /// a constructor or a conversion function.
13040b57cec5SDimitry Andric   void AddUserConversionStep(FunctionDecl *Function,
13050b57cec5SDimitry Andric                              DeclAccessPair FoundDecl,
13060b57cec5SDimitry Andric                              QualType T,
13070b57cec5SDimitry Andric                              bool HadMultipleCandidates);
13080b57cec5SDimitry Andric 
13090b57cec5SDimitry Andric   /// Add a new step that performs a qualification conversion to the
13100b57cec5SDimitry Andric   /// given type.
13110b57cec5SDimitry Andric   void AddQualificationConversionStep(QualType Ty,
13120b57cec5SDimitry Andric                                      ExprValueKind Category);
13130b57cec5SDimitry Andric 
1314e8d8bef9SDimitry Andric   /// Add a new step that performs a function reference conversion to the
1315e8d8bef9SDimitry Andric   /// given type.
1316e8d8bef9SDimitry Andric   void AddFunctionReferenceConversionStep(QualType Ty);
1317e8d8bef9SDimitry Andric 
13180b57cec5SDimitry Andric   /// Add a new step that performs conversion from non-atomic to atomic
13190b57cec5SDimitry Andric   /// type.
13200b57cec5SDimitry Andric   void AddAtomicConversionStep(QualType Ty);
13210b57cec5SDimitry Andric 
13220b57cec5SDimitry Andric   /// Add a new step that applies an implicit conversion sequence.
13230b57cec5SDimitry Andric   void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
13240b57cec5SDimitry Andric                                  QualType T, bool TopLevelOfInitList = false);
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric   /// Add a list-initialization step.
13270b57cec5SDimitry Andric   void AddListInitializationStep(QualType T);
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   /// Add a constructor-initialization step.
13300b57cec5SDimitry Andric   ///
13310b57cec5SDimitry Andric   /// \param FromInitList The constructor call is syntactically an initializer
13320b57cec5SDimitry Andric   /// list.
13330b57cec5SDimitry Andric   /// \param AsInitList The constructor is called as an init list constructor.
13340b57cec5SDimitry Andric   void AddConstructorInitializationStep(DeclAccessPair FoundDecl,
13350b57cec5SDimitry Andric                                         CXXConstructorDecl *Constructor,
13360b57cec5SDimitry Andric                                         QualType T,
13370b57cec5SDimitry Andric                                         bool HadMultipleCandidates,
13380b57cec5SDimitry Andric                                         bool FromInitList, bool AsInitList);
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric   /// Add a zero-initialization step.
13410b57cec5SDimitry Andric   void AddZeroInitializationStep(QualType T);
13420b57cec5SDimitry Andric 
13430b57cec5SDimitry Andric   /// Add a C assignment step.
13440b57cec5SDimitry Andric   //
13450b57cec5SDimitry Andric   // FIXME: It isn't clear whether this should ever be needed;
13460b57cec5SDimitry Andric   // ideally, we would handle everything needed in C in the common
13470b57cec5SDimitry Andric   // path. However, that isn't the case yet.
13480b57cec5SDimitry Andric   void AddCAssignmentStep(QualType T);
13490b57cec5SDimitry Andric 
13500b57cec5SDimitry Andric   /// Add a string init step.
13510b57cec5SDimitry Andric   void AddStringInitStep(QualType T);
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric   /// Add an Objective-C object conversion step, which is
13540b57cec5SDimitry Andric   /// always a no-op.
13550b57cec5SDimitry Andric   void AddObjCObjectConversionStep(QualType T);
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric   /// Add an array initialization loop step.
13580b57cec5SDimitry Andric   void AddArrayInitLoopStep(QualType T, QualType EltTy);
13590b57cec5SDimitry Andric 
13600b57cec5SDimitry Andric   /// Add an array initialization step.
13610b57cec5SDimitry Andric   void AddArrayInitStep(QualType T, bool IsGNUExtension);
13620b57cec5SDimitry Andric 
13630b57cec5SDimitry Andric   /// Add a parenthesized array initialization step.
13640b57cec5SDimitry Andric   void AddParenthesizedArrayInitStep(QualType T);
13650b57cec5SDimitry Andric 
13660b57cec5SDimitry Andric   /// Add a step to pass an object by indirect copy-restore.
13670b57cec5SDimitry Andric   void AddPassByIndirectCopyRestoreStep(QualType T, bool shouldCopy);
13680b57cec5SDimitry Andric 
13690b57cec5SDimitry Andric   /// Add a step to "produce" an Objective-C object (by
13700b57cec5SDimitry Andric   /// retaining it).
13710b57cec5SDimitry Andric   void AddProduceObjCObjectStep(QualType T);
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric   /// Add a step to construct a std::initializer_list object from an
13740b57cec5SDimitry Andric   /// initializer list.
13750b57cec5SDimitry Andric   void AddStdInitializerListConstructionStep(QualType T);
13760b57cec5SDimitry Andric 
13770b57cec5SDimitry Andric   /// Add a step to initialize an OpenCL sampler from an integer
13780b57cec5SDimitry Andric   /// constant.
13790b57cec5SDimitry Andric   void AddOCLSamplerInitStep(QualType T);
13800b57cec5SDimitry Andric 
13810b57cec5SDimitry Andric   /// Add a step to initialzie an OpenCL opaque type (event_t, queue_t, etc.)
13820b57cec5SDimitry Andric   /// from a zero constant.
13830b57cec5SDimitry Andric   void AddOCLZeroOpaqueTypeStep(QualType T);
13840b57cec5SDimitry Andric 
1385bdd1243dSDimitry Andric   void AddParenthesizedListInitStep(QualType T);
1386bdd1243dSDimitry Andric 
13870b57cec5SDimitry Andric   /// Add steps to unwrap a initializer list for a reference around a
13880b57cec5SDimitry Andric   /// single element and rewrap it at the end.
13890b57cec5SDimitry Andric   void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
13900b57cec5SDimitry Andric 
13910b57cec5SDimitry Andric   /// Note that this initialization sequence failed.
SetFailed(FailureKind Failure)13920b57cec5SDimitry Andric   void SetFailed(FailureKind Failure) {
13930b57cec5SDimitry Andric     SequenceKind = FailedSequence;
13940b57cec5SDimitry Andric     this->Failure = Failure;
13950b57cec5SDimitry Andric     assert((Failure != FK_Incomplete || !FailedIncompleteType.isNull()) &&
13960b57cec5SDimitry Andric            "Incomplete type failure requires a type!");
13970b57cec5SDimitry Andric   }
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric   /// Note that this initialization sequence failed due to failed
14000b57cec5SDimitry Andric   /// overload resolution.
14010b57cec5SDimitry Andric   void SetOverloadFailure(FailureKind Failure, OverloadingResult Result);
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric   /// Retrieve a reference to the candidate set when overload
14040b57cec5SDimitry Andric   /// resolution fails.
getFailedCandidateSet()14050b57cec5SDimitry Andric   OverloadCandidateSet &getFailedCandidateSet() {
14060b57cec5SDimitry Andric     return FailedCandidateSet;
14070b57cec5SDimitry Andric   }
14080b57cec5SDimitry Andric 
14090b57cec5SDimitry Andric   /// Get the overloading result, for when the initialization
14100b57cec5SDimitry Andric   /// sequence failed due to a bad overload.
getFailedOverloadResult()14110b57cec5SDimitry Andric   OverloadingResult getFailedOverloadResult() const {
14120b57cec5SDimitry Andric     return FailedOverloadResult;
14130b57cec5SDimitry Andric   }
14140b57cec5SDimitry Andric 
14150b57cec5SDimitry Andric   /// Note that this initialization sequence failed due to an
14160b57cec5SDimitry Andric   /// incomplete type.
setIncompleteTypeFailure(QualType IncompleteType)14170b57cec5SDimitry Andric   void setIncompleteTypeFailure(QualType IncompleteType) {
14180b57cec5SDimitry Andric     FailedIncompleteType = IncompleteType;
14190b57cec5SDimitry Andric     SetFailed(FK_Incomplete);
14200b57cec5SDimitry Andric   }
14210b57cec5SDimitry Andric 
14220b57cec5SDimitry Andric   /// Determine why initialization failed.
getFailureKind()14230b57cec5SDimitry Andric   FailureKind getFailureKind() const {
14240b57cec5SDimitry Andric     assert(Failed() && "Not an initialization failure!");
14250b57cec5SDimitry Andric     return Failure;
14260b57cec5SDimitry Andric   }
14270b57cec5SDimitry Andric 
14280b57cec5SDimitry Andric   /// Dump a representation of this initialization sequence to
14290b57cec5SDimitry Andric   /// the given stream, for debugging purposes.
14300b57cec5SDimitry Andric   void dump(raw_ostream &OS) const;
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric   /// Dump a representation of this initialization sequence to
14330b57cec5SDimitry Andric   /// standard error, for debugging purposes.
14340b57cec5SDimitry Andric   void dump() const;
14350b57cec5SDimitry Andric };
14360b57cec5SDimitry Andric 
14370b57cec5SDimitry Andric } // namespace clang
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric #endif // LLVM_CLANG_SEMA_INITIALIZATION_H
1440