diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-09 19:17:44 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-09 19:17:44 +0000 |
| commit | 60437620db8efae20e880c3a70933f6e8149dc7c (patch) | |
| tree | 25e4f211469fcc36ffba57cf477aed2e59d28c0f /clang/lib/Sema/SemaDecl.cpp | |
| parent | a18ef6f1f9d2a32519192feedadb7814461db488 (diff) | |
| download | bcm5719-llvm-60437620db8efae20e880c3a70933f6e8149dc7c.tar.gz bcm5719-llvm-60437620db8efae20e880c3a70933f6e8149dc7c.zip | |
[c++1z] P0091R3: Basic support for deducing class template arguments via deduction-guides.
llvm-svn: 294613
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 103 |
1 files changed, 57 insertions, 46 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index f103f30b4df..658146d6389 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9807,16 +9807,33 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, DeducedType *Deduced = Type->getContainedDeducedType(); assert(Deduced && "deduceVarTypeFromInitializer for non-deduced type"); + ArrayRef<Expr*> DeduceInits = Init ? ArrayRef<Expr*>(Init) : None; + if (DirectInit) { + if (auto *PL = dyn_cast_or_null<ParenListExpr>(Init)) + DeduceInits = PL->exprs(); + } + if (isa<DeducedTemplateSpecializationType>(Deduced)) { - Diag(Init->getLocStart(), diag::err_deduced_class_template_not_supported); + assert(VDecl && "non-auto type for init capture deduction?"); + InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl); + InitializationKind Kind = InitializationKind::CreateForInit( + VDecl->getLocation(), DirectInit, Init); + // FIXME: Initialization should not be taking a mutable list of inits. + SmallVector<Expr*, 8> InitsCopy(DeduceInits.begin(), DeduceInits.end()); + return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind, + InitsCopy); + } + + // C++11 [dcl.spec.auto]p3 + if (!Init) { + assert(VDecl && "no init for init capture deduction?"); + Diag(VDecl->getLocation(), diag::err_auto_var_requires_init) + << VDecl->getDeclName() << Type; return QualType(); } - ArrayRef<Expr *> DeduceInits = Init; if (DirectInit) { - if (auto *PL = dyn_cast<ParenListExpr>(Init)) - DeduceInits = PL->exprs(); - else if (auto *IL = dyn_cast<InitListExpr>(Init)) + if (auto *IL = dyn_cast<InitListExpr>(Init)) DeduceInits = IL->inits(); } @@ -9902,6 +9919,36 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, return DeducedType; } +bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, + Expr *Init) { + QualType DeducedType = deduceVarTypeFromInitializer( + VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(), + VDecl->getSourceRange(), DirectInit, Init); + if (DeducedType.isNull()) { + VDecl->setInvalidDecl(); + return true; + } + + VDecl->setType(DeducedType); + assert(VDecl->isLinkageValid()); + + // In ARC, infer lifetime. + if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl)) + VDecl->setInvalidDecl(); + + // If this is a redeclaration, check that the type we just deduced matches + // the previously declared type. + if (VarDecl *Old = VDecl->getPreviousDecl()) { + // We never need to merge the type, because we cannot form an incomplete + // array of auto, nor deduce such a type. + MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/ false); + } + + // Check the deduced type is valid for a variable declaration. + CheckVariableDeclarationType(VDecl); + return VDecl->isInvalidDecl(); +} + /// AddInitializerToDecl - Adds the initializer Init to the /// declaration dcl. If DirectInit is true, this is C++ direct /// initialization rather than copy initialization. @@ -9941,32 +9988,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { } Init = Res.get(); - QualType DeducedType = deduceVarTypeFromInitializer( - VDecl, VDecl->getDeclName(), VDecl->getType(), - VDecl->getTypeSourceInfo(), VDecl->getSourceRange(), DirectInit, Init); - if (DeducedType.isNull()) { - RealDecl->setInvalidDecl(); - return; - } - - VDecl->setType(DeducedType); - assert(VDecl->isLinkageValid()); - - // In ARC, infer lifetime. - if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl)) - VDecl->setInvalidDecl(); - - // If this is a redeclaration, check that the type we just deduced matches - // the previously declared type. - if (VarDecl *Old = VDecl->getPreviousDecl()) { - // We never need to merge the type, because we cannot form an incomplete - // array of auto, nor deduce such a type. - MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/ false); - } - - // Check the deduced type is valid for a variable declaration. - CheckVariableDeclarationType(VDecl); - if (VDecl->isInvalidDecl()) + if (DeduceVariableDeclarationType(VDecl, DirectInit, Init)) return; } @@ -10085,15 +10107,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { } InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl); - InitializationKind Kind = - DirectInit - ? CXXDirectInit - ? InitializationKind::CreateDirect(VDecl->getLocation(), - Init->getLocStart(), - Init->getLocEnd()) - : InitializationKind::CreateDirectList(VDecl->getLocation()) - : InitializationKind::CreateCopy(VDecl->getLocation(), - Init->getLocStart()); + InitializationKind Kind = InitializationKind::CreateForInit( + VDecl->getLocation(), DirectInit, Init); MultiExprArg Args = Init; if (CXXDirectInit) @@ -10417,13 +10432,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { return; } - // C++11 [dcl.spec.auto]p3 - if (Type->isUndeducedType()) { - Diag(Var->getLocation(), diag::err_auto_var_requires_init) - << Var->getDeclName() << Type; - Var->setInvalidDecl(); + if (Type->isUndeducedType() && + DeduceVariableDeclarationType(Var, false, nullptr)) return; - } // C++11 [class.static.data]p3: A static data member can be declared with // the constexpr specifier; if so, its declaration shall specify |

