diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 28 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 9 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 19 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 112 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 147 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.h | 19 |
7 files changed, 228 insertions, 110 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 32a57269d6b..0472d50ea57 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -3676,8 +3676,8 @@ public: /// type checking declaration initializers (C99 6.7.8) bool CheckInitializerTypes(Expr *&simpleInit_or_initList, QualType &declType, - SourceLocation InitLoc,DeclarationName InitEntity, - bool DirectInit); + const InitializedEntity &Entity, + const InitializationKind &Kind); bool CheckInitList(InitListExpr *&InitList, QualType &DeclType); bool CheckForConstantInitializer(Expr *e, QualType t); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6c5c2595aef..7a27e1185e3 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3504,6 +3504,18 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { Expr *Init = init.takeAs<Expr>(); assert(Init && "missing initializer"); + // Capture the variable that is being initialized and the style of + // initialization. + InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl); + + // FIXME: Poor source location information. + InitializationKind Kind + = DirectInit? InitializationKind::CreateDirect(VDecl->getLocation(), + Init->getLocStart(), + Init->getLocEnd()) + : InitializationKind::CreateCopy(VDecl->getLocation(), + Init->getLocStart()); + // Get the decls type and save a reference for later, since // CheckInitializerTypes may change it. QualType DclT = VDecl->getType(), SavT = DclT; @@ -3514,16 +3526,6 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { } else if (!VDecl->isInvalidDecl()) { if (VDecl->getType()->isReferenceType() || isa<InitListExpr>(Init)) { - InitializedEntity Entity - = InitializedEntity::InitializeVariable(VDecl); - - // FIXME: Poor source location information. - InitializationKind Kind - = DirectInit? InitializationKind::CreateDirect(VDecl->getLocation(), - SourceLocation(), - SourceLocation()) - : InitializationKind::CreateCopy(VDecl->getLocation(), - SourceLocation()); InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1); if (InitSeq) { OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, @@ -3540,8 +3542,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { VDecl->setInvalidDecl(); return; } - } else if (CheckInitializerTypes(Init, DclT, VDecl->getLocation(), - VDecl->getDeclName(), DirectInit)) + } else if (CheckInitializerTypes(Init, DclT, Entity, Kind)) VDecl->setInvalidDecl(); // C++ 3.6.2p2, allow dynamic initialization of static initializers. @@ -3602,8 +3603,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { if (VDecl->getStorageClass() == VarDecl::Extern) Diag(VDecl->getLocation(), diag::warn_extern_init); if (!VDecl->isInvalidDecl()) - if (CheckInitializerTypes(Init, DclT, VDecl->getLocation(), - VDecl->getDeclName(), DirectInit)) + if (CheckInitializerTypes(Init, DclT, Entity, Kind)) VDecl->setInvalidDecl(); // C++ 3.6.2p2, allow dynamic initialization of static initializers. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 80d67efae9b..a70841f536d 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -125,8 +125,10 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg, // the same semantic constraints as the initializer expression in // a declaration of a variable of the parameter type, using the // copy-initialization semantics (8.5). - if (CheckInitializerTypes(Arg, ParamType, EqualLoc, - Param->getDeclName(), /*DirectInit=*/false)) + InitializedEntity Entity = InitializedEntity::InitializeParameter(Param); + InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(), + EqualLoc); + if (CheckInitializerTypes(Arg, ParamType, Entity, Kind)) return true; Arg = MaybeCreateCXXExprWithTemporaries(Arg); @@ -3775,7 +3777,8 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, Expr **Exprs = (Expr **)ExprArgs.release(); MarkDeclarationReferenced(ConstructLoc, Constructor); - return Owned(CXXConstructExpr::Create(Context, DeclInitType, Constructor, + return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc, + Constructor, Elidable, Exprs, NumExprs)); } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 12c3a3a2b00..70646dd9ed4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "Sema.h" +#include "SemaInit.h" #include "Lookup.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" @@ -3531,8 +3532,12 @@ Action::OwningExprResult Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, SourceLocation RParenLoc, ExprArg InitExpr) { assert((Ty != 0) && "ActOnCompoundLiteral(): missing type"); - //FIXME: Preserve type source info. - QualType literalType = GetTypeFromParser(Ty); + + TypeSourceInfo *TInfo = 0; + QualType literalType = GetTypeFromParser(Ty, &TInfo); + if (!TInfo) + TInfo = Context.getTrivialTypeSourceInfo(literalType, LParenLoc); + // FIXME: put back this assert when initializers are worked out. //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression"); Expr *literalExpr = static_cast<Expr*>(InitExpr.get()); @@ -3548,8 +3553,12 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, literalExpr->getSourceRange().getEnd()))) return ExprError(); - if (CheckInitializerTypes(literalExpr, literalType, LParenLoc, - DeclarationName(), /*FIXME:DirectInit=*/false)) + InitializedEntity Entity + = InitializedEntity::InitializeTemporary(TInfo->getTypeLoc()); + InitializationKind Kind + = InitializationKind::CreateCast(SourceRange(LParenLoc, RParenLoc), + /*IsCStyleCast=*/true); + if (CheckInitializerTypes(literalExpr, literalType, Entity, Kind)) return ExprError(); bool isFileScope = getCurFunctionOrMethodDecl() == 0; @@ -3558,6 +3567,8 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, return ExprError(); } InitExpr.release(); + + // FIXME: Store the TInfo to preserve type information better. return Owned(new (Context) CompoundLiteralExpr(LParenLoc, literalType, literalExpr, isFileScope)); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index d119350a6f5..80b64306540 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -425,74 +425,70 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, bool Init = ConstructorLParen.isValid(); // --- Choosing a constructor --- - // C++ 5.3.4p15 - // 1) If T is a POD and there's no initializer (ConstructorLParen is invalid) - // the object is not initialized. If the object, or any part of it, is - // const-qualified, it's an error. - // 2) If T is a POD and there's an empty initializer, the object is value- - // initialized. - // 3) If T is a POD and there's one initializer argument, the object is copy- - // constructed. - // 4) If T is a POD and there's more initializer arguments, it's an error. - // 5) If T is not a POD, the initializer arguments are used as constructor - // arguments. - // - // Or by the C++0x formulation: - // 1) If there's no initializer, the object is default-initialized according - // to C++0x rules. - // 2) Otherwise, the object is direct-initialized. CXXConstructorDecl *Constructor = 0; Expr **ConsArgs = (Expr**)ConstructorArgs.get(); - const RecordType *RT; unsigned NumConsArgs = ConstructorArgs.size(); ASTOwningVector<&ActionBase::DeleteExpr> ConvertedConstructorArgs(*this); - if (AllocType->isDependentType() || - Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) { - // Skip all the checks. - } else if ((RT = AllocType->getAs<RecordType>()) && - !AllocType->isAggregateType()) { - InitializationKind InitKind = InitializationKind::CreateDefault(TypeLoc); - if (NumConsArgs > 0) - InitKind = InitializationKind::CreateDirect(TypeLoc, - PlacementLParen, - PlacementRParen); - Constructor = PerformInitializationByConstructor( - AllocType, move(ConstructorArgs), - TypeLoc, - SourceRange(TypeLoc, ConstructorRParen), - RT->getDecl()->getDeclName(), - InitKind, - ConvertedConstructorArgs); - if (!Constructor) + if (!AllocType->isDependentType() && + !Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) { + // C++0x [expr.new]p15: + // A new-expression that creates an object of type T initializes that + // object as follows: + InitializationKind Kind + // - If the new-initializer is omitted, the object is default- + // initialized (8.5); if no initialization is performed, + // the object has indeterminate value + = !Init? InitializationKind::CreateDefault(TypeLoc) + // - Otherwise, the new-initializer is interpreted according to the + // initialization rules of 8.5 for direct-initialization. + : InitializationKind::CreateDirect(TypeLoc, + ConstructorLParen, + ConstructorRParen); + + // FIXME: We shouldn't have to fake this. + TypeSourceInfo *TInfo + = Context.getTrivialTypeSourceInfo(AllocType, TypeLoc); + InitializedEntity Entity + = InitializedEntity::InitializeTemporary(TInfo->getTypeLoc()); + InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs); + + if (!InitSeq) { + InitSeq.Diagnose(*this, Entity, Kind, ConsArgs, NumConsArgs); return ExprError(); + } - // Take the converted constructor arguments and use them for the new - // expression. - NumConsArgs = ConvertedConstructorArgs.size(); - ConsArgs = (Expr **)ConvertedConstructorArgs.take(); - } else { - if (!Init) { - // FIXME: Check that no subpart is const. - if (AllocType.isConstQualified()) - return ExprError(Diag(StartLoc, diag::err_new_uninitialized_const) - << TypeRange); - } else if (NumConsArgs == 0) { - // Object is value-initialized. Do nothing. - } else if (NumConsArgs == 1) { - // Object is direct-initialized. - // FIXME: What DeclarationName do we pass in here? - if (CheckInitializerTypes(ConsArgs[0], AllocType, StartLoc, - DeclarationName() /*AllocType.getAsString()*/, - /*DirectInit=*/true)) - return ExprError(); + OwningExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, + move(ConstructorArgs)); + if (FullInit.isInvalid()) + return ExprError(); + + // FullInit is our initializer; walk through it to determine if it's a + // constructor call, which CXXNewExpr handles directly. + if (Expr *FullInitExpr = (Expr *)FullInit.get()) { + if (CXXBindTemporaryExpr *Binder + = dyn_cast<CXXBindTemporaryExpr>(FullInitExpr)) + FullInitExpr = Binder->getSubExpr(); + if (CXXConstructExpr *Construct + = dyn_cast<CXXConstructExpr>(FullInitExpr)) { + Constructor = Construct->getConstructor(); + for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(), + AEnd = Construct->arg_end(); + A != AEnd; ++A) + ConvertedConstructorArgs.push_back(A->Retain()); + } else { + // Take the converted initializer. + ConvertedConstructorArgs.push_back(FullInit.release()); + } } else { - return ExprError(Diag(StartLoc, - diag::err_builtin_direct_init_more_than_one_arg) - << SourceRange(ConstructorLParen, ConstructorRParen)); + // No initialization required. } + + // Take the converted arguments and use them for the new expression. + NumConsArgs = ConvertedConstructorArgs.size(); + ConsArgs = (Expr **)ConvertedConstructorArgs.take(); } - + // FIXME: Also check that the destructor is accessible. (C++ 5.3.4p16) PlacementArgs.release(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 45184650eb7..a732b07b9dd 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -135,8 +135,12 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, Sema &S) { } bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType, - SourceLocation InitLoc, - DeclarationName InitEntity, bool DirectInit) { + const InitializedEntity &Entity, + const InitializationKind &Kind) { + SourceLocation InitLoc = Kind.getLocation(); + DeclarationName InitEntity = Entity.getName(); + bool DirectInit = (Kind.getKind() == InitializationKind::IK_Direct); + if (DeclType->isDependentType() || Init->isTypeDependent() || Init->isValueDependent()) { // We have either a dependent type or a type- or value-dependent @@ -1954,6 +1958,24 @@ InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context, return Result; } +DeclarationName InitializedEntity::getName() const { + switch (getKind()) { + case EK_Variable: + case EK_Parameter: + case EK_Member: + return VariableOrMember->getDeclName(); + + case EK_Result: + case EK_Exception: + case EK_Temporary: + case EK_Base: + return DeclarationName(); + } + + // Silence GCC warning + return DeclarationName(); +} + //===----------------------------------------------------------------------===// // Initialization sequence //===----------------------------------------------------------------------===// @@ -2512,7 +2534,7 @@ static void TryConstructorInitialization(Sema &S, Constructor = cast<CXXConstructorDecl>(*Con); if (!Constructor->isInvalidDecl() && - Constructor->isConvertingConstructor(AllowExplicit)) { + (AllowExplicit || !Constructor->isExplicit())) { if (ConstructorTmpl) S.AddTemplateOverloadCandidate(ConstructorTmpl, /*ExplicitArgs*/ 0, Args, NumArgs, CandidateSet); @@ -2575,6 +2597,41 @@ static void TryValueInitialization(Sema &S, Sequence.setSequenceKind(InitializationSequence::ZeroInitialization); } +/// \brief Attempt default initialization (C++ [dcl.init]p6). +static void TryDefaultInitialization(Sema &S, + const InitializedEntity &Entity, + const InitializationKind &Kind, + InitializationSequence &Sequence) { + assert(Kind.getKind() == InitializationKind::IK_Default); + + // C++ [dcl.init]p6: + // To default-initialize an object of type T means: + // - if T is an array type, each element is default-initialized; + QualType DestType = Entity.getType().getType(); + while (const ArrayType *Array = S.Context.getAsArrayType(DestType)) + DestType = Array->getElementType(); + + // - if T is a (possibly cv-qualified) class type (Clause 9), the default + // constructor for T is called (and the initialization is ill-formed if + // T has no accessible default constructor); + if (DestType->isRecordType()) { + // FIXME: If a program calls for the default initialization of an object of + // a const-qualified type T, T shall be a class type with a user-provided + // default constructor. + return TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType, + Sequence); + } + + // - otherwise, no initialization is performed. + Sequence.setSequenceKind(InitializationSequence::NoInitialization); + + // If a program calls for the default initialization of an object of + // a const-qualified type T, T shall be a class type with a user-provided + // default constructor. + if (DestType.isConstQualified()) + Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst); +} + /// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]), /// which enumerates all conversion functions and performs overload resolution /// to select the best. @@ -2749,7 +2806,7 @@ InitializationSequence::InitializationSequence(Sema &S, QualType SourceType; Expr *Initializer = 0; - if (Kind.getKind() == InitializationKind::IK_Copy) { + if (NumArgs == 1) { Initializer = Args[0]; if (!isa<InitListExpr>(Initializer)) SourceType = Initializer->getType(); @@ -2785,11 +2842,18 @@ InitializationSequence::InitializationSequence(Sema &S, } // - If the initializer is (), the object is value-initialized. - if (Kind.getKind() == InitializationKind::IK_Value) { + if (Kind.getKind() == InitializationKind::IK_Value || + (Kind.getKind() == InitializationKind::IK_Direct && NumArgs == 0)) { TryValueInitialization(S, Entity, Kind, *this); return; } + // Handle default initialization. + if (Kind.getKind() == InitializationKind::IK_Default){ + TryDefaultInitialization(S, Entity, Kind, *this); + return; + } + // - Otherwise, if the destination type is an array, the program is // ill-formed. if (const ArrayType *AT = Context.getAsArrayType(DestType)) { @@ -2824,9 +2888,15 @@ InitializationSequence::InitializationSequence(Sema &S, return; } + if (NumArgs > 1) { + SetFailed(FK_TooManyInitsForScalar); + return; + } + assert(NumArgs == 1 && "Zero-argument case handled above"); + // - Otherwise, if the source type is a (possibly cv-qualified) class // type, conversion functions are considered. - if (SourceType->isRecordType()) { + if (!SourceType.isNull() && SourceType->isRecordType()) { TryUserDefinedConversion(S, Entity, Kind, Initializer, *this); return; } @@ -2836,6 +2906,7 @@ InitializationSequence::InitializationSequence(Sema &S, // conversions (Clause 4) will be used, if necessary, to convert the // initializer expression to the cv-unqualified version of the // destination type; no user-defined conversions are considered. + setSequenceKind(StandardConversion); TryImplicitConversion(S, Entity, Kind, Initializer, *this); } @@ -2909,23 +2980,41 @@ InitializationSequence::Perform(Sema &S, SourceLocation())); } + if (SequenceKind == NoInitialization) + return S.Owned((Expr *)0); + QualType DestType = Entity.getType().getType().getNonReferenceType(); if (ResultType) *ResultType = Entity.getType().getType(); - Sema::OwningExprResult CurInit(S); - // For copy initialization and any other initialization forms that - // only have a single initializer, we start with the (only) - // initializer we have. - // FIXME: DPG is not happy about this. There's confusion regarding whether - // we're supposed to start the conversion from the solitary initializer or - // from the set of arguments. - if (Kind.getKind() == InitializationKind::IK_Copy || - SequenceKind != ConstructorInitialization) { - assert(Args.size() == 1); - CurInit = Sema::OwningExprResult(S, Args.release()[0]); - if (CurInit.isInvalid()) - return S.ExprError(); + Sema::OwningExprResult CurInit = S.Owned((Expr *)0); + + assert(!Steps.empty() && "Cannot have an empty initialization sequence"); + + // For initialization steps that start with a single initializer, + // grab the only argument out the Args and place it into the "current" + // initializer. + switch (Steps.front().Kind) { + case SK_ResolveAddressOfOverloadedFunction: + case SK_CastDerivedToBaseRValue: + case SK_CastDerivedToBaseLValue: + case SK_BindReference: + case SK_BindReferenceToTemporary: + case SK_UserConversion: + case SK_QualificationConversionLValue: + case SK_QualificationConversionRValue: + case SK_ConversionSequence: + case SK_ListInitialization: + assert(Args.size() == 1); + CurInit = Sema::OwningExprResult(S, + ((Expr **)(Args.get()))[0]->Retain()); + if (CurInit.isInvalid()) + return S.ExprError(); + break; + + case SK_ConstructorInitialization: + case SK_ZeroInitialization: + break; } // Walk through the computed steps for the initialization sequence, @@ -2936,7 +3025,7 @@ InitializationSequence::Perform(Sema &S, return S.ExprError(); Expr *CurInitExpr = (Expr *)CurInit.get(); - QualType SourceType = CurInitExpr->getType(); + QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType(); switch (Step->Kind) { case SK_ResolveAddressOfOverloadedFunction: @@ -3100,7 +3189,6 @@ InitializationSequence::Perform(Sema &S, if (CurInit.isInvalid()) return S.ExprError(); - CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>()); break; } @@ -3228,12 +3316,16 @@ bool InitializationSequence::Diagnose(Sema &S, break; case FK_TooManyInitsForScalar: { - InitListExpr *InitList = cast<InitListExpr>(Args[0]); + SourceRange R; + + if (InitListExpr *InitList = dyn_cast<InitListExpr>(Args[0])) + R = SourceRange(InitList->getInit(1)->getLocStart(), + InitList->getLocEnd()); + else + R = SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd()); S.Diag(Kind.getLocation(), diag::err_excess_initializers) - << /*scalar=*/2 - << SourceRange(InitList->getInit(1)->getLocStart(), - InitList->getLocEnd()); + << /*scalar=*/2 << R; break; } @@ -3290,6 +3382,11 @@ bool InitializationSequence::Diagnose(Sema &S, } break; } + + case FK_DefaultInitOfConst: + S.Diag(Kind.getLocation(), diag::err_default_init_const) + << DestType; + break; } return true; diff --git a/clang/lib/Sema/SemaInit.h b/clang/lib/Sema/SemaInit.h index 2d4b01f26b0..c084025b817 100644 --- a/clang/lib/Sema/SemaInit.h +++ b/clang/lib/Sema/SemaInit.h @@ -137,8 +137,8 @@ public: } /// \brief Create the initialization entity for a temporary. - static InitializedEntity InitializeTemporary(EntityKind Kind, TypeLoc TL) { - return InitializedEntity(Kind, SourceLocation(), TL); + static InitializedEntity InitializeTemporary(TypeLoc TL) { + return InitializedEntity(EK_Temporary, SourceLocation(), TL); } /// \brief Create the initialization entity for a base class subobject. @@ -156,6 +156,9 @@ public: /// \brief Retrieve type being initialized. TypeLoc getType() const { return TL; } + /// \brief Retrieve the name of the entity being initialized. + DeclarationName getName() const; + /// \brief Determine the location of the 'return' keyword when initializing /// the result of a function call. SourceLocation getReturnLoc() const { @@ -319,7 +322,13 @@ public: ListInitialization, /// \brief Zero-initialization. - ZeroInitialization + ZeroInitialization, + + /// \brief No initialization required. + NoInitialization, + + /// \brief Standard conversion sequence. + StandardConversion }; /// \brief Describes the kind of a particular step in an initialization @@ -420,7 +429,9 @@ public: /// \brief Overloading for a user-defined conversion failed. FK_UserConversionOverloadFailed, /// \brief Overloaded for initialization by constructor failed. - FK_ConstructorOverloadFailed + FK_ConstructorOverloadFailed, + /// \brief Default-initialization of a 'const' object. + FK_DefaultInitOfConst }; private: |

