llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-hlsl Author: Helena Kotas (hekota) <details> <summary>Changes</summary> Converts existing resource attributes `[[hlsl::resource_class(..)]]` and `[[is_rov]]` to 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 --- Patch is 36.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/107160.diff 20 Files Affected: - (modified) clang/include/clang/AST/TypeLoc.h (+8) - (modified) clang/include/clang/Basic/Attr.td (+2-4) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+1) - (modified) clang/include/clang/Sema/SemaHLSL.h (+19-2) - (modified) clang/lib/AST/TypePrinter.cpp (+6-3) - (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+5-4) - (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+15-10) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (-6) - (modified) clang/lib/Sema/SemaHLSL.cpp (+120-54) - (modified) clang/lib/Sema/TreeTransform.h (+20-2) - (modified) clang/test/AST/HLSL/RWBuffer-AST.hlsl (+4-6) - (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test (-2) - (modified) clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl (+12-5) - (modified) clang/test/ParserHLSL/hlsl_is_rov_attr_error.hlsl (+11-10) - (modified) clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl (+24-24) - (modified) clang/test/ParserHLSL/hlsl_resource_class_attr_error.hlsl (+15-14) - (modified) clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl (+9-8) - (modified) clang/test/SemaHLSL/resource_binding_attr_error.hlsl (+1-1) - (modified) clang/test/SemaHLSL/resource_binding_attr_error_resource.hlsl (+5-5) - (modified) clang/test/SemaHLSL/resource_binding_attr_error_udt.hlsl (+5-5) ``````````diff 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..f340ed367f8cf3 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -15,8 +15,10 @@ #include "clang/AST/ASTFwd.h" #include "clang/AST/Attr.h" +#include "clang/AST/Type.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 +61,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 +77,23 @@ 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; + + /// SourceLocation 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..b6e6555e63fca1 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -295,13 +295,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..37d24eefb5e66c 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..c2f52f49e10398 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,120 @@ 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"); + } } - D->addAttr(HLSLResourceClassAttr::Create(getASTContext(), RC, ArgLoc)); + if (!hasResourceClass) { + S.Diag(AttrList.back()->getRange().getEnd(), + diag::err_missing_resource_class); + return false; + } + + 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 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) { - // 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 +733,19 @@ 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 +765,11 @@ static void updateResourceClassFlagsFromRecordType(RegisterBindingFlags &Flags, const RecordDecl *RD = RT->getDecl(); for (FieldDecl *FD : RD->fields()) { - if (HLSLResourceClassAttr *RCAttr = - FD->getAttr<HLSLResourceClassAttr>()) { + const Type *FieldTy = FD->getType().getTypePtr(); + if (const HLSLAttributedResourceType *AttrResType = + dyn_cast<HLSLAttributedResourceType>(FieldTy)) { updateResourceClassFlagsFromDeclResourceClass( - Flags, RCAttr->getResourceClass()); + Flags, AttrResType->getAttrs().ResourceClass); continue; } TypesToScan.emplace_back(FD->getType().getTypePtr()); @@ -729,11 +796,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()) 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 = ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/107160 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits