Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -6168,10 +6168,18 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
struct Attributes {
// Data gathered from HLSL resource attributes
llvm::dxil::ResourceClass ResourceClass;

LLVM_PREFERRED_TYPE(bool)
uint8_t IsROV : 1;
Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV)
: ResourceClass(ResourceClass), IsROV(IsROV) {}
Attributes() : ResourceClass(llvm::dxil::ResourceClass::UAV), IsROV(0) {}

LLVM_PREFERRED_TYPE(bool)
uint8_t RawBuffer : 1;

Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV,
bool RawBuffer)
: ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {}

Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {}
};

private:
Expand Down Expand Up @@ -6204,6 +6212,7 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
ID.AddPointer(Contained.getAsOpaquePtr());
ID.AddInteger(static_cast<uint32_t>(Attrs.ResourceClass));
ID.AddBoolean(Attrs.IsROV);
ID.AddBoolean(Attrs.RawBuffer);
}

static bool classof(const Type *T) {
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/AST/TypeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -697,14 +697,17 @@ let Class = HLSLAttributedResourceType in {
def : Property<"isROV", Bool> {
let Read = [{ node->getAttrs().IsROV }];
}
def : Property<"rawBuffer", Bool> {
let Read = [{ node->getAttrs().RawBuffer }];
}
def : Property<"wrappedTy", QualType> {
let Read = [{ node->getWrappedType() }];
}
def : Property<"containedTy", QualType> {
let Read = [{ node->getContainedType() }];
}
def : Creator<[{
HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV);
HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rawBuffer);
return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs);
}]>;
}
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -4674,6 +4674,12 @@ def HLSLContainedType : TypeAttr {
let Documentation = [InternalOnly];
}

def HLSLRawBuffer : TypeAttr {
let Spellings = [CXX11<"hlsl", "raw_buffer">];
let LangOpts = [HLSL];
let Documentation = [InternalOnly];
}

def HLSLGroupSharedAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"groupshared">];
let Subjects = SubjectList<[Var]>;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/ASTStructuralEquivalence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -808,8 +808,8 @@ static bool
IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
const HLSLAttributedResourceType::Attributes &Attrs1,
const HLSLAttributedResourceType::Attributes &Attrs2) {
return std::tie(Attrs1.ResourceClass, Attrs1.IsROV) ==
std::tie(Attrs2.ResourceClass, Attrs2.IsROV);
return std::tie(Attrs1.ResourceClass, Attrs1.IsROV, Attrs1.RawBuffer) ==
std::tie(Attrs2.ResourceClass, Attrs2.IsROV, Attrs2.RawBuffer);
}

/// Determine structural equivalence of two types.
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,

case attr::HLSLResourceClass:
case attr::HLSLROV:
case attr::HLSLRawBuffer:
case attr::HLSLContainedType:
llvm_unreachable("HLSL resource type attributes handled separately");

Expand Down Expand Up @@ -2079,6 +2080,8 @@ void TypePrinter::printHLSLAttributedResourceAfter(
<< ")]]";
if (Attrs.IsROV)
OS << " [[hlsl::is_rov]]";
if (Attrs.RawBuffer)
OS << " [[hlsl::raw_buffer]]";

QualType ContainedTy = T->getContainedType();
if (!ContainedTy.isNull()) {
Expand Down
18 changes: 11 additions & 7 deletions clang/lib/Sema/HLSLExternalSemaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ struct BuiltinTypeDeclBuilder {

BuiltinTypeDeclBuilder &
addHandleMember(Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV,
bool RawBuffer,
AccessSpecifier Access = AccessSpecifier::AS_private) {
if (Record->isCompleteDefinition())
return *this;
Expand All @@ -135,10 +136,11 @@ struct BuiltinTypeDeclBuilder {
SmallVector<const Attr *> Attrs = {
HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC),
IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr,
RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Record->getASTContext())
: nullptr,
ElementTypeInfo ? HLSLContainedTypeAttr::CreateImplicit(
Record->getASTContext(), ElementTypeInfo)
: nullptr,
};
: nullptr};
Attr *ResourceAttr =
HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK);
if (CreateHLSLAttributedResourceType(S, Ty, Attrs, AttributedResTy))
Expand Down Expand Up @@ -507,9 +509,9 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
/// Set up common members and attributes for buffer types
static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
ResourceClass RC, ResourceKind RK,
bool IsROV) {
bool IsROV, bool RawBuffer) {
return BuiltinTypeDeclBuilder(Decl)
.addHandleMember(S, RC, RK, IsROV)
.addHandleMember(S, RC, RK, IsROV, RawBuffer)
.addDefaultHandleConstructor(S, RC);
}

Expand All @@ -522,7 +524,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
ResourceKind::TypedBuffer,
/*IsROV=*/false)
/*IsROV=*/false, /*RawBuffer=*/false)
.addArraySubscriptOperators()
.completeDefinition();
});
Expand All @@ -533,7 +535,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.Record;
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
ResourceKind::TypedBuffer, /*IsROV=*/true)
ResourceKind::TypedBuffer, /*IsROV=*/true,
/*RawBuffer=*/false)
.addArraySubscriptOperators()
.completeDefinition();
});
Expand All @@ -543,7 +546,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.Record;
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
ResourceKind::TypedBuffer, /*IsROV=*/false)
ResourceKind::TypedBuffer, /*IsROV=*/false,
/*RawBuffer=*/true)
.addArraySubscriptOperators()
.completeDefinition();
});
Expand Down
13 changes: 12 additions & 1 deletion clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ bool clang::CreateHLSLAttributedResourceType(
SourceLocation LocBegin = AttrList[0]->getRange().getBegin();
SourceLocation LocEnd = AttrList[0]->getRange().getEnd();

HLSLAttributedResourceType::Attributes ResAttrs = {};
HLSLAttributedResourceType::Attributes ResAttrs;

bool HasResourceClass = false;
for (const Attr *A : AttrList) {
Expand Down Expand Up @@ -606,6 +606,13 @@ bool clang::CreateHLSLAttributedResourceType(
}
ResAttrs.IsROV = true;
break;
case attr::HLSLRawBuffer:
if (ResAttrs.RawBuffer) {
S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
return false;
}
ResAttrs.RawBuffer = true;
break;
case attr::HLSLContainedType: {
const HLSLContainedTypeAttr *CTAttr = cast<HLSLContainedTypeAttr>(A);
QualType Ty = CTAttr->getType();
Expand Down Expand Up @@ -679,6 +686,10 @@ bool SemaHLSL::handleResourceTypeAttr(const ParsedAttr &AL) {
A = HLSLROVAttr::Create(getASTContext(), AL.getLoc());
break;

case ParsedAttr::AT_HLSLRawBuffer:
A = HLSLRawBufferAttr::Create(getASTContext(), AL.getLoc());
break;

case ParsedAttr::AT_HLSLContainedType: {
if (AL.getNumArgs() != 1 && !AL.hasParsedType()) {
Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8846,6 +8846,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
}
case ParsedAttr::AT_HLSLResourceClass:
case ParsedAttr::AT_HLSLROV:
case ParsedAttr::AT_HLSLRawBuffer:
case ParsedAttr::AT_HLSLContainedType: {
// Only collect HLSL resource type attributes that are in
// decl-specifier-seq; do not collect attributes on declarations or those
Expand Down
8 changes: 4 additions & 4 deletions clang/test/AST/HLSL/StructuredBuffer-AST.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ StructuredBuffer<float> Buffer;
// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class StructuredBuffer definition

// CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::contained_type(element_type)]]':'element_type *'
// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]] {{\[\[}}hlsl::contained_type(element_type)]]':'element_type *'
// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer

// CHECK: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &const (unsigned int) const'
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Idx 'unsigned int'
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
// CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::contained_type(element_type)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]] {{\[\[}}hlsl::contained_type(element_type)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const StructuredBuffer<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
Expand All @@ -48,7 +48,7 @@ StructuredBuffer<float> Buffer;
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
// CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::contained_type(element_type)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]] {{\[\[}}hlsl::contained_type(element_type)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'StructuredBuffer<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
Expand All @@ -58,5 +58,5 @@ StructuredBuffer<float> Buffer;
// CHECK: TemplateArgument type 'float'
// CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float'
// CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::contained_type(float)]]':'float *'
// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]] {{\[\[}}hlsl::contained_type(float)]]':'float *'
// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer
16 changes: 16 additions & 0 deletions clang/test/ParserHLSL/hlsl_raw_buffer_attr.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s

// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} struct MyBuffer definition
// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:6:3, col:72> col:72 h1 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'__hlsl_resource_t'
struct MyBuffer {
__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer]] h1;
};

// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:10:1, col:70> col:70 h2 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(SRV)]] {{\[\[}}hlsl::raw_buffer]]':'__hlsl_resource_t'
__hlsl_resource_t [[hlsl::raw_buffer]] [[hlsl::resource_class(SRV)]] h2;

// CHECK: FunctionDecl 0x{{[0-9a-f]+}} <line:14:1, line:16:1> line:14:6 f 'void ()
// CHECK: VarDecl 0x{{[0-9a-f]+}} <col:3, col:72> col:72 h3 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'__hlsl_resource_t'
void f() {
__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer]] h3;
}
13 changes: 13 additions & 0 deletions clang/test/ParserHLSL/hlsl_raw_buffer_attr_error.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify

// expected-error@+1{{'raw_buffer' attribute cannot be applied to a declaration}}
[[hlsl::raw_buffer]] __hlsl_resource_t res0;

// expected-error@+1{{'raw_buffer' attribute takes no arguments}}
__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer(3)]] res2;

// expected-error@+1{{use of undeclared identifier 'gibberish'}}
__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer(gibberish)]] res3;

// expected-warning@+1{{attribute 'raw_buffer' is already applied}}
__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer]] [[hlsl::raw_buffer]] res4;