Index: cfe/trunk/include/clang/Sema/Sema.h =================================================================== --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -5647,7 +5647,8 @@ SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef Params, - SourceLocation RAngleLoc); + SourceLocation RAngleLoc, + Expr *RequiresClause); /// \brief The context in which we are checking a template parameter list. enum TemplateParamListContext { Index: cfe/trunk/lib/Parse/ParseDecl.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp +++ cfe/trunk/lib/Parse/ParseDecl.cpp @@ -2004,7 +2004,7 @@ TemplateParameterLists FakedParamLists; FakedParamLists.push_back(Actions.ActOnTemplateParameterList( 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None, - LAngleLoc)); + LAngleLoc, nullptr)); ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D); Index: cfe/trunk/lib/Parse/ParseDeclCXX.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp @@ -1670,7 +1670,7 @@ // template specialization. FakedParamLists.push_back(Actions.ActOnTemplateParameterList( 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None, - LAngleLoc)); + LAngleLoc, nullptr)); TemplateParams = &FakedParamLists; } } Index: cfe/trunk/lib/Parse/ParseTemplate.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseTemplate.cpp +++ cfe/trunk/lib/Parse/ParseTemplate.cpp @@ -122,20 +122,15 @@ return nullptr; } - ParamLists.push_back( - Actions.ActOnTemplateParameterList(CurTemplateDepthTracker.getDepth(), - ExportLoc, - TemplateLoc, LAngleLoc, - TemplateParams, RAngleLoc)); - + ExprResult OptionalRequiresClauseConstraintER; if (!TemplateParams.empty()) { isSpecialization = false; ++CurTemplateDepthTracker; if (TryConsumeToken(tok::kw_requires)) { - ExprResult ER = + OptionalRequiresClauseConstraintER = Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression()); - if (!ER.isUsable()) { + if (!OptionalRequiresClauseConstraintER.isUsable()) { // Skip until the semi-colon or a '}'. SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); TryConsumeToken(tok::semi); @@ -145,6 +140,10 @@ } else { LastParamListWasEmpty = true; } + + ParamLists.push_back(Actions.ActOnTemplateParameterList( + CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc, + TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get())); } while (Tok.isOneOf(tok::kw_export, tok::kw_template)); unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope; @@ -287,7 +286,7 @@ TemplateParameterLists FakedParamLists; FakedParamLists.push_back(Actions.ActOnTemplateParameterList( 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None, - LAngleLoc)); + LAngleLoc, nullptr)); return ParseFunctionDefinition( DeclaratorInfo, ParsedTemplateInfo(&FakedParamLists, @@ -638,7 +637,7 @@ Actions.ActOnTemplateParameterList(Depth, SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams, - RAngleLoc); + RAngleLoc, nullptr); // Grab a default argument (if available). // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before Index: cfe/trunk/lib/Sema/SemaTemplate.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp +++ cfe/trunk/lib/Sema/SemaTemplate.cpp @@ -817,18 +817,21 @@ return Param; } -/// ActOnTemplateParameterList - Builds a TemplateParameterList that -/// contains the template parameters in Params/NumParams. +/// ActOnTemplateParameterList - Builds a TemplateParameterList, optionally +/// constrained by RequiresClause, that contains the template parameters in +/// Params. TemplateParameterList * Sema::ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef Params, - SourceLocation RAngleLoc) { + SourceLocation RAngleLoc, + Expr *RequiresClause) { if (ExportLoc.isValid()) Diag(ExportLoc, diag::warn_template_export_unsupported); + // FIXME: store RequiresClause return TemplateParameterList::Create( Context, TemplateLoc, LAngleLoc, llvm::makeArrayRef((NamedDecl *const *)Params.data(), Params.size()),