Skip to content

Commit 8e35c86

Browse files
authored
[HLSL] Apply resource attributes to the resource type rather than the handle member (#107160)
Converts existing resource attributes `[[hlsl::resource_class(..)]]` and `[[is_rov]]` from declaration attributes to type attributes. During type attribute processing all HLSL resource type attributes are validated and collected by `SemaHLSL` (`SemaHLSL::handleResourceTypeAttr`). At the end of the declaration they are be combined into a single `HLSLAttributedResourceType` instance (`SemaHLSL::ProcessResourceTypeAttributes`) that wraps the original type and stores all of the necessary information about the resource. `SemaHLSL` will also need to short-term-store the `TypeLoc` information for the newly created type that will be grabbed by `TypeSpecLocFiller` soon after it is created. Updates all places that expected resource attributes on declarations like resource binding diagnostic, builtin types in HLSLExternalSemaSource, or codegen. Also includes implementation of `TreeTransform<Derived>::TransformHLSLAttributedResourceType` that enables the use of attributed resource types inside templates. Fixes #104861 Part 2/2
1 parent ede40da commit 8e35c86

20 files changed

+281
-168
lines changed

clang/include/clang/AST/TypeLoc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,12 +951,20 @@ class HLSLAttributedResourceTypeLoc
951951
HLSLAttributedResourceLocInfo> {
952952
public:
953953
TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); }
954+
955+
TypeLoc getContainedLoc() const {
956+
return TypeLoc(getTypePtr()->getContainedType(), getNonLocalData());
957+
}
958+
954959
void setSourceRange(const SourceRange &R) { getLocalData()->Range = R; }
955960
SourceRange getLocalSourceRange() const { return getLocalData()->Range; }
956961
void initializeLocal(ASTContext &Context, SourceLocation loc) {
957962
setSourceRange(SourceRange());
958963
}
959964
QualType getInnerType() const { return getTypePtr()->getWrappedType(); }
965+
unsigned getLocalDataSize() const {
966+
return sizeof(HLSLAttributedResourceLocInfo);
967+
}
960968
};
961969

962970
struct ObjCObjectTypeLocInfo {

clang/include/clang/Basic/Attr.td

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4643,16 +4643,14 @@ def HLSLResource : InheritableAttr {
46434643
let Documentation = [InternalOnly];
46444644
}
46454645

4646-
def HLSLROV : InheritableAttr {
4646+
def HLSLROV : TypeAttr {
46474647
let Spellings = [CXX11<"hlsl", "is_rov">];
4648-
let Subjects = SubjectList<[Struct]>;
46494648
let LangOpts = [HLSL];
46504649
let Documentation = [InternalOnly];
46514650
}
46524651

4653-
def HLSLResourceClass : InheritableAttr {
4652+
def HLSLResourceClass : TypeAttr {
46544653
let Spellings = [CXX11<"hlsl", "resource_class">];
4655-
let Subjects = SubjectList<[Field]>;
46564654
let LangOpts = [HLSL];
46574655
let Args = [
46584656
EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass",

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12368,6 +12368,7 @@ def err_hlsl_packoffset_cross_reg_boundary : Error<"packoffset cannot cross regi
1236812368
def err_hlsl_packoffset_alignment_mismatch : Error<"packoffset at 'y' not match alignment %0 required by %1">;
1236912369
def err_hlsl_pointers_unsupported : Error<
1237012370
"%select{pointers|references}0 are unsupported in HLSL">;
12371+
def err_hlsl_missing_resource_class : Error<"HLSL resource needs to have [[hlsl::resource_class()]] attribute">;
1237112372

1237212373
def err_hlsl_operator_unsupported : Error<
1237312374
"the '%select{&|*|->}0' operator is unsupported in HLSL">;

clang/include/clang/Sema/SemaHLSL.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515

1616
#include "clang/AST/ASTFwd.h"
1717
#include "clang/AST/Attr.h"
18+
#include "clang/AST/Type.h"
1819
#include "clang/Basic/SourceLocation.h"
1920
#include "clang/Sema/SemaBase.h"
21+
#include "llvm/ADT/SmallVector.h"
2022
#include "llvm/TargetParser/Triple.h"
2123
#include <initializer_list>
2224

@@ -26,6 +28,12 @@ class IdentifierInfo;
2628
class ParsedAttr;
2729
class Scope;
2830

31+
// FIXME: This can be hidden (as static function in SemaHLSL.cpp) once we no
32+
// longer need to create builtin buffer types in HLSLExternalSemaSource.
33+
bool CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped,
34+
ArrayRef<const Attr *> AttrList,
35+
QualType &ResType);
36+
2937
class SemaHLSL : public SemaBase {
3038
public:
3139
SemaHLSL(Sema &S);
@@ -59,8 +67,6 @@ class SemaHLSL : public SemaBase {
5967
void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL);
6068
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
6169
void handleShaderAttr(Decl *D, const ParsedAttr &AL);
62-
void handleROVAttr(Decl *D, const ParsedAttr &AL);
63-
void handleResourceClassAttr(Decl *D, const ParsedAttr &AL);
6470
void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL);
6571
void handleParamModifierAttr(Decl *D, const ParsedAttr &AL);
6672
bool handleResourceTypeAttr(const ParsedAttr &AL);
@@ -78,6 +84,16 @@ class SemaHLSL : public SemaBase {
7884
ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg);
7985

8086
QualType getInoutParameterType(QualType Ty);
87+
88+
private:
89+
// HLSL resource type attributes need to be processed all at once.
90+
// This is a list to collect them.
91+
llvm::SmallVector<const Attr *> HLSLResourcesTypeAttrs;
92+
93+
/// SourceLocation corresponding to HLSLAttributedResourceTypeLocs that we
94+
/// have not yet populated.
95+
llvm::DenseMap<const HLSLAttributedResourceType *, SourceLocation>
96+
LocsForHLSLAttributedResources;
8197
};
8298

8399
} // namespace clang

clang/lib/AST/TypePrinter.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,10 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
19421942
case attr::BTFTypeTag:
19431943
llvm_unreachable("BTFTypeTag attribute handled separately");
19441944

1945+
case attr::HLSLResourceClass:
1946+
case attr::HLSLROV:
1947+
llvm_unreachable("HLSL resource type attributes handled separately");
1948+
19451949
case attr::OpenCLPrivateAddressSpace:
19461950
case attr::OpenCLGlobalAddressSpace:
19471951
case attr::OpenCLGlobalDeviceAddressSpace:
@@ -2062,7 +2066,11 @@ void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
20622066
void TypePrinter::printHLSLAttributedResourceBefore(
20632067
const HLSLAttributedResourceType *T, raw_ostream &OS) {
20642068
printBefore(T->getWrappedType(), OS);
2069+
}
20652070

2071+
void TypePrinter::printHLSLAttributedResourceAfter(
2072+
const HLSLAttributedResourceType *T, raw_ostream &OS) {
2073+
printAfter(T->getWrappedType(), OS);
20662074
const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
20672075
OS << " [[hlsl::resource_class("
20682076
<< HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
@@ -2071,11 +2079,6 @@ void TypePrinter::printHLSLAttributedResourceBefore(
20712079
OS << " [[hlsl::is_rov()]]";
20722080
}
20732081

2074-
void TypePrinter::printHLSLAttributedResourceAfter(
2075-
const HLSLAttributedResourceType *T, raw_ostream &OS) {
2076-
printAfter(T->getWrappedType(), OS);
2077-
}
2078-
20792082
void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
20802083
raw_ostream &OS) {
20812084
OS << T->getDecl()->getName();

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,14 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) {
295295
// inside the record decl
296296
for (auto *FD : RD->fields()) {
297297
const auto *HLSLResAttr = FD->getAttr<HLSLResourceAttr>();
298-
const auto *HLSLResClassAttr = FD->getAttr<HLSLResourceClassAttr>();
299-
if (!HLSLResAttr || !HLSLResClassAttr)
298+
const HLSLAttributedResourceType *AttrResType =
299+
dyn_cast<HLSLAttributedResourceType>(FD->getType().getTypePtr());
300+
if (!HLSLResAttr || !AttrResType)
300301
continue;
301302

302-
llvm::hlsl::ResourceClass RC = HLSLResClassAttr->getResourceClass();
303+
llvm::hlsl::ResourceClass RC = AttrResType->getAttrs().ResourceClass;
304+
bool IsROV = AttrResType->getAttrs().IsROV;
303305
llvm::hlsl::ResourceKind RK = HLSLResAttr->getResourceKind();
304-
bool IsROV = FD->hasAttr<HLSLROVAttr>();
305306
llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty);
306307

307308
BufferResBinding Binding(D->getAttr<HLSLResourceBindingAttr>());

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
#include "clang/AST/ASTContext.h"
1414
#include "clang/AST/Attr.h"
1515
#include "clang/AST/DeclCXX.h"
16+
#include "clang/AST/Type.h"
1617
#include "clang/Basic/AttrKinds.h"
1718
#include "clang/Basic/HLSLRuntime.h"
1819
#include "clang/Sema/Lookup.h"
1920
#include "clang/Sema/Sema.h"
21+
#include "clang/Sema/SemaHLSL.h"
22+
#include "llvm/ADT/SmallVector.h"
2023
#include "llvm/Frontend/HLSL/HLSLResource.h"
2124

2225
#include <functional>
@@ -107,7 +110,7 @@ struct BuiltinTypeDeclBuilder {
107110
}
108111

109112
BuiltinTypeDeclBuilder &
110-
addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV,
113+
addHandleMember(Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV,
111114
AccessSpecifier Access = AccessSpecifier::AS_private) {
112115
if (Record->isCompleteDefinition())
113116
return *this;
@@ -118,16 +121,16 @@ struct BuiltinTypeDeclBuilder {
118121
Ty = Record->getASTContext().getPointerType(
119122
QualType(TTD->getTypeForDecl(), 0));
120123
}
121-
// add handle member
122-
Attr *ResourceClassAttr =
123-
HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC);
124+
125+
// add handle member with resource type attributes
126+
QualType AttributedResTy = QualType();
127+
SmallVector<const Attr *> Attrs = {
128+
HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC),
129+
IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr};
124130
Attr *ResourceAttr =
125131
HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK);
126-
Attr *ROVAttr =
127-
IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr;
128-
addMemberVariable("h", Ty, {ResourceClassAttr, ResourceAttr, ROVAttr},
129-
Access);
130-
132+
if (CreateHLSLAttributedResourceType(S, Ty, Attrs, AttributedResTy))
133+
addMemberVariable("h", AttributedResTy, {ResourceAttr}, Access);
131134
return *this;
132135
}
133136

@@ -494,7 +497,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
494497
ResourceClass RC, ResourceKind RK,
495498
bool IsROV) {
496499
return BuiltinTypeDeclBuilder(Decl)
497-
.addHandleMember(RC, RK, IsROV)
500+
.addHandleMember(S, RC, RK, IsROV)
498501
.addDefaultHandleConstructor(S, RC);
499502
}
500503

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6907,12 +6907,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
69076907
case ParsedAttr::AT_HLSLResourceBinding:
69086908
S.HLSL().handleResourceBindingAttr(D, AL);
69096909
break;
6910-
case ParsedAttr::AT_HLSLROV:
6911-
handleSimpleAttribute<HLSLROVAttr>(S, D, AL);
6912-
break;
6913-
case ParsedAttr::AT_HLSLResourceClass:
6914-
S.HLSL().handleResourceClassAttr(D, AL);
6915-
break;
69166910
case ParsedAttr::AT_HLSLParamModifier:
69176911
S.HLSL().handleParamModifierAttr(D, AL);
69186912
break;

0 commit comments

Comments
 (0)