forked from OSchip/llvm-project
[c++17] P0490R0, NB comment FI 20: allow direct-initialization of decomposition declarations.
llvm-svn: 289286
This commit is contained in:
parent
e4600d330f
commit
4b46cb9190
|
@ -398,8 +398,6 @@ def err_decomp_decl_not_alone : Error<
|
|||
"decomposition declaration must be the only declaration in its group">;
|
||||
def err_decomp_decl_requires_init : Error<
|
||||
"decomposition declaration %0 requires an initializer">;
|
||||
def err_decomp_decl_paren_init : Error<
|
||||
"decomposition declaration %0 cannot have a parenthesized initializer">;
|
||||
def err_decomp_decl_wrong_number_bindings : Error<
|
||||
"type %0 decomposes into %2 elements, but %select{only |}3%1 "
|
||||
"names were provided">;
|
||||
|
|
|
@ -9625,6 +9625,20 @@ namespace {
|
|||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace {
|
||||
// Simple wrapper to add the name of a variable or (if no variable is
|
||||
// available) a DeclarationName into a diagnostic.
|
||||
struct VarDeclOrName {
|
||||
VarDecl *VDecl;
|
||||
DeclarationName Name;
|
||||
|
||||
friend const Sema::SemaDiagnosticBuilder &
|
||||
operator<<(const Sema::SemaDiagnosticBuilder &Diag, VarDeclOrName VN) {
|
||||
return VN.VDecl ? Diag << VN.VDecl : Diag << VN.Name;
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
||||
DeclarationName Name, QualType Type,
|
||||
TypeSourceInfo *TSI,
|
||||
|
@ -9634,6 +9648,8 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
|||
assert((!VDecl || !VDecl->isInitCapture()) &&
|
||||
"init captures are expected to be deduced prior to initialization");
|
||||
|
||||
VarDeclOrName VN{VDecl, Name};
|
||||
|
||||
// FIXME: Deduction for a decomposition declaration does weird things if the
|
||||
// initializer is an array.
|
||||
|
||||
|
@ -9652,7 +9668,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
|||
Diag(Init->getLocStart(), IsInitCapture
|
||||
? diag::err_init_capture_no_expression
|
||||
: diag::err_auto_var_init_no_expression)
|
||||
<< Name << Type << Range;
|
||||
<< VN << Type << Range;
|
||||
return QualType();
|
||||
}
|
||||
|
||||
|
@ -9660,7 +9676,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
|||
Diag(DeduceInits[1]->getLocStart(),
|
||||
IsInitCapture ? diag::err_init_capture_multiple_expressions
|
||||
: diag::err_auto_var_init_multiple_expressions)
|
||||
<< Name << Type << Range;
|
||||
<< VN << Type << Range;
|
||||
return QualType();
|
||||
}
|
||||
|
||||
|
@ -9669,7 +9685,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
|||
Diag(Init->getLocStart(), IsInitCapture
|
||||
? diag::err_init_capture_paren_braces
|
||||
: diag::err_auto_var_init_paren_braces)
|
||||
<< isa<InitListExpr>(Init) << Name << Type << Range;
|
||||
<< isa<InitListExpr>(Init) << VN << Type << Range;
|
||||
return QualType();
|
||||
}
|
||||
|
||||
|
@ -9692,13 +9708,13 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
|||
else if (isa<InitListExpr>(Init))
|
||||
Diag(Range.getBegin(),
|
||||
diag::err_init_capture_deduction_failure_from_init_list)
|
||||
<< Name
|
||||
<< VN
|
||||
<< (DeduceInit->getType().isNull() ? TSI->getType()
|
||||
: DeduceInit->getType())
|
||||
<< DeduceInit->getSourceRange();
|
||||
else
|
||||
Diag(Range.getBegin(), diag::err_init_capture_deduction_failure)
|
||||
<< Name << TSI->getType()
|
||||
<< VN << TSI->getType()
|
||||
<< (DeduceInit->getType().isNull() ? TSI->getType()
|
||||
: DeduceInit->getType())
|
||||
<< DeduceInit->getSourceRange();
|
||||
|
@ -9712,7 +9728,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
|||
if (ActiveTemplateInstantiations.empty() && !DefaultedAnyToId &&
|
||||
!IsInitCapture && !DeducedType.isNull() && DeducedType->isObjCIdType()) {
|
||||
SourceLocation Loc = TSI->getTypeLoc().getBeginLoc();
|
||||
Diag(Loc, diag::warn_auto_var_is_id) << Name << Range;
|
||||
Diag(Loc, diag::warn_auto_var_is_id) << VN << Range;
|
||||
}
|
||||
|
||||
return DeducedType;
|
||||
|
@ -9746,11 +9762,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
|
|||
return;
|
||||
}
|
||||
|
||||
// C++1z [dcl.dcl]p1 grammar implies that a parenthesized initializer is not
|
||||
// permitted.
|
||||
if (isa<DecompositionDecl>(VDecl) && DirectInit && isa<ParenListExpr>(Init))
|
||||
Diag(VDecl->getLocation(), diag::err_decomp_decl_paren_init) << VDecl;
|
||||
|
||||
// C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
|
||||
if (TypeMayContainAuto && VDecl->getType()->isUndeducedType()) {
|
||||
// Attempt typo correction early so that the type of the init expression can
|
||||
|
|
|
@ -139,9 +139,11 @@ namespace Init {
|
|||
int arr[1];
|
||||
struct S { int n; };
|
||||
auto &[bad1]; // expected-error {{decomposition declaration '[bad1]' requires an initializer}}
|
||||
const auto &[bad2](S{}); // expected-error {{decomposition declaration '[bad2]' cannot have a parenthesized initializer}}
|
||||
const auto &[bad2](S{}, S{}); // expected-error {{initializer for variable '[bad2]' with type 'const auto &' contains multiple expressions}}
|
||||
const auto &[bad3](); // expected-error {{expected expression}}
|
||||
auto &[good1] = arr;
|
||||
auto &&[good2] = S{};
|
||||
const auto &[good3](S{});
|
||||
S [goodish3] = { 4 }; // expected-error {{cannot be declared with type 'S'}}
|
||||
S [goodish4] { 4 }; // expected-error {{cannot be declared with type 'S'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue