diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 6a6aff594fb0f..defc79683e61f 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -280,18 +280,22 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) { const auto *RD = Ty->getAsCXXRecordDecl(); if (!RD) return; - const auto *HLSLResAttr = RD->getAttr(); - const auto *HLSLResClassAttr = RD->getAttr(); - if (!HLSLResAttr || !HLSLResClassAttr) - return; + // the resource related attributes are on the handle member + // inside the record decl + for (auto *FD : RD->fields()) { + const auto *HLSLResAttr = FD->getAttr(); + const auto *HLSLResClassAttr = FD->getAttr(); + if (!HLSLResAttr || !HLSLResClassAttr) + continue; - llvm::hlsl::ResourceClass RC = HLSLResClassAttr->getResourceClass(); - llvm::hlsl::ResourceKind RK = HLSLResAttr->getResourceKind(); - bool IsROV = HLSLResAttr->getIsROV(); - llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty); + llvm::hlsl::ResourceClass RC = HLSLResClassAttr->getResourceClass(); + llvm::hlsl::ResourceKind RK = HLSLResAttr->getResourceKind(); + bool IsROV = HLSLResAttr->getIsROV(); + llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty); - BufferResBinding Binding(D->getAttr()); - addBufferResourceAnnotation(GV, RC, RK, IsROV, ET, Binding); + BufferResBinding Binding(D->getAttr()); + addBufferResourceAnnotation(GV, RC, RK, IsROV, ET, Binding); + } } CGHLSLRuntime::BufferResBinding::BufferResBinding( diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index ca88d138aef5d..6ee90d15d7a6d 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -80,7 +80,7 @@ struct BuiltinTypeDeclBuilder { } BuiltinTypeDeclBuilder & - addMemberVariable(StringRef Name, QualType Type, + addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef Attrs, AccessSpecifier Access = AccessSpecifier::AS_private) { if (Record->isCompleteDefinition()) return *this; @@ -96,13 +96,16 @@ struct BuiltinTypeDeclBuilder { nullptr, false, InClassInitStyle::ICIS_NoInit); Field->setAccess(Access); Field->setImplicit(true); + for (Attr *A : Attrs) + Field->addAttr(A); Record->addDecl(Field); Fields[Name] = Field; return *this; } BuiltinTypeDeclBuilder & - addHandleMember(AccessSpecifier Access = AccessSpecifier::AS_private) { + addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV, + AccessSpecifier Access = AccessSpecifier::AS_private) { if (Record->isCompleteDefinition()) return *this; QualType Ty = Record->getASTContext().VoidPtrTy; @@ -112,17 +115,13 @@ struct BuiltinTypeDeclBuilder { Ty = Record->getASTContext().getPointerType( QualType(TTD->getTypeForDecl(), 0)); } - return addMemberVariable("h", Ty, Access); - } - - BuiltinTypeDeclBuilder &annotateHLSLResource(ResourceClass RC, - ResourceKind RK, bool IsROV) { - if (Record->isCompleteDefinition()) - return *this; - Record->addAttr( - HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC)); - Record->addAttr( - HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK, IsROV)); + // add handle member + llvm::SmallVector Attrs; + Attr *ResourceClassAttr = + HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC); + Attr *ResourceAttr = + HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK, IsROV); + addMemberVariable("h", Ty, {ResourceClassAttr, ResourceAttr}, Access); return *this; } @@ -489,9 +488,8 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV) { return BuiltinTypeDeclBuilder(Decl) - .addHandleMember() - .addDefaultHandleConstructor(S, RC) - .annotateHLSLResource(RC, RK, IsROV); + .addHandleMember(RC, RK, IsROV) + .addDefaultHandleConstructor(S, RC); } void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl index e95acb8896ba4..1f6ef60e121ea 100644 --- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl @@ -30,9 +30,9 @@ RWBuffer Buffer; // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <> implicit class RWBuffer definition // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final +// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit h 'element_type *' // CHECK-NEXT: HLSLResourceClassAttr 0x{{[0-9A-Fa-f]+}} <> Implicit UAV // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit TypedBuffer -// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit h 'element_type *' // CHECK: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'element_type &const (unsigned int) const' // CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Idx 'unsigned int' @@ -59,6 +59,6 @@ RWBuffer Buffer; // CHECK: TemplateArgument type 'float' // CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float' // CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final +// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit referenced h 'float *' // CHECK-NEXT: HLSLResourceClassAttr 0x{{[0-9A-Fa-f]+}} <> Implicit UAV // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit TypedBuffer -// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit referenced h 'float *' diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl new file mode 100644 index 0000000000000..6b7bcbc35b8f8 --- /dev/null +++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s | FileCheck %s + +// CHECK: -ClassTemplateDecl 0x{{[0-9a-f]+}} <> implicit RWBuffer +// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} <> implicit class RWBuffer definition +// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <> implicit h 'element_type *' +// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <> Implicit UAV +// CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <> Implicit TypedBuffer +RasterizerOrderedBuffer > BufferArray3[4] : register(u4, space1); + +// CHECK: -ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <> class RWBuffer definition implicit_instantiation +// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <> implicit referenced h 'float *' +// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <> Implicit UAV +// CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <> Implicit TypedBuffer +RWBuffer Buffer1;