diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-28 06:27:18 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-28 06:27:18 +0000 |
commit | 15361a21e01026e74cb17011b702c7d1c881ae94 (patch) | |
tree | 76c2b63c54704b2b79c6f9059e9b5463cdb4df64 /clang/lib/Sema | |
parent | 873c275caa6d8ece36eb4f799e37ba1e6e1674bf (diff) | |
download | bcm5719-llvm-15361a21e01026e74cb17011b702c7d1c881ae94.tar.gz bcm5719-llvm-15361a21e01026e74cb17011b702c7d1c881ae94.zip |
Mark 'auto' as dependent when instantiating the type of a non-type template
parameter. Fixes failed deduction for 'auto' non-type template parameters
nested within templates.
llvm-svn: 290660
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 31 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 26 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 9 |
3 files changed, 37 insertions, 29 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 996a8baee1d..55421a3e0b0 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -729,8 +729,22 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, /// /// \returns the (possibly-promoted) parameter type if valid; /// otherwise, produces a diagnostic and returns a NULL type. -QualType -Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) { +QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, + SourceLocation Loc) { + if (TSI->getType()->isUndeducedType()) { + // C++1z [temp.dep.expr]p3: + // An id-expression is type-dependent if it contains + // - an identifier associated by name lookup with a non-type + // template-parameter declared with a type that contains a + // placeholder type (7.1.7.4), + TSI = SubstAutoTypeSourceInfo(TSI, Context.DependentTy); + } + + return CheckNonTypeTemplateParameterType(TSI->getType(), Loc); +} + +QualType Sema::CheckNonTypeTemplateParameterType(QualType T, + SourceLocation Loc) { // We don't allow variably-modified types as the type of non-type template // parameters. if (T->isVariablyModifiedType()) { @@ -759,10 +773,6 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) { T->isDependentType() || // Allow use of auto in template parameter declarations. T->isUndeducedType()) { - if (T->isUndeducedType()) { - Diag(Loc, diag::warn_cxx14_compat_template_nontype_parm_auto_type) - << QualType(T->getContainedAutoType(), 0); - } // C++ [temp.param]p5: The top-level cv-qualifiers on the template-parameter // are ignored when determining its type. return T.getUnqualifiedType(); @@ -788,13 +798,18 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, SourceLocation EqualLoc, Expr *Default) { TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); - QualType T = TInfo->getType(); + + if (TInfo->getType()->isUndeducedType()) { + Diag(D.getIdentifierLoc(), + diag::warn_cxx14_compat_template_nontype_parm_auto_type) + << QualType(TInfo->getType()->getContainedAutoType(), 0); + } assert(S->isTemplateParamScope() && "Non-type template parameter not in template parameter scope!"); bool Invalid = false; - T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc()); + QualType T = CheckNonTypeTemplateParameterType(TInfo, D.getIdentifierLoc()); if (T.isNull()) { T = Context.IntTy; // Recover with an 'int' type. Invalid = true; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8e671ad46cf..7328dcb8760 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2085,18 +2085,18 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( ExpandedParameterPackTypes.reserve(D->getNumExpansionTypes()); ExpandedParameterPackTypesAsWritten.reserve(D->getNumExpansionTypes()); for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { - TypeSourceInfo *NewDI =SemaRef.SubstType(D->getExpansionTypeSourceInfo(I), - TemplateArgs, - D->getLocation(), - D->getDeclName()); + TypeSourceInfo *NewDI = + SemaRef.SubstType(D->getExpansionTypeSourceInfo(I), TemplateArgs, + D->getLocation(), D->getDeclName()); if (!NewDI) return nullptr; - ExpandedParameterPackTypesAsWritten.push_back(NewDI); - QualType NewT =SemaRef.CheckNonTypeTemplateParameterType(NewDI->getType(), - D->getLocation()); + QualType NewT = + SemaRef.CheckNonTypeTemplateParameterType(NewDI, D->getLocation()); if (NewT.isNull()) return nullptr; + + ExpandedParameterPackTypesAsWritten.push_back(NewDI); ExpandedParameterPackTypes.push_back(NewT); } @@ -2136,12 +2136,12 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( if (!NewDI) return nullptr; - ExpandedParameterPackTypesAsWritten.push_back(NewDI); - QualType NewT = SemaRef.CheckNonTypeTemplateParameterType( - NewDI->getType(), - D->getLocation()); + QualType NewT = + SemaRef.CheckNonTypeTemplateParameterType(NewDI, D->getLocation()); if (NewT.isNull()) return nullptr; + + ExpandedParameterPackTypesAsWritten.push_back(NewDI); ExpandedParameterPackTypes.push_back(NewT); } @@ -2161,6 +2161,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( if (!NewPattern) return nullptr; + SemaRef.CheckNonTypeTemplateParameterType(NewPattern, D->getLocation()); DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(), NumExpansions); if (!DI) @@ -2176,8 +2177,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( return nullptr; // Check that this type is acceptable for a non-type template parameter. - T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(), - D->getLocation()); + T = SemaRef.CheckNonTypeTemplateParameterType(DI, D->getLocation()); if (T.isNull()) { T = SemaRef.Context.IntTy; Invalid = true; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index aa3887962d1..ae9a3ee790e 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1534,14 +1534,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // template type parameter. Result = QualType(CorrespondingTemplateParam->getTypeForDecl(), 0); } else { - // If auto appears in the declaration of a template parameter, treat - // the parameter as type-dependent. - bool IsDependent = - S.getLangOpts().CPlusPlus1z && - declarator.getContext() == Declarator::TemplateParamContext; - Result = Context.getAutoType(QualType(), - AutoTypeKeyword::Auto, - IsDependent); + Result = Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false); } break; |