-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[HLSL] Apply resource attributes to the resource type rather than the handle member #107160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… handle member (#6)
✅ With the latest revision this PR passed the C/C++ code formatter. |
@llvm/pr-subscribers-hlsl Author: Helena Kotas (hekota) ChangesConverts existing resource attributes During type attribute processing all HLSL resource type attributes are validated and collected by
Updates all places that expected resource attributes on declarations like resource binding diagnostic, builtin types in HLSLExternalSemaSource, or codegen. Also includes implementation of 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:
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]
|
@llvm/pr-subscribers-clang-codegen Author: Helena Kotas (hekota) ChangesConverts existing resource attributes During type attribute processing all HLSL resource type attributes are validated and collected by
Updates all places that expected resource attributes on declarations like resource binding diagnostic, builtin types in HLSLExternalSemaSource, or codegen. Also includes implementation of 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:
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]
|
@llvm/pr-subscribers-clang Author: Helena Kotas (hekota) ChangesConverts existing resource attributes During type attribute processing all HLSL resource type attributes are validated and collected by
Updates all places that expected resource attributes on declarations like resource binding diagnostic, builtin types in HLSLExternalSemaSource, or codegen. Also includes implementation of 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:
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]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in description:
Converts existing resource attributes [[hlsl::resource_class(..)]] and [[is_rov]]
tofrom declaration attributes to type attributes.
There's many places in the existing tests where these attributes are being used in ways we don't really intend them to use. Maybe now would be the right time to fix them up?
- use __hlsl_resource_t in tests - move function out of SemaHLSL - call erase with iterator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple more very minor comments then this LGTM!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/73/builds/5051 Here is the relevant piece of the build log for the reference
|
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 singleHLSLAttributedResourceType
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 theTypeLoc
information for the newly created type that will be grabbed byTypeSpecLocFiller
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