Sema &SemaRef;
bool hadError;
bool VerifyOnly; // no diagnostics, no structure building
+ bool TreatUnavailableAsInvalid; // Used only in VerifyOnly mode.
llvm::DenseMap<InitListExpr *, InitListExpr *> SyntacticToSemantic;
InitListExpr *FullyStructuredList;
static ExprResult PerformEmptyInit(Sema &SemaRef,
SourceLocation Loc,
const InitializedEntity &Entity,
- bool VerifyOnly);
+ bool VerifyOnly,
+ bool TreatUnavailableAsInvalid);
// Explanation on the "FillWithNoInit" mode:
//
public:
InitListChecker(Sema &S, const InitializedEntity &Entity,
- InitListExpr *IL, QualType &T, bool VerifyOnly);
+ InitListExpr *IL, QualType &T, bool VerifyOnly,
+ bool TreatUnavailableAsInvalid);
bool HadError() { return hadError; }
// @brief Retrieves the fully-structured initializer list used for
ExprResult InitListChecker::PerformEmptyInit(Sema &SemaRef,
SourceLocation Loc,
const InitializedEntity &Entity,
- bool VerifyOnly) {
+ bool VerifyOnly,
+ bool TreatUnavailableAsInvalid) {
InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
true);
MultiExprArg SubInit;
InitSeq.InitializeFrom(
SemaRef, Entity,
InitializationKind::CreateValue(Loc, Loc, Loc, true),
- MultiExprArg(), /*TopLevelOfInitList=*/false);
+ MultiExprArg(), /*TopLevelOfInitList=*/false,
+ TreatUnavailableAsInvalid);
// Emit a warning for this. System header warnings aren't shown
// by default, but people working on system headers should see it.
if (!VerifyOnly) {
SourceLocation Loc) {
assert(VerifyOnly &&
"CheckEmptyInitializable is only inteded for verification mode.");
- if (PerformEmptyInit(SemaRef, Loc, Entity, /*VerifyOnly*/true).isInvalid())
+ if (PerformEmptyInit(SemaRef, Loc, Entity, /*VerifyOnly*/true,
+ TreatUnavailableAsInvalid).isInvalid())
hadError = true;
}
ExprResult BaseInit =
FillWithNoInit ? new (SemaRef.Context) NoInitExpr(Base.getType())
: PerformEmptyInit(SemaRef, ILE->getLocEnd(), BaseEntity,
- /*VerifyOnly*/ false);
+ /*VerifyOnly*/ false,
+ TreatUnavailableAsInvalid);
if (BaseInit.isInvalid()) {
hadError = true;
return;
}
ExprResult MemberInit = PerformEmptyInit(SemaRef, Loc, MemberEntity,
- /*VerifyOnly*/false);
+ /*VerifyOnly*/false,
+ TreatUnavailableAsInvalid);
if (MemberInit.isInvalid()) {
hadError = true;
return;
else {
ExprResult ElementInit = PerformEmptyInit(SemaRef, ILE->getLocEnd(),
ElementEntity,
- /*VerifyOnly*/false);
+ /*VerifyOnly*/false,
+ TreatUnavailableAsInvalid);
if (ElementInit.isInvalid()) {
hadError = true;
return;
InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
InitListExpr *IL, QualType &T,
- bool VerifyOnly)
- : SemaRef(S), VerifyOnly(VerifyOnly) {
+ bool VerifyOnly,
+ bool TreatUnavailableAsInvalid)
+ : SemaRef(S), VerifyOnly(VerifyOnly),
+ TreatUnavailableAsInvalid(TreatUnavailableAsInvalid) {
// FIXME: Check that IL isn't already the semantic form of some other
// InitListExpr. If it is, we'd create a broken AST.
// Make sure we can use this declaration.
bool InvalidUse;
if (VerifyOnly)
- InvalidUse = !SemaRef.CanUseDecl(*Field);
+ InvalidUse = !SemaRef.CanUseDecl(*Field, TreatUnavailableAsInvalid);
else
InvalidUse = SemaRef.DiagnoseUseOfDecl(*Field,
IList->getInit(Index)->getLocStart());
// Make sure we can use this declaration.
bool InvalidUse;
if (VerifyOnly)
- InvalidUse = !SemaRef.CanUseDecl(*Field);
+ InvalidUse = !SemaRef.CanUseDecl(*Field, TreatUnavailableAsInvalid);
else
InvalidUse = SemaRef.DiagnoseUseOfDecl(*Field, D->getFieldLoc());
if (InvalidUse) {
const InitializedEntity &Entity,
const InitializationKind &Kind,
InitListExpr *InitList,
- InitializationSequence &Sequence);
+ InitializationSequence &Sequence,
+ bool TreatUnavailableAsInvalid);
/// \brief When initializing from init list via constructor, handle
/// initialization of an object of type std::initializer_list<T>.
static bool TryInitializerListConstruction(Sema &S,
InitListExpr *List,
QualType DestType,
- InitializationSequence &Sequence) {
+ InitializationSequence &Sequence,
+ bool TreatUnavailableAsInvalid) {
QualType E;
if (!S.isStdInitializerList(DestType, &E))
return false;
InitializedEntity::InitializeTemporary(ArrayType);
InitializationKind Kind =
InitializationKind::CreateDirectList(List->getExprLoc());
- TryListInitialization(S, HiddenArray, Kind, List, Sequence);
+ TryListInitialization(S, HiddenArray, Kind, List, Sequence,
+ TreatUnavailableAsInvalid);
if (Sequence)
Sequence.AddStdInitializerListConstructionStep(DestType);
return true;
const InitializedEntity &Entity,
const InitializationKind &Kind,
InitListExpr *InitList,
- InitializationSequence &Sequence) {
+ InitializationSequence &Sequence,
+ bool TreatUnavailableAsInvalid) {
// First, catch C++03 where this isn't possible.
if (!S.getLangOpts().CPlusPlus11) {
Sequence.SetFailed(InitializationSequence::FK_ReferenceBindingToInitList);
// Not reference-related. Create a temporary and bind to that.
InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1);
- TryListInitialization(S, TempEntity, Kind, InitList, Sequence);
+ TryListInitialization(S, TempEntity, Kind, InitList, Sequence,
+ TreatUnavailableAsInvalid);
if (Sequence) {
if (DestType->isRValueReferenceType() ||
(T1Quals.hasConst() && !T1Quals.hasVolatile()))
const InitializedEntity &Entity,
const InitializationKind &Kind,
InitListExpr *InitList,
- InitializationSequence &Sequence) {
+ InitializationSequence &Sequence,
+ bool TreatUnavailableAsInvalid) {
QualType DestType = Entity.getType();
// C++ doesn't allow scalar initialization with more than one argument.
return;
}
if (DestType->isReferenceType()) {
- TryReferenceListInitialization(S, Entity, Kind, InitList, Sequence);
+ TryReferenceListInitialization(S, Entity, Kind, InitList, Sequence,
+ TreatUnavailableAsInvalid);
return;
}
InitList->getRBraceLoc())
: Kind;
Sequence.InitializeFrom(S, Entity, SubKind, SubInit,
- /*TopLevelOfInitList*/ true);
+ /*TopLevelOfInitList*/ true,
+ TreatUnavailableAsInvalid);
// TryStringLiteralInitialization() (in InitializeFrom()) will fail if
// the element is not an appropriately-typed string literal, in which
// - Otherwise, if T is a specialization of std::initializer_list<E>,
// an initializer_list object constructed [...]
- if (TryInitializerListConstruction(S, InitList, DestType, Sequence))
+ if (TryInitializerListConstruction(S, InitList, DestType, Sequence,
+ TreatUnavailableAsInvalid))
return;
// - Otherwise, if T is a class type, constructors are considered.
: Kind;
Expr *SubInit[1] = { InitList->getInit(0) };
Sequence.InitializeFrom(S, Entity, SubKind, SubInit,
- /*TopLevelOfInitList*/true);
+ /*TopLevelOfInitList*/true,
+ TreatUnavailableAsInvalid);
if (Sequence)
Sequence.RewrapReferenceInitList(Entity.getType(), InitList);
return;
}
InitListChecker CheckInitList(S, Entity, InitList,
- DestType, /*VerifyOnly=*/true);
+ DestType, /*VerifyOnly=*/true, TreatUnavailableAsInvalid);
if (CheckInitList.HadError()) {
Sequence.SetFailed(InitializationSequence::FK_ListInitializationFailed);
return;
const InitializedEntity &Entity,
const InitializationKind &Kind,
MultiExprArg Args,
- bool TopLevelOfInitList)
+ bool TopLevelOfInitList,
+ bool TreatUnavailableAsInvalid)
: FailedCandidateSet(Kind.getLocation(), OverloadCandidateSet::CSK_Normal) {
- InitializeFrom(S, Entity, Kind, Args, TopLevelOfInitList);
+ InitializeFrom(S, Entity, Kind, Args, TopLevelOfInitList,
+ TreatUnavailableAsInvalid);
}
/// Tries to get a FunctionDecl out of `E`. If it succeeds and we can take the
const InitializedEntity &Entity,
const InitializationKind &Kind,
MultiExprArg Args,
- bool TopLevelOfInitList) {
+ bool TopLevelOfInitList,
+ bool TreatUnavailableAsInvalid) {
ASTContext &Context = S.Context;
// Eliminate non-overload placeholder types in the arguments. We
// object is list-initialized (8.5.4).
if (Kind.getKind() != InitializationKind::IK_Direct) {
if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
- TryListInitialization(S, Entity, Kind, InitList, *this);
+ TryListInitialization(S, Entity, Kind, InitList, *this,
+ TreatUnavailableAsInvalid);
return;
}
}
Entity.getKind() == InitializedEntity::EK_Member &&
Initializer && isa<InitListExpr>(Initializer)) {
TryListInitialization(S, Entity, Kind, cast<InitListExpr>(Initializer),
- *this);
+ *this, TreatUnavailableAsInvalid);
AddParenthesizedArrayInitStep(DestType);
} else if (DestAT->getElementType()->isCharType())
SetFailed(FK_ArrayNeedsInitListOrStringLiteral);
InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(Ty);
InitializedEntity InitEntity = IsTemporary ? TempEntity : Entity;
InitListChecker PerformInitList(S, InitEntity,
- InitList, Ty, /*VerifyOnly=*/false);
+ InitList, Ty, /*VerifyOnly=*/false,
+ /*TreatUnavailableAsInvalid=*/false);
if (PerformInitList.HadError())
return ExprError();
}
InitListChecker DiagnoseInitList(S, Entity, InitList, DestType,
- /*VerifyOnly=*/false);
+ /*VerifyOnly=*/false,
+ /*TreatUnavailableAsInvalid=*/false);
assert(DiagnoseInitList.HadError() &&
"Inconsistent init list check result.");
}