https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/107160
>From 337a9ed1d5e7c71fb5be5741afe7726f5b76af7b Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Tue, 3 Sep 2024 15:30:50 -0700 Subject: [PATCH 1/4] [HLSL] Apply resource attributes to the resource type rather than the handle member (#6) --- clang/include/clang/AST/TypeLoc.h | 8 + clang/include/clang/Basic/Attr.td | 6 +- .../clang/Basic/DiagnosticSemaKinds.td | 1 + clang/include/clang/Sema/SemaHLSL.h | 21 ++- clang/lib/AST/TypePrinter.cpp | 9 +- clang/lib/CodeGen/CGHLSLRuntime.cpp | 10 +- clang/lib/Sema/HLSLExternalSemaSource.cpp | 25 ++- clang/lib/Sema/SemaDeclAttr.cpp | 6 - clang/lib/Sema/SemaHLSL.cpp | 177 ++++++++++++------ clang/lib/Sema/TreeTransform.h | 22 ++- clang/test/AST/HLSL/RWBuffer-AST.hlsl | 10 +- ...a-attribute-supported-attributes-list.test | 2 - clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl | 17 +- .../ParserHLSL/hlsl_is_rov_attr_error.hlsl | 21 ++- .../ParserHLSL/hlsl_resource_class_attr.hlsl | 48 ++--- .../hlsl_resource_class_attr_error.hlsl | 29 +-- .../hlsl_resource_handle_attrs.hlsl | 17 +- .../SemaHLSL/resource_binding_attr_error.hlsl | 2 +- .../resource_binding_attr_error_resource.hlsl | 10 +- .../resource_binding_attr_error_udt.hlsl | 10 +- 20 files changed, 284 insertions(+), 167 deletions(-) diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 5db39eb3aefa74..03fbdcf60140df 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -951,12 +951,20 @@ class HLSLAttributedResourceTypeLoc HLSLAttributedResourceLocInfo> { public: TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); } + + TypeLoc getContainedLoc() const { + return TypeLoc(getTypePtr()->getContainedType(), getNonLocalData()); + } + void setSourceRange(const SourceRange &R) { getLocalData()->Range = R; } SourceRange getLocalSourceRange() const { return getLocalData()->Range; } void initializeLocal(ASTContext &Context, SourceLocation loc) { setSourceRange(SourceRange()); } QualType getInnerType() const { return getTypePtr()->getWrappedType(); } + unsigned getLocalDataSize() const { + return sizeof(HLSLAttributedResourceLocInfo); + } }; struct ObjCObjectTypeLocInfo { diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 8d2a362abc3c32..0c98f8e25a6fbb 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4643,16 +4643,14 @@ def HLSLResource : InheritableAttr { let Documentation = [InternalOnly]; } -def HLSLROV : InheritableAttr { +def HLSLROV : TypeAttr { let Spellings = [CXX11<"hlsl", "is_rov">]; - let Subjects = SubjectList<[Struct]>; let LangOpts = [HLSL]; let Documentation = [InternalOnly]; } -def HLSLResourceClass : InheritableAttr { +def HLSLResourceClass : TypeAttr { let Spellings = [CXX11<"hlsl", "resource_class">]; - let Subjects = SubjectList<[Field]>; let LangOpts = [HLSL]; let Args = [ EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass", diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dcb49d8a67604a..4f522f68f080aa 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12364,6 +12364,7 @@ def err_hlsl_packoffset_cross_reg_boundary : Error<"packoffset cannot cross regi def err_hlsl_packoffset_alignment_mismatch : Error<"packoffset at 'y' not match alignment %0 required by %1">; def err_hlsl_pointers_unsupported : Error< "%select{pointers|references}0 are unsupported in HLSL">; +def err_missing_resource_class : Error<"HLSL resource needs to have [[hlsl::resource_class()]] attribute">; def err_hlsl_operator_unsupported : Error< "the '%select{&|*|->}0' operator is unsupported in HLSL">; diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index d79ca9a4fa18d1..5131458863e20b 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -15,8 +15,11 @@ #include "clang/AST/ASTFwd.h" #include "clang/AST/Attr.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/SemaBase.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/TargetParser/Triple.h" #include <initializer_list> @@ -59,8 +62,6 @@ class SemaHLSL : public SemaBase { void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL); void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL); void handleShaderAttr(Decl *D, const ParsedAttr &AL); - void handleROVAttr(Decl *D, const ParsedAttr &AL); - void handleResourceClassAttr(Decl *D, const ParsedAttr &AL); void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL); void handleParamModifierAttr(Decl *D, const ParsedAttr &AL); bool handleResourceTypeAttr(const ParsedAttr &AL); @@ -77,6 +78,22 @@ class SemaHLSL : public SemaBase { ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg); QualType getInoutParameterType(QualType Ty); + + // FIXME: This can be hidden (as static function in SemaHLSL.cpp) once we no + // longer need to create builtin buffer types in HLSLExternalSemaSource. + static bool + CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, + llvm::SmallVector<const Attr *> &AttrList, + QualType &ResType); + +private: + // HLSL resource type attributes need to be processed all at once. + // This is a list to collect them. + llvm::SmallVector<const Attr*> HLSLResourcesTypeAttrs; + + /// SourceRanges corresponding to HLSLAttributedResourceTypeLocs that we have not yet populated. + llvm::DenseMap<const HLSLAttributedResourceType *, SourceLocation> + LocsForHLSLAttributedResources; }; } // namespace clang diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index b1d9516c96eb7a..27b251a5575855 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1942,6 +1942,10 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::BTFTypeTag: llvm_unreachable("BTFTypeTag attribute handled separately"); + case attr::HLSLResourceClass: + case attr::HLSLROV: + llvm_unreachable("HLSL resource type attributes handled separately"); + case attr::OpenCLPrivateAddressSpace: case attr::OpenCLGlobalAddressSpace: case attr::OpenCLGlobalDeviceAddressSpace: @@ -2062,6 +2066,7 @@ void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T, void TypePrinter::printHLSLAttributedResourceBefore( const HLSLAttributedResourceType *T, raw_ostream &OS) { printBefore(T->getWrappedType(), OS); + printAfter(T->getWrappedType(), OS); const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs(); OS << " [[hlsl::resource_class(" @@ -2072,9 +2077,7 @@ void TypePrinter::printHLSLAttributedResourceBefore( } void TypePrinter::printHLSLAttributedResourceAfter( - const HLSLAttributedResourceType *T, raw_ostream &OS) { - printAfter(T->getWrappedType(), OS); -} + const HLSLAttributedResourceType *T, raw_ostream &OS) {} void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T, raw_ostream &OS) { diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 4bd7b6ba58de0d..0abca7b000d177 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -17,6 +17,7 @@ #include "CodeGenModule.h" #include "TargetInfo.h" #include "clang/AST/Decl.h" +#include "clang/AST/Type.h" #include "clang/Basic/TargetOptions.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -295,13 +296,14 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) { // inside the record decl for (auto *FD : RD->fields()) { const auto *HLSLResAttr = FD->getAttr<HLSLResourceAttr>(); - const auto *HLSLResClassAttr = FD->getAttr<HLSLResourceClassAttr>(); - if (!HLSLResAttr || !HLSLResClassAttr) + const HLSLAttributedResourceType *AttrResType = + dyn_cast<HLSLAttributedResourceType>(FD->getType().getTypePtr()); + if (!HLSLResAttr || !AttrResType) continue; - llvm::hlsl::ResourceClass RC = HLSLResClassAttr->getResourceClass(); + llvm::hlsl::ResourceClass RC = AttrResType->getAttrs().ResourceClass; + bool IsROV = AttrResType->getAttrs().IsROV; llvm::hlsl::ResourceKind RK = HLSLResAttr->getResourceKind(); - bool IsROV = FD->hasAttr<HLSLROVAttr>(); llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty); BufferResBinding Binding(D->getAttr<HLSLResourceBindingAttr>()); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 9aacbe4ad9548e..07164069336dbd 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -13,10 +13,13 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/HLSLRuntime.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/SemaHLSL.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Frontend/HLSL/HLSLResource.h" #include <functional> @@ -107,7 +110,7 @@ struct BuiltinTypeDeclBuilder { } BuiltinTypeDeclBuilder & - addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV, + addHandleMember(Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV, AccessSpecifier Access = AccessSpecifier::AS_private) { if (Record->isCompleteDefinition()) return *this; @@ -118,16 +121,18 @@ struct BuiltinTypeDeclBuilder { Ty = Record->getASTContext().getPointerType( QualType(TTD->getTypeForDecl(), 0)); } - // add handle member - Attr *ResourceClassAttr = - HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC); + + // add handle member with resource type attributes + QualType AttributedResTy = QualType(); + SmallVector<const Attr*> Attrs = { + HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC), + IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr + }; Attr *ResourceAttr = HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK); - Attr *ROVAttr = - IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr; - addMemberVariable("h", Ty, {ResourceClassAttr, ResourceAttr, ROVAttr}, - Access); - + if (SemaHLSL::CreateHLSLAttributedResourceType(S, Ty, Attrs, AttributedResTy)) { + addMemberVariable("h", AttributedResTy, {ResourceAttr}, Access); + } return *this; } @@ -494,7 +499,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV) { return BuiltinTypeDeclBuilder(Decl) - .addHandleMember(RC, RK, IsROV) + .addHandleMember(S, RC, RK, IsROV) .addDefaultHandleConstructor(S, RC); } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 33547c2e6e1452..d068cb6a78f266 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6907,12 +6907,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_HLSLResourceBinding: S.HLSL().handleResourceBindingAttr(D, AL); break; - case ParsedAttr::AT_HLSLROV: - handleSimpleAttribute<HLSLROVAttr>(S, D, AL); - break; - case ParsedAttr::AT_HLSLResourceClass: - S.HLSL().handleResourceClassAttr(D, AL); - break; case ParsedAttr::AT_HLSLParamModifier: S.HLSL().handleParamModifierAttr(D, AL); break; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 778d524a005482..69f4382e465300 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -9,9 +9,12 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaHLSL.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Type.h" +#include "clang/Basic/AttrKinds.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" @@ -19,7 +22,9 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/ParsedAttr.h" #include "clang/Sema/Sema.h" +#include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" @@ -27,6 +32,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/TargetParser/Triple.h" #include <iterator> +#include <utility> using namespace clang; @@ -556,46 +562,113 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } -void SemaHLSL::handleResourceClassAttr(Decl *D, const ParsedAttr &AL) { - if (!AL.isArgIdent(0)) { - Diag(AL.getLoc(), diag::err_attribute_argument_type) - << AL << AANT_ArgumentIdentifier; - return; - } +bool SemaHLSL::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, llvm::SmallVector<const Attr *> &AttrList, QualType &ResType) { + assert(AttrList.size() && "expected list of resource attributes"); - IdentifierLoc *Loc = AL.getArgAsIdent(0); - StringRef Identifier = Loc->Ident->getName(); - SourceLocation ArgLoc = Loc->Loc; + QualType Contained = QualType(); + HLSLAttributedResourceType::Attributes ResAttrs = {}; - // Validate. - llvm::dxil::ResourceClass RC; - if (!HLSLResourceClassAttr::ConvertStrToResourceClass(Identifier, RC)) { - Diag(ArgLoc, diag::warn_attribute_type_not_supported) - << "ResourceClass" << Identifier; - return; + bool hasResourceClass = false; + for (auto *Attr : AttrList) { + if (!Attr) + continue; + switch (Attr->getKind()) { + case attr::HLSLResourceClass: { + llvm::dxil::ResourceClass RC = dyn_cast<HLSLResourceClassAttr>(Attr)->getResourceClass(); + if (!hasResourceClass) { + ResAttrs.ResourceClass = RC; + hasResourceClass = true; + } else if (RC != ResAttrs.ResourceClass) { + S.Diag(Attr->getLocation(), diag::warn_duplicate_attribute) << Attr; + return false; + } + break; + } + case attr::HLSLROV: + ResAttrs.IsROV = true; + break; + default: + llvm_unreachable("unhandled resource attribute type"); + } + } + + if (!hasResourceClass) { + S.Diag(AttrList.back()->getRange().getEnd(), diag::err_missing_resource_class); + return false; } - D->addAttr(HLSLResourceClassAttr::Create(getASTContext(), RC, ArgLoc)); + ResType = S.getASTContext().getHLSLAttributedResourceType(Wrapped, Contained, ResAttrs); + return true; } -// Validates HLSL resource type attribute and adds it to the list to be -// processed into a single HLSLAttributedResourceType later on. -// Returns false if the attribute is invalid. +// Validates and creates an HLSL attribute that is applied as type attribute on +// HLSL resource. The attributes are collected in HLSLResourcesAttrs and at the +// end of the declaration they are applied to the declaration type by wrapping +// it in HLSLAttributedResourceType. bool SemaHLSL::handleResourceTypeAttr(const ParsedAttr &AL) { - // FIXME: placeholder - not yet implemented + Attr *A = nullptr; + + // validate number of arguments + if (!AL.checkExactlyNumArgs(SemaRef, AL.getMinArgs())) + return false; + + switch (AL.getKind()) { + case ParsedAttr::AT_HLSLResourceClass: { + if (!AL.isArgIdent(0)) { + Diag(AL.getLoc(), diag::err_attribute_argument_type) + << AL << AANT_ArgumentIdentifier; + return false; + } + + IdentifierLoc *Loc = AL.getArgAsIdent(0); + StringRef Identifier = Loc->Ident->getName(); + SourceLocation ArgLoc = Loc->Loc; + + // Validate resource class value + llvm::dxil::ResourceClass RC; + if (!HLSLResourceClassAttr::ConvertStrToResourceClass(Identifier, RC)) { + Diag(ArgLoc, diag::warn_attribute_type_not_supported) + << "ResourceClass" << Identifier; + return false; + } + A = HLSLResourceClassAttr::Create(getASTContext(), RC, AL.getLoc()); + break; + } + case ParsedAttr::AT_HLSLROV: + A = HLSLROVAttr::Create(getASTContext(), AL.getLoc()); + break; + default: + llvm_unreachable("unhandled HLSL attribute"); + } + + HLSLResourcesTypeAttrs.emplace_back(A); return true; } -// Combines all resource type attributes and create HLSLAttributedResourceType. +// Combines all resource type attributes and creates HLSLAttributedResourceType. QualType SemaHLSL::ProcessResourceTypeAttributes(QualType CurrentType) { - // FIXME: placeholder - not yet implemented - return CurrentType; + if (!HLSLResourcesTypeAttrs.size()) + return CurrentType; + + QualType QT = CurrentType; + if (CreateHLSLAttributedResourceType(SemaRef, CurrentType, HLSLResourcesTypeAttrs, QT)) { + const HLSLAttributedResourceType *RT = dyn_cast<HLSLAttributedResourceType>(QT.getTypePtr()); + SourceLocation Loc = HLSLResourcesTypeAttrs[0]->getLoc(); + LocsForHLSLAttributedResources.insert(std::pair(RT, Loc)); + } + HLSLResourcesTypeAttrs.clear(); + return QT; } // Returns source location for the HLSLAttributedResourceType SourceLocation SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) { - // FIXME: placeholder - not yet implemented + auto I = LocsForHLSLAttributedResources.find(RT); + if (I != LocsForHLSLAttributedResources.end()) { + SourceLocation Loc = I->second; + LocsForHLSLAttributedResources.erase(RT); + return Loc; + } return SourceLocation(); } @@ -653,33 +726,18 @@ static void updateResourceClassFlagsFromDeclResourceClass( } } -template <typename T> -static const T *getSpecifiedHLSLAttrFromRecordDecl(RecordDecl *TheRecordDecl) { - if (!TheRecordDecl) - return nullptr; - - if (TheRecordDecl->hasAttr<T>()) - return TheRecordDecl->getAttr<T>(); - for (auto *FD : TheRecordDecl->fields()) { - const T *Attr = FD->getAttr<T>(); - if (Attr) - return Attr; +const HLSLAttributedResourceType *findAttributedResourceTypeOnField(VarDecl *VD) { + assert(VD != nullptr && "expected VarDecl"); + if (RecordDecl *RD = getRecordDeclFromVarDecl(VD)) { + for (auto *FD : RD->fields()) { + if (const HLSLAttributedResourceType *AttrResType = + dyn_cast<HLSLAttributedResourceType>(FD->getType().getTypePtr())) + return AttrResType; + } } return nullptr; } -template <typename T> -static const T *getSpecifiedHLSLAttrFromVarDecl(VarDecl *VD) { - RecordDecl *TheRecordDecl = nullptr; - if (VD) { - TheRecordDecl = getRecordDeclFromVarDecl(VD); - if (!TheRecordDecl) - return nullptr; - } - - return getSpecifiedHLSLAttrFromRecordDecl<T>(TheRecordDecl); -} - static void updateResourceClassFlagsFromRecordType(RegisterBindingFlags &Flags, const RecordType *RT) { llvm::SmallVector<const Type *> TypesToScan; @@ -699,10 +757,10 @@ static void updateResourceClassFlagsFromRecordType(RegisterBindingFlags &Flags, const RecordDecl *RD = RT->getDecl(); for (FieldDecl *FD : RD->fields()) { - if (HLSLResourceClassAttr *RCAttr = - FD->getAttr<HLSLResourceClassAttr>()) { - updateResourceClassFlagsFromDeclResourceClass( - Flags, RCAttr->getResourceClass()); + const Type *FieldTy = FD->getType().getTypePtr(); + if (const HLSLAttributedResourceType *AttrResType = + dyn_cast<HLSLAttributedResourceType>(FieldTy)) { + updateResourceClassFlagsFromDeclResourceClass(Flags, AttrResType->getAttrs().ResourceClass); continue; } TypesToScan.emplace_back(FD->getType().getTypePtr()); @@ -729,11 +787,10 @@ static RegisterBindingFlags HLSLFillRegisterBindingFlags(Sema &S, } // Samplers, UAVs, and SRVs are VarDecl types else if (VarDecl *TheVarDecl = dyn_cast<VarDecl>(TheDecl)) { - const HLSLResourceClassAttr *resClassAttr = - getSpecifiedHLSLAttrFromVarDecl<HLSLResourceClassAttr>(TheVarDecl); - if (resClassAttr) { + if (const HLSLAttributedResourceType *AttrResType = + findAttributedResourceTypeOnField(TheVarDecl)) { Flags.Resource = true; - Flags.ResourceClass = resClassAttr->getResourceClass(); + Flags.ResourceClass = AttrResType->getAttrs().ResourceClass; } else { const clang::Type *TheBaseType = TheVarDecl->getType().getTypePtr(); while (TheBaseType->isArrayType()) @@ -758,7 +815,15 @@ static RegisterBindingFlags HLSLFillRegisterBindingFlags(Sema &S, return Flags; } -enum class RegisterType { SRV, UAV, CBuffer, Sampler, C, I, Invalid }; +enum class RegisterType { + SRV = static_cast<int>(llvm::dxil::ResourceClass::SRV), + UAV = static_cast<int>(llvm::dxil::ResourceClass::UAV), + CBuffer = static_cast<int>(llvm::dxil::ResourceClass::CBuffer), + Sampler = static_cast<int>(llvm::dxil::ResourceClass::Sampler), + C, + I, + Invalid +}; static RegisterType getRegisterType(llvm::dxil::ResourceClass RC) { switch (RC) { diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 66e3f27fed9de0..06d3936b05b913 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7462,8 +7462,26 @@ QualType TreeTransform<Derived>::TransformBTFTagAttributedType( template <typename Derived> QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType( TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) { - llvm_unreachable( - "Unexpected TreeTransform for HLSLAttributedResourceTypeLoc"); + + const HLSLAttributedResourceType *oldType = TL.getTypePtr(); + + QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc()); + if (WrappedTy.isNull()) + return QualType(); + + QualType ContainedTy = QualType(); + if (!oldType->getContainedType().isNull()) + ContainedTy = getDerived().TransformType(TLB, TL.getContainedLoc()); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() || + ContainedTy != oldType->getContainedType()) { + Result = SemaRef.Context.getHLSLAttributedResourceType( + WrappedTy, ContainedTy, oldType->getAttrs()); + } + + TLB.push<HLSLAttributedResourceTypeLoc>(Result); + return Result; } template<typename Derived> diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl index 1f6ef60e121ea5..0e7803ce50a890 100644 --- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl +++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl @@ -30,8 +30,7 @@ RWBuffer<float> Buffer; // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer 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 *' -// CHECK-NEXT: HLSLResourceClassAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit UAV +// CHECK-NEXT: implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'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' @@ -39,7 +38,7 @@ RWBuffer<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 *' lvalue .h 0x{{[0-9A-Fa-f]+}} +// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}} // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const RWBuffer<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 @@ -49,7 +48,7 @@ RWBuffer<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 *' lvalue .h 0x{{[0-9A-Fa-f]+}} +// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}} // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWBuffer<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 @@ -59,6 +58,5 @@ RWBuffer<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 *' -// CHECK-NEXT: HLSLResourceClassAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit UAV +// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *' // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 5ebbd29b316bfa..eca86331149028 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -82,8 +82,6 @@ // CHECK-NEXT: FunctionReturnThunks (SubjectMatchRule_function) // CHECK-NEXT: GNUInline (SubjectMatchRule_function) // CHECK-NEXT: HIPManaged (SubjectMatchRule_variable) -// CHECK-NEXT: HLSLROV (SubjectMatchRule_record_not_is_union) -// CHECK-NEXT: HLSLResourceClass (SubjectMatchRule_field) // CHECK-NEXT: Hot (SubjectMatchRule_function) // CHECK-NEXT: HybridPatchable (SubjectMatchRule_function) // CHECK-NEXT: IBAction (SubjectMatchRule_objc_method_is_instance) diff --git a/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl b/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl index 29850828ad3bc2..24c85c6ccf7d74 100644 --- a/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl +++ b/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl @@ -1,9 +1,16 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s - -// CHECK: -HLSLROVAttr 0x{{[0-9a-f]+}} <col:10, col:16> -struct [[hlsl::is_rov]] Eg1 { - int i; +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} struct MyBuffer definition +// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:6:3, col:68> col:68 h '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov()]]':'__hlsl_resource_t' +struct MyBuffer { + __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov]] h; }; -Eg1 e1; +// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:10:1, col:66> col:66 res '__hlsl_resource_t {{\[\[}}hlsl::resource_class(SRV)]] {{\[\[}}hlsl::is_rov()]]':'__hlsl_resource_t' +__hlsl_resource_t [[hlsl::is_rov]] [[hlsl::resource_class(SRV)]] res; + +// 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 r '__hlsl_resource_t {{\[\[}}hlsl::resource_class(Sampler)]] {{\[\[}}hlsl::is_rov()]]':'__hlsl_resource_t' +void f() { + __hlsl_resource_t [[hlsl::resource_class(Sampler)]] [[hlsl::is_rov]] r; +} diff --git a/clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl index a21fed22220b6d..68b2d9ecb190a8 100644 --- a/clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl +++ b/clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl @@ -1,15 +1,16 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s -verify +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify -// expected-error@+1{{'is_rov' attribute takes no arguments}} -struct [[hlsl::is_rov(3)]] Eg1 { - int i; -}; +// expected-error@+1{{'is_rov' attribute cannot be applied to a declaration}} +[[hlsl::is_rov()]] __hlsl_resource_t res0; -Eg1 e1; +// expected-error@+1{{HLSL resource needs to have [[hlsl::resource_class()]] attribute}} +__hlsl_resource_t [[hlsl::is_rov()]] res1; +// expected-error@+1{{'is_rov' attribute takes no arguments}} +__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov(3)]] res2; + // expected-error@+1{{use of undeclared identifier 'gibberish'}} -struct [[hlsl::is_rov(gibberish)]] Eg2 { - int i; -}; +__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov(gibberish)]] res3; -Eg2 e2; +// duplicate attribute with the same meaning - no error +__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov()]] [[hlsl::is_rov()]] res4; diff --git a/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl b/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl index 4b002e2d890093..2e25e58d4253e8 100644 --- a/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl +++ b/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl @@ -1,32 +1,32 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s - -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <col:26> SRV -struct Eg1 { - [[hlsl::resource_class(SRV)]] int i; +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} struct MyBuffer definition +// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:6:3, col:51> col:51 h '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]]':'__hlsl_resource_t' +struct MyBuffer { + __hlsl_resource_t [[hlsl::resource_class(UAV)]] h; }; -Eg1 e1; - -// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} <line:13:1, line:15:1> line:13:8 referenced struct Eg2 definition -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <col:26> UAV -struct Eg2 { - [[hlsl::resource_class(UAV)]] int i; -}; -Eg2 e2; +// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:10:1, col:49> col:49 res '__hlsl_resource_t {{\[\[}}hlsl::resource_class(SRV)]]':'__hlsl_resource_t' +__hlsl_resource_t [[hlsl::resource_class(SRV)]] res; -// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} <line:20:1, line:22:1> line:20:8 referenced struct Eg3 definition -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <col:26> CBuffer -struct Eg3 { - [[hlsl::resource_class(CBuffer)]] int i; -}; -Eg3 e3; +// 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:55> col:55 r '__hlsl_resource_t {{\[\[}}hlsl::resource_class(Sampler)]]':'__hlsl_resource_t' +void f() { + __hlsl_resource_t [[hlsl::resource_class(Sampler)]] r; +} -// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} <line:27:1, line:29:1> line:27:8 referenced struct Eg4 definition -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <col:26> Sampler -struct Eg4 { - [[hlsl::resource_class(Sampler)]] int i; +// CHECK: ClassTemplateDecl 0x{{[0-9a-f]+}} <line:23:1, line:25:1> line:23:29 MyBuffer2 +// CHECK: TemplateTypeParmDecl 0x{{[0-9a-f]+}} <col:10, col:19> col:19 referenced typename depth 0 index 0 T +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, line:25:1> line:23:29 struct MyBuffer2 definition +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, col:29> col:29 implicit struct MyBuffer2 +// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:24:3, col:35> col:35 h 'T {{\[\[}}hlsl::resource_class(UAV)]]':'T' +template<typename T> struct MyBuffer2 { + T [[hlsl::resource_class(UAV)]] h; }; -Eg4 e4; -RWBuffer<int> In : register(u1); +// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <line:23:1, line:25:1> line:23:29 struct MyBuffer2 definition implicit_instantiation +// CHECK: TemplateArgument type 'float' +// CHECK: BuiltinType 0x{{[0-9a-f]+}} 'float' +// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, col:29> col:29 implicit struct MyBuffer2 +// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:24:3, col:35> col:35 h 'float {{\[\[}}hlsl::resource_class(UAV)]]':'float' +MyBuffer2<float> myBuffer2; diff --git a/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl index 76bed2f0607830..bb0e9e4621593f 100644 --- a/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl +++ b/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl @@ -1,22 +1,23 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s -verify +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify -struct Eg1 { -// expected-error@+1{{'resource_class' attribute takes one argument}} - [[hlsl::resource_class()]] int i; +struct SomeType { + int i; }; -Eg1 e1; +// expected-error@+1{{'resource_class' attribute cannot be applied to a declaration}} +[[hlsl::resource_class(UAV)]] SomeType e0; + +// expected-error@+1{{'resource_class' attribute takes one argument}} +SomeType [[hlsl::resource_class()]] e1; -struct Eg2 { // expected-warning@+1{{ResourceClass attribute argument not supported: gibberish}} - [[hlsl::resource_class(gibberish)]] int i; -}; +SomeType [[hlsl::resource_class(gibberish)]] e2; -Eg2 e2; +// expected-warning@+1{{attribute 'resource_class' is already applied with different arguments}} +SomeType [[hlsl::resource_class(SRV)]] [[hlsl::resource_class(UAV)]] e3; -// expected-warning@+1{{'resource_class' attribute only applies to non-static data members}} -struct [[hlsl::resource_class(SRV)]] Eg3 { - int i; -}; +// duplicate attribute with the same meaning - no error +SomeType [[hlsl::resource_class(SRV)]] [[hlsl::resource_class(SRV)]] e4; -Eg3 e3; +// expected-error@+1{{'resource_class' attribute takes one argument}} +SomeType [[hlsl::resource_class(SRV, "aa")]] e5; diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl index 320d1160e761dd..6324a11fc8a2df 100644 --- a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl +++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl @@ -1,15 +1,16 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s | FileCheck %s // CHECK: -ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> class RWBuffer definition implicit_instantiation -// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float *' -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit UAV +// CHECK: -TemplateArgument type 'float' +// CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float' +// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *' // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer RWBuffer<float> Buffer1; -// CHECK: -ClassTemplateDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit RasterizerOrderedBuffer -// CHECK: -CXXRecordDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit class RasterizerOrderedBuffer definition -// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit h 'element_type *' -// CHECK: -HLSLResourceClassAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit UAV +// CHECK: -ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> class RasterizerOrderedBuffer definition implicit_instantiation +// CHECK: -TemplateArgument type 'vector<float, 4>' +// CHECK: `-ExtVectorType 0x{{[0-9a-f]+}} 'vector<float, 4>' 4 +// CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float' +// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'vector<float *, 4> {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov()]]':'vector<float *, 4>' // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer -// CHECK: -HLSLROVAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit -RasterizerOrderedBuffer<vector<float, 4> > BufferArray3[4] : register(u4, space1); +RasterizerOrderedBuffer<vector<float, 4> > BufferArray3[4]; diff --git a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl index 6a0b5956545dd8..9a0474730ed17d 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl @@ -2,7 +2,7 @@ template<typename T> struct MyTemplatedSRV { - [[hlsl::resource_class(SRV)]] T x; + T [[hlsl::resource_class(SRV)]] x; }; // valid, The register keyword in this statement isn't binding a resource, rather it is diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl index c40d1d7f60b347..6e9df45da48057 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl @@ -6,23 +6,23 @@ template<typename T> struct MyTemplatedSRV { - [[hlsl::resource_class(SRV)]] T x; + T [[hlsl::resource_class(SRV)]] x; }; struct MySRV { - [[hlsl::resource_class(SRV)]] int x; + int [[hlsl::resource_class(SRV)]] x; }; struct MySampler { - [[hlsl::resource_class(Sampler)]] int x; + int [[hlsl::resource_class(Sampler)]] x; }; struct MyUAV { - [[hlsl::resource_class(UAV)]] int x; + int [[hlsl::resource_class(UAV)]] x; }; struct MyCBuffer { - [[hlsl::resource_class(CBuffer)]] int x; + int [[hlsl::resource_class(CBuffer)]] x; }; diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl index edb3f30739cdfd..8bc20f72b0d0b3 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl @@ -2,23 +2,23 @@ template<typename T> struct MyTemplatedUAV { - [[hlsl::resource_class(UAV)]] T x; + T [[hlsl::resource_class(UAV)]] x; }; struct MySRV { - [[hlsl::resource_class(SRV)]] int x; + int [[hlsl::resource_class(SRV)]] x; }; struct MySampler { - [[hlsl::resource_class(Sampler)]] int x; + int [[hlsl::resource_class(Sampler)]] x; }; struct MyUAV { - [[hlsl::resource_class(UAV)]] int x; + int [[hlsl::resource_class(UAV)]] x; }; struct MyCBuffer { - [[hlsl::resource_class(CBuffer)]] int x; + int [[hlsl::resource_class(CBuffer)]] x; }; // Valid: f is skipped, SRVBuf is bound to t0, UAVBuf is bound to u0 >From ba9d46516a267c95d70a00745405248e192449e4 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Tue, 3 Sep 2024 16:14:43 -0700 Subject: [PATCH 2/4] clang-format, cleanup --- clang/include/clang/Sema/SemaHLSL.h | 6 ++-- clang/lib/CodeGen/CGHLSLRuntime.cpp | 1 - clang/lib/Sema/HLSLExternalSemaSource.cpp | 10 +++---- clang/lib/Sema/SemaHLSL.cpp | 35 ++++++++++++----------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 5131458863e20b..f340ed367f8cf3 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -16,7 +16,6 @@ #include "clang/AST/ASTFwd.h" #include "clang/AST/Attr.h" #include "clang/AST/Type.h" -#include "clang/AST/TypeLoc.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/SemaBase.h" #include "llvm/ADT/SmallVector.h" @@ -89,9 +88,10 @@ class SemaHLSL : public SemaBase { private: // HLSL resource type attributes need to be processed all at once. // This is a list to collect them. - llvm::SmallVector<const Attr*> HLSLResourcesTypeAttrs; + llvm::SmallVector<const Attr *> HLSLResourcesTypeAttrs; - /// SourceRanges corresponding to HLSLAttributedResourceTypeLocs that we have not yet populated. + /// SourceLocation corresponding to HLSLAttributedResourceTypeLocs that we + /// have not yet populated. llvm::DenseMap<const HLSLAttributedResourceType *, SourceLocation> LocsForHLSLAttributedResources; }; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 0abca7b000d177..b6e6555e63fca1 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -17,7 +17,6 @@ #include "CodeGenModule.h" #include "TargetInfo.h" #include "clang/AST/Decl.h" -#include "clang/AST/Type.h" #include "clang/Basic/TargetOptions.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 07164069336dbd..37d24eefb5e66c 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -124,13 +124,13 @@ struct BuiltinTypeDeclBuilder { // add handle member with resource type attributes QualType AttributedResTy = QualType(); - SmallVector<const Attr*> Attrs = { - HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC), - IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr - }; + SmallVector<const Attr *> Attrs = { + HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC), + IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr}; Attr *ResourceAttr = HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK); - if (SemaHLSL::CreateHLSLAttributedResourceType(S, Ty, Attrs, AttributedResTy)) { + if (SemaHLSL::CreateHLSLAttributedResourceType(S, Ty, Attrs, + AttributedResTy)) { addMemberVariable("h", AttributedResTy, {ResourceAttr}, Access); } return *this; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 69f4382e465300..b542465ee2b6e5 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -562,7 +562,9 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } -bool SemaHLSL::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, llvm::SmallVector<const Attr *> &AttrList, QualType &ResType) { +bool SemaHLSL::CreateHLSLAttributedResourceType( + Sema &S, QualType Wrapped, llvm::SmallVector<const Attr *> &AttrList, + QualType &ResType) { assert(AttrList.size() && "expected list of resource attributes"); QualType Contained = QualType(); @@ -574,7 +576,8 @@ bool SemaHLSL::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, llvm: continue; switch (Attr->getKind()) { case attr::HLSLResourceClass: { - llvm::dxil::ResourceClass RC = dyn_cast<HLSLResourceClassAttr>(Attr)->getResourceClass(); + llvm::dxil::ResourceClass RC = + dyn_cast<HLSLResourceClassAttr>(Attr)->getResourceClass(); if (!hasResourceClass) { ResAttrs.ResourceClass = RC; hasResourceClass = true; @@ -593,11 +596,13 @@ bool SemaHLSL::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, llvm: } if (!hasResourceClass) { - S.Diag(AttrList.back()->getRange().getEnd(), diag::err_missing_resource_class); + S.Diag(AttrList.back()->getRange().getEnd(), + diag::err_missing_resource_class); return false; } - ResType = S.getASTContext().getHLSLAttributedResourceType(Wrapped, Contained, ResAttrs); + ResType = S.getASTContext().getHLSLAttributedResourceType(Wrapped, Contained, + ResAttrs); return true; } @@ -651,8 +656,10 @@ QualType SemaHLSL::ProcessResourceTypeAttributes(QualType CurrentType) { return CurrentType; QualType QT = CurrentType; - if (CreateHLSLAttributedResourceType(SemaRef, CurrentType, HLSLResourcesTypeAttrs, QT)) { - const HLSLAttributedResourceType *RT = dyn_cast<HLSLAttributedResourceType>(QT.getTypePtr()); + if (CreateHLSLAttributedResourceType(SemaRef, CurrentType, + HLSLResourcesTypeAttrs, QT)) { + const HLSLAttributedResourceType *RT = + dyn_cast<HLSLAttributedResourceType>(QT.getTypePtr()); SourceLocation Loc = HLSLResourcesTypeAttrs[0]->getLoc(); LocsForHLSLAttributedResources.insert(std::pair(RT, Loc)); } @@ -726,7 +733,8 @@ static void updateResourceClassFlagsFromDeclResourceClass( } } -const HLSLAttributedResourceType *findAttributedResourceTypeOnField(VarDecl *VD) { +const HLSLAttributedResourceType * +findAttributedResourceTypeOnField(VarDecl *VD) { assert(VD != nullptr && "expected VarDecl"); if (RecordDecl *RD = getRecordDeclFromVarDecl(VD)) { for (auto *FD : RD->fields()) { @@ -760,7 +768,8 @@ static void updateResourceClassFlagsFromRecordType(RegisterBindingFlags &Flags, const Type *FieldTy = FD->getType().getTypePtr(); if (const HLSLAttributedResourceType *AttrResType = dyn_cast<HLSLAttributedResourceType>(FieldTy)) { - updateResourceClassFlagsFromDeclResourceClass(Flags, AttrResType->getAttrs().ResourceClass); + updateResourceClassFlagsFromDeclResourceClass( + Flags, AttrResType->getAttrs().ResourceClass); continue; } TypesToScan.emplace_back(FD->getType().getTypePtr()); @@ -815,15 +824,7 @@ static RegisterBindingFlags HLSLFillRegisterBindingFlags(Sema &S, return Flags; } -enum class RegisterType { - SRV = static_cast<int>(llvm::dxil::ResourceClass::SRV), - UAV = static_cast<int>(llvm::dxil::ResourceClass::UAV), - CBuffer = static_cast<int>(llvm::dxil::ResourceClass::CBuffer), - Sampler = static_cast<int>(llvm::dxil::ResourceClass::Sampler), - C, - I, - Invalid -}; +enum class RegisterType { SRV, UAV, CBuffer, Sampler, C, I, Invalid }; static RegisterType getRegisterType(llvm::dxil::ResourceClass RC) { switch (RC) { >From 4e99c5f07fb70fa68ef1f2239d67dd6e645866b5 Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Tue, 3 Sep 2024 16:45:18 -0700 Subject: [PATCH 3/4] Update comment --- clang/lib/Sema/SemaHLSL.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index b542465ee2b6e5..c2f52f49e10398 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -607,9 +607,9 @@ bool SemaHLSL::CreateHLSLAttributedResourceType( } // Validates and creates an HLSL attribute that is applied as type attribute on -// HLSL resource. The attributes are collected in HLSLResourcesAttrs and at the -// end of the declaration they are applied to the declaration type by wrapping -// it in HLSLAttributedResourceType. +// HLSL resource. The attributes are collected in HLSLResourcesTypeAttrs and at +// the end of the declaration they are applied to the declaration type by +// wrapping it in HLSLAttributedResourceType. bool SemaHLSL::handleResourceTypeAttr(const ParsedAttr &AL) { Attr *A = nullptr; >From dfd0d0f23ed9df3e3cc8a54a39ba3a3a48e1808f Mon Sep 17 00:00:00 2001 From: Helena Kotas <heko...@microsoft.com> Date: Wed, 4 Sep 2024 12:18:02 -0700 Subject: [PATCH 4/4] Address code review feedback - use __hlsl_resource_t in tests - move function out of SemaHLSL - call erase with iterator --- clang/include/clang/Sema/SemaHLSL.h | 13 ++++++------- clang/lib/Sema/HLSLExternalSemaSource.cpp | 4 +--- clang/lib/Sema/SemaHLSL.cpp | 4 ++-- .../ParserHLSL/hlsl_resource_class_attr.hlsl | 8 ++++---- .../hlsl_resource_class_attr_error.hlsl | 16 ++++++---------- .../SemaHLSL/resource_binding_attr_error.hlsl | 2 +- .../resource_binding_attr_error_resource.hlsl | 10 +++++----- .../resource_binding_attr_error_udt.hlsl | 10 +++++----- 8 files changed, 30 insertions(+), 37 deletions(-) diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index f340ed367f8cf3..46eb14321c2740 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -28,6 +28,12 @@ class IdentifierInfo; class ParsedAttr; class Scope; +// FIXME: This can be hidden (as static function in SemaHLSL.cpp) once we no +// longer need to create builtin buffer types in HLSLExternalSemaSource. +bool CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, + llvm::SmallVector<const Attr *> &AttrList, + QualType &ResType); + class SemaHLSL : public SemaBase { public: SemaHLSL(Sema &S); @@ -78,13 +84,6 @@ class SemaHLSL : public SemaBase { QualType getInoutParameterType(QualType Ty); - // FIXME: This can be hidden (as static function in SemaHLSL.cpp) once we no - // longer need to create builtin buffer types in HLSLExternalSemaSource. - static bool - CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped, - llvm::SmallVector<const Attr *> &AttrList, - QualType &ResType); - private: // HLSL resource type attributes need to be processed all at once. // This is a list to collect them. diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 37d24eefb5e66c..071e64fe56d48a 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -129,10 +129,8 @@ struct BuiltinTypeDeclBuilder { IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr}; Attr *ResourceAttr = HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK); - if (SemaHLSL::CreateHLSLAttributedResourceType(S, Ty, Attrs, - AttributedResTy)) { + if (CreateHLSLAttributedResourceType(S, Ty, Attrs, AttributedResTy)) addMemberVariable("h", AttributedResTy, {ResourceAttr}, Access); - } return *this; } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index c2f52f49e10398..d69960fffc812b 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -562,7 +562,7 @@ void SemaHLSL::handleShaderAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } -bool SemaHLSL::CreateHLSLAttributedResourceType( +bool clang::CreateHLSLAttributedResourceType( Sema &S, QualType Wrapped, llvm::SmallVector<const Attr *> &AttrList, QualType &ResType) { assert(AttrList.size() && "expected list of resource attributes"); @@ -673,7 +673,7 @@ SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) { auto I = LocsForHLSLAttributedResources.find(RT); if (I != LocsForHLSLAttributedResources.end()) { SourceLocation Loc = I->second; - LocsForHLSLAttributedResources.erase(RT); + LocsForHLSLAttributedResources.erase(I); return Loc; } return SourceLocation(); diff --git a/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl b/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl index 2e25e58d4253e8..f11a64d33839bd 100644 --- a/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl +++ b/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl @@ -16,17 +16,17 @@ void f() { } // CHECK: ClassTemplateDecl 0x{{[0-9a-f]+}} <line:23:1, line:25:1> line:23:29 MyBuffer2 -// CHECK: TemplateTypeParmDecl 0x{{[0-9a-f]+}} <col:10, col:19> col:19 referenced typename depth 0 index 0 T +// CHECK: TemplateTypeParmDecl 0x{{[0-9a-f]+}} <col:10, col:19> col:19 typename depth 0 index 0 T // CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, line:25:1> line:23:29 struct MyBuffer2 definition // CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, col:29> col:29 implicit struct MyBuffer2 -// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:24:3, col:35> col:35 h 'T {{\[\[}}hlsl::resource_class(UAV)]]':'T' +// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:24:3, col:51> col:51 h '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]]':'__hlsl_resource_t' template<typename T> struct MyBuffer2 { - T [[hlsl::resource_class(UAV)]] h; + __hlsl_resource_t [[hlsl::resource_class(UAV)]] h; }; // CHECK: ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <line:23:1, line:25:1> line:23:29 struct MyBuffer2 definition implicit_instantiation // CHECK: TemplateArgument type 'float' // CHECK: BuiltinType 0x{{[0-9a-f]+}} 'float' // CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, col:29> col:29 implicit struct MyBuffer2 -// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:24:3, col:35> col:35 h 'float {{\[\[}}hlsl::resource_class(UAV)]]':'float' +// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:24:3, col:51> col:51 h '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]]':'__hlsl_resource_t' MyBuffer2<float> myBuffer2; diff --git a/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl index bb0e9e4621593f..06e607d7462c63 100644 --- a/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl +++ b/clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl @@ -1,23 +1,19 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify -struct SomeType { - int i; -}; - // expected-error@+1{{'resource_class' attribute cannot be applied to a declaration}} -[[hlsl::resource_class(UAV)]] SomeType e0; +[[hlsl::resource_class(UAV)]] __hlsl_resource_t e0; // expected-error@+1{{'resource_class' attribute takes one argument}} -SomeType [[hlsl::resource_class()]] e1; +__hlsl_resource_t [[hlsl::resource_class()]] e1; // expected-warning@+1{{ResourceClass attribute argument not supported: gibberish}} -SomeType [[hlsl::resource_class(gibberish)]] e2; +__hlsl_resource_t [[hlsl::resource_class(gibberish)]] e2; // expected-warning@+1{{attribute 'resource_class' is already applied with different arguments}} -SomeType [[hlsl::resource_class(SRV)]] [[hlsl::resource_class(UAV)]] e3; +__hlsl_resource_t [[hlsl::resource_class(SRV)]] [[hlsl::resource_class(UAV)]] e3; // duplicate attribute with the same meaning - no error -SomeType [[hlsl::resource_class(SRV)]] [[hlsl::resource_class(SRV)]] e4; +__hlsl_resource_t [[hlsl::resource_class(SRV)]] [[hlsl::resource_class(SRV)]] e4; // expected-error@+1{{'resource_class' attribute takes one argument}} -SomeType [[hlsl::resource_class(SRV, "aa")]] e5; +__hlsl_resource_t [[hlsl::resource_class(SRV, "aa")]] e5; diff --git a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl index 9a0474730ed17d..cb728dca838c3b 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl @@ -2,7 +2,7 @@ template<typename T> struct MyTemplatedSRV { - T [[hlsl::resource_class(SRV)]] x; + __hlsl_resource_t [[hlsl::resource_class(SRV)]] x; }; // valid, The register keyword in this statement isn't binding a resource, rather it is diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl index 6e9df45da48057..4b6af47c0ab725 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl @@ -6,23 +6,23 @@ template<typename T> struct MyTemplatedSRV { - T [[hlsl::resource_class(SRV)]] x; + __hlsl_resource_t [[hlsl::resource_class(SRV)]] x; }; struct MySRV { - int [[hlsl::resource_class(SRV)]] x; + __hlsl_resource_t [[hlsl::resource_class(SRV)]] x; }; struct MySampler { - int [[hlsl::resource_class(Sampler)]] x; + __hlsl_resource_t [[hlsl::resource_class(Sampler)]] x; }; struct MyUAV { - int [[hlsl::resource_class(UAV)]] x; + __hlsl_resource_t [[hlsl::resource_class(UAV)]] x; }; struct MyCBuffer { - int [[hlsl::resource_class(CBuffer)]] x; + __hlsl_resource_t [[hlsl::resource_class(CBuffer)]] x; }; diff --git a/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl index 8bc20f72b0d0b3..ea2d576e4cca55 100644 --- a/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl +++ b/clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl @@ -2,23 +2,23 @@ template<typename T> struct MyTemplatedUAV { - T [[hlsl::resource_class(UAV)]] x; + __hlsl_resource_t [[hlsl::resource_class(UAV)]] x; }; struct MySRV { - int [[hlsl::resource_class(SRV)]] x; + __hlsl_resource_t [[hlsl::resource_class(SRV)]] x; }; struct MySampler { - int [[hlsl::resource_class(Sampler)]] x; + __hlsl_resource_t [[hlsl::resource_class(Sampler)]] x; }; struct MyUAV { - int [[hlsl::resource_class(UAV)]] x; + __hlsl_resource_t [[hlsl::resource_class(UAV)]] x; }; struct MyCBuffer { - int [[hlsl::resource_class(CBuffer)]] x; + __hlsl_resource_t [[hlsl::resource_class(CBuffer)]] x; }; // Valid: f is skipped, SRVBuf is bound to t0, UAVBuf is bound to u0 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits