[202x] Enable variadic templates - #8911
Chris B (llvm-beanz) wants to merge 4 commits into
Conversation
This enables C++11 variadic templates in HLSL and exposes `...` function parameter packs. This feature is being refined by TC57 for inclusion in the first draft of the HLSL specification, and while including it here is getting a little ahead of the committee, it's a frequently requested high-value feature that is minimally invasive to support in DXC and is already supported in Clang. Resolves microsoft#8905 Assisted-by: GitHub Copilot
There was a problem hiding this comment.
🟡 Changes recommended
The newly enabled template-template parameter-pack parser path lacks positive and backward-compatibility coverage.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Enables C++11 variadic templates for HLSL 202x while preserving rejection in earlier language versions.
Changes:
- Adds version-aware parsing and semantic support for parameter packs, expansions, and
sizeof.... - Adds DXIL, SPIR-V, semantic, and negative coverage.
- Documents the feature in release notes.
File summaries
| File | Description |
|---|---|
tools/clang/test/SemaHLSL/v202x/templates/variadic-templates.hlsl |
Tests core semantics and ASTs. |
tools/clang/test/SemaHLSL/v202x/templates/variadic-templates-pre202x.hlsl |
Tests HLSL 2021 rejection. |
tools/clang/test/SemaHLSL/v202x/templates/variadic-templates-negative.hlsl |
Tests invalid constructs. |
tools/clang/test/SemaHLSL/v202x/templates/variadic-templates-initlist-scalarize.hlsl |
Tests initializer scalarization. |
tools/clang/test/SemaHLSL/v202x/templates/variadic-templates-initlist-scalarize-negative.hlsl |
Tests scalarization diagnostics. |
tools/clang/test/SemaHLSL/v202x/templates/variadic-base-class-unsupported.hlsl |
Tests unsupported base packs. |
tools/clang/test/HLSLFileCheckLit/hlsl/templates/variadic-initlist-scalarize.hlsl |
Verifies DXIL scalarization. |
tools/clang/test/HLSLFileCheckLit/hlsl/templates/variadic-builtin-templates.hlsl |
Verifies built-in template expansion. |
tools/clang/test/HLSLFileCheckLit/hlsl/templates/variadic-202x.hlsl |
Verifies basic DXIL generation. |
tools/clang/test/CodeGenSPIRV/variadic.templates.initlist-scalarize.hlsl |
Verifies SPIR-V scalarization. |
tools/clang/test/CodeGenSPIRV/variadic.templates.builtin.hlsl |
Verifies SPIR-V built-in templates. |
tools/clang/test/CodeGenSPIRV/variadic.templates.basic.hlsl |
Verifies basic SPIR-V generation. |
tools/clang/lib/Sema/SemaType.cpp |
Enables parameter-pack types in 202x. |
tools/clang/lib/Sema/SemaTemplateVariadic.cpp |
Enables pack expansion semantics. |
tools/clang/lib/Parse/ParseTemplate.cpp |
Enables variadic template syntax. |
tools/clang/lib/Parse/ParseInit.cpp |
Enables initializer-list expansions. |
tools/clang/lib/Parse/ParseExpr.cpp |
Enables expression expansions and sizeof.... |
tools/clang/lib/Parse/ParseDecl.cpp |
Enables function parameter packs. |
tools/clang/include/clang/Basic/LangOptions.h |
Adds the version feature predicate. |
docs/ReleaseNotes.md |
Announces HLSL 202x support. |
Review details
- Files reviewed: 20/20 changed files
- Comments generated: 2
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| // HLSL Change Starts | ||
| /// Whether the active HLSL version rejects variadic templates. | ||
| bool HLSLDisallowsVariadicTemplates() const { |
| if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) { | ||
| // HLSL Change Starts | ||
| if (getLangOpts().HLSL) | ||
| if (getLangOpts().HLSLDisallowsVariadicTemplates()) |
There was a problem hiding this comment.
🔵 Needs a closer look
Preprocessor feature reporting is inconsistent with the new language support, and template-template parameter packs lack coverage.
Review details
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
tools/clang/include/clang/Basic/LangOptions.h:194
- The new language-version gate is not reflected in the preprocessor feature probes. HLSL sets
CPlusPlusbut notCPlusPlus11, soPPMacroExpansion.cpp:1159still makes__has_feature(cxx_variadic_templates)false in 202x, while line 1252 makes__has_extension(cxx_variadic_templates)true even in pre-202x modes. These are the documented probes for variadic-template support, so version-conditional code receives contradictory results. Please gate both probes on HLSL 202x as well (and consider the corresponding__cpp_variadic_templatesmacro).
tools/clang/lib/Parse/ParseTemplate.cpp:625
- This branch newly enables template-template parameter packs, but none of the added HLSL tests exercises syntax such as
template <template <typename> class... Ts>. Add a 202x acceptance/AST case and a pre-202x rejection case so this distinct parser path cannot regress independently of type and non-type packs.
if (getLangOpts().HLSLDisallowsVariadicTemplates())
Diag(EllipsisLoc, diag::err_hlsl_variadic_templates);
else if (!getLangOpts().HLSL) // HLSL has no C++98-compat warnings
- Files reviewed: 20/20 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Not sure how I missed this before pushing initially...
There was a problem hiding this comment.
🔵 Needs a closer look
The broad expansion gate unintentionally enables C++17 fold expressions, and one newly enabled parser path lacks coverage.
Review details
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
tools/clang/lib/Sema/SemaTemplateVariadic.cpp:548
- This global gate also enables C++17 fold expressions in HLSL 202x, although this change is scoped to C++11 variadic templates.
ParseFoldExpressionaccepts the syntax (with only an extension warning), andTreeTransform::TransformCXXFoldExprreaches this function during instantiation, so a function such astemplate<typename... T> int sum(T... x) { return (x + ...); }is now expanded. The linked TC57 proposal lists fold expressions separately under C++17 rather than as part of this adoption. Please retain an explicit HLSL rejection for fold expressions and add a negative 202x test.
tools/clang/lib/Parse/ParseTemplate.cpp:625
- This branch newly enables template-template parameter packs, but the added tests cover only type and non-type packs. Please add HLSL 202x acceptance/instantiation coverage (and preferably the pre-202x rejection) for syntax such as
template <template <typename> class... Templates>so this distinct parser/Sema path is exercised.
if (getLangOpts().HLSLDisallowsVariadicTemplates())
Diag(EllipsisLoc, diag::err_hlsl_variadic_templates);
else if (!getLangOpts().HLSL) // HLSL has no C++98-compat warnings
- Files reviewed: 20/20 changed files
- Comments generated: 0 new
- Review effort level: Balanced
In tree transform we need to generate an expanded parameter modifier set for the parameter pack. We also need ot handle value-dependent expressions for constant evaluation.
There was a problem hiding this comment.
🟡 Changes recommended
Pack expansion can misassign parameter modifiers, enable out-of-scope fold expressions, and report inconsistent feature availability.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
tools/clang/include/clang/Basic/LangOptions.h:195
- Please apply this version gate to the preprocessor capability probes as well. HLSL sets
CPlusPlusbut notCPlusPlus11, so__has_feature(cxx_variadic_templates)remains false in 202x, while__has_extension(cxx_variadic_templates)remains true even in pre-202x modes (PPMacroExpansion.cpp:1159,1252);__cpp_variadic_templatesis also still omitted byInitPreprocessor.cpp:477-490. Code cannot reliably detect the newly versioned feature until these probes use the same condition.
tools/clang/lib/Sema/SemaTemplateVariadic.cpp:550 - This shared expansion gate also enables C++17 fold expressions in HLSL 202x, although the PR is scoped to C++11 variadic templates.
ParseFoldExpressionaccepts(args + ...)with only an extension diagnostic, andTransformCXXFoldExprreaches this method during instantiation; changing this condition therefore lets the fold instantiate instead of retaining HLSL's rejection. Keep an explicit HLSL rejection for fold expressions and add a 202x negative test.
- Files reviewed: 22/22 changed files
- Comments generated: 1
- Review effort level: Balanced
| if (ParamMods.size() != ParamTypes.size()) { | ||
| ExpandedParamMods.reserve(ParamDecls.size()); | ||
| for (ParmVarDecl *Param : ParamDecls) | ||
| ExpandedParamMods.push_back(Param ? Param->getParamModifiers() | ||
| : hlsl::ParameterModifier()); | ||
| ParamMods = ExpandedParamMods; |
There was a problem hiding this comment.
A function template can't have multiple different parameter packs for different parameters. It would be ambiguous at the call site to split the parameter packs.
This enables C++11 variadic templates in HLSL and exposes
...function parameter packs.This feature is being refined by TC57 for inclusion in the first draft of the HLSL specification, and while including it here is getting a little ahead of the committee, it's a frequently requested high-value feature that is minimally invasive to support in DXC and is already supported in Clang.
Resolves #8905
Assisted-by: GitHub Copilot