Skip to content

Commit af24013

Browse files
authored
[HLSL2021] Fix template parameter for buffer types (#4099)
This is a bit of an oddball situation caused by a two factors. (1) We verify that template parameters for buffer types are complete (2) The template expansion for the HLSL buffer types doesn't actually require instantiation of the parameter type We could, skip verification of template parameters, but doing so causes the backend to crash because we need the buffer type expanded for code generation. Skipping verification might work in some common cases, but will fail if buffers are unused, and if nothing else forces the instantiation. The safe approach is to force instantiation ourselves, and that's what this change does. Basically if the parameter of a buffer type is a template specialization, we force the specialization to instantiate by creating the specialization in the AST. This allows us to continue verifing that the types are complete, because after instantiation the template type is complete.
1 parent cc50c79 commit af24013

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

tools/clang/lib/Sema/SemaHLSL.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4830,6 +4830,17 @@ class HLSLExternalSource : public ExternalSemaSource {
48304830
<< argType;
48314831
return true;
48324832
}
4833+
if (auto *TST = dyn_cast<TemplateSpecializationType>(argType)) {
4834+
// This is a bit of a special case we need to handle. Because the
4835+
// buffer types don't use their template parameter in a way that would
4836+
// force instantiation, we need to force specialization here.
4837+
GetOrCreateTemplateSpecialization(
4838+
*m_context, *m_sema,
4839+
cast<ClassTemplateDecl>(
4840+
TST->getTemplateName().getAsTemplateDecl()),
4841+
llvm::ArrayRef<TemplateArgument>(TST->getArgs(),
4842+
TST->getNumArgs()));
4843+
}
48334844
if (const RecordType* recordType = argType->getAsStructureType()) {
48344845
if (!recordType->getDecl()->isCompleteDefinition()) {
48354846
m_sema->Diag(argSrcLoc, diag::err_typecheck_decl_incomplete_type)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %dxc -E main -T cs_6_0 -ast-dump -enable-templates %s | FileCheck %s
2+
// RUN: %dxc -E main -T cs_6_0 -ast-dump -HV 2021 %s | FileCheck %s
3+
struct Foo { float f;};
4+
template <typename T> struct Wrap { T value; };
5+
ConstantBuffer<Wrap<Foo> >CB;
6+
7+
[numthreads(1,1,1)]
8+
void main() {
9+
}
10+
11+
// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9a-zA-Z]+}} <col:1, col:46> col:30 struct Wrap definition
12+
// CHECK-NEXT: TemplateArgument type 'Foo'
13+
// CHECK-NEXT: CXXRecordDecl 0x{{[0-9a-zA-Z]+}} prev 0x{{[0-9a-zA-Z]+}} <col:23, col:30> col:30 implicit struct Wrap
14+
// CHECK-NEXT: `-FieldDecl 0x{{[0-9a-zA-Z]+}} <col:37, col:39> col:39 value 'Foo':'Foo'

0 commit comments

Comments
 (0)