-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[HLSL] Implement SpirvType
and SpirvOpaqueType
#134034
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
base: main
Are you sure you want to change the base?
Conversation
This implements the design proposed by [Representing SpirvType in Clang's Type System](llvm/wg-hlsl#181). It creates `HLSLInlineSpirvType` as a new `Type` subclass, and `__hlsl_spirv_type` as a new builtin type template to create such a type. This new type is lowered to the `spirv.Type` target extension type, as described in [Target Extension Types for Inline SPIR-V and Decorated Types](https://github.com/llvm/wg-hlsl/blob/main/proposals/0017-inline-spirv-and-decorated-types.md).
@llvm/pr-subscribers-debuginfo @llvm/pr-subscribers-backend-x86 Author: Cassandra Beckley (cassiebeckley) ChangesThis implements the design proposed by Representing SpirvType in Clang's Type System. It creates This new type is lowered to the Patch is 74.71 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/134034.diff 51 Files Affected:
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 38e2417dcd181..757f8a3afc758 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -3034,7 +3034,8 @@ enum CXTypeKind {
/* HLSL Types */
CXType_HLSLResource = 179,
- CXType_HLSLAttributedResource = 180
+ CXType_HLSLAttributedResource = 180,
+ CXType_HLSLInlineSpirv = 181
};
/**
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index a24f30815e6b9..c62f9f7672010 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -260,6 +260,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
DependentBitIntTypes;
mutable llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes;
llvm::FoldingSet<HLSLAttributedResourceType> HLSLAttributedResourceTypes;
+ llvm::FoldingSet<HLSLInlineSpirvType> HLSLInlineSpirvTypes;
mutable llvm::FoldingSet<CountAttributedType> CountAttributedTypes;
@@ -1795,6 +1796,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType Wrapped, QualType Contained,
const HLSLAttributedResourceType::Attributes &Attrs);
+ QualType getHLSLInlineSpirvType(uint32_t Opcode, uint32_t Size,
+ uint32_t Alignment,
+ ArrayRef<SpirvOperand> Operands);
+
QualType
getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
unsigned Index,
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index f086d8134a64b..fd9108221590e 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -450,6 +450,24 @@ class ASTNodeTraverser
if (!Contained.isNull())
Visit(Contained);
}
+ void VisitHLSLInlineSpirvType(const HLSLInlineSpirvType *T) {
+ for (auto &Operand : T->getOperands()) {
+ using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
+
+ switch (Operand.getKind()) {
+ case SpirvOperandKind::kConstantId:
+ case SpirvOperandKind::kLiteral:
+ break;
+
+ case SpirvOperandKind::kTypeId:
+ Visit(Operand.getResultType());
+ break;
+
+ default:
+ llvm_unreachable("Invalid SpirvOperand kind!");
+ }
+ }
+ }
void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
void
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td
index 5171555008ac9..7d5e6671fec7d 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -147,6 +147,7 @@ def UInt64 : CountPropertyType<"uint64_t">;
def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">;
def VectorKind : EnumPropertyType<"VectorKind">;
def TypeCoupledDeclRefInfo : PropertyType;
+def HLSLSpirvOperand : PropertyType<"SpirvOperand"> { let PassByReference = 1; }
def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> {
let BufferElementTypes = [ QualType ];
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 0530996ed20d3..255e39a46db09 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1154,6 +1154,14 @@ DEF_TRAVERSE_TYPE(BTFTagAttributedType,
DEF_TRAVERSE_TYPE(HLSLAttributedResourceType,
{ TRY_TO(TraverseType(T->getWrappedType())); })
+DEF_TRAVERSE_TYPE(HLSLInlineSpirvType, {
+ for (auto &Operand : T->getOperands()) {
+ if (Operand.isConstant() || Operand.isType()) {
+ TRY_TO(TraverseType(Operand.getResultType()));
+ }
+ }
+})
+
DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
DEF_TRAVERSE_TYPE(MacroQualifiedType,
@@ -1457,6 +1465,9 @@ DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
{ TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
+DEF_TRAVERSE_TYPELOC(HLSLInlineSpirvType,
+ { TRY_TO(TraverseType(TL.getType())); })
+
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
if (TL.getQualifierLoc()) {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index cfd417068abb7..f351e68d5297d 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2652,6 +2652,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isHLSLSpecificType() const; // Any HLSL specific type
bool isHLSLBuiltinIntangibleType() const; // Any HLSL builtin intangible type
bool isHLSLAttributedResourceType() const;
+ bool isHLSLInlineSpirvType() const;
bool isHLSLResourceRecord() const;
bool isHLSLIntangibleType()
const; // Any HLSL intangible type (builtin, array, class)
@@ -6330,6 +6331,140 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
findHandleTypeOnResource(const Type *RT);
};
+/// Instances of this class represent operands to a SPIR-V type instruction.
+class SpirvOperand {
+public:
+ enum SpirvOperandKind : unsigned char {
+ kInvalid, ///< Uninitialized.
+ kConstantId, ///< Integral value to represent as a SPIR-V OpConstant
+ ///< instruction ID.
+ kLiteral, ///< Integral value to represent as an immediate literal.
+ kTypeId, ///< Type to represent as a SPIR-V type ID.
+
+ kMax,
+ };
+
+private:
+ SpirvOperandKind Kind = kInvalid;
+
+ QualType ResultType;
+ llvm::APInt Value; // Signedness of constants is represented by ResultType.
+
+public:
+ SpirvOperand() : Kind(kInvalid), ResultType() {}
+
+ SpirvOperand(SpirvOperandKind Kind, QualType ResultType, llvm::APInt Value)
+ : Kind(Kind), ResultType(ResultType), Value(Value) {}
+
+ SpirvOperand(const SpirvOperand &Other) { *this = Other; }
+ ~SpirvOperand() {}
+
+ SpirvOperand &operator=(const SpirvOperand &Other) {
+ this->Kind = Other.Kind;
+ this->ResultType = Other.ResultType;
+ this->Value = Other.Value;
+ return *this;
+ }
+
+ bool operator==(const SpirvOperand &Other) const {
+ return Kind == Other.Kind && ResultType == Other.ResultType &&
+ Value == Other.Value;
+ }
+
+ bool operator!=(const SpirvOperand &Other) const { return !(*this == Other); }
+
+ SpirvOperandKind getKind() const { return Kind; }
+
+ bool isValid() const { return Kind != kInvalid && Kind < kMax; }
+ bool isConstant() const { return Kind == kConstantId; }
+ bool isLiteral() const { return Kind == kLiteral; }
+ bool isType() const { return Kind == kTypeId; }
+
+ llvm::APInt getValue() const {
+ assert((isConstant() || isLiteral()) &&
+ "This is not an operand with a value!");
+ return Value;
+ }
+
+ QualType getResultType() const {
+ assert((isConstant() || isType()) &&
+ "This is not an operand with a result type!");
+ return ResultType;
+ }
+
+ static SpirvOperand createConstant(QualType ResultType, llvm::APInt Val) {
+ return SpirvOperand(kConstantId, ResultType, Val);
+ }
+
+ static SpirvOperand createLiteral(llvm::APInt Val) {
+ return SpirvOperand(kLiteral, QualType(), Val);
+ }
+
+ static SpirvOperand createType(QualType T) {
+ return SpirvOperand(kTypeId, T, llvm::APSInt());
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger(Kind);
+ ID.AddPointer(ResultType.getAsOpaquePtr());
+ Value.Profile(ID);
+ }
+};
+
+/// Represents an arbitrary, user-specified SPIR-V type instruction.
+class HLSLInlineSpirvType final
+ : public Type,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<HLSLInlineSpirvType, SpirvOperand> {
+ friend class ASTContext; // ASTContext creates these
+ friend TrailingObjects;
+
+private:
+ uint32_t Opcode;
+ uint32_t Size;
+ uint32_t Alignment;
+ size_t NumOperands;
+
+ HLSLInlineSpirvType(uint32_t Opcode, uint32_t Size, uint32_t Alignment,
+ ArrayRef<SpirvOperand> Operands)
+ : Type(HLSLInlineSpirv, QualType(), TypeDependence::None), Opcode(Opcode),
+ Size(Size), Alignment(Alignment), NumOperands(Operands.size()) {
+ for (size_t I = 0; I < NumOperands; I++) {
+ getTrailingObjects<SpirvOperand>()[I] = Operands[I];
+ }
+ }
+
+public:
+ uint32_t getOpcode() const { return Opcode; }
+ uint32_t getSize() const { return Size; }
+ uint32_t getAlignment() const { return Alignment; }
+ ArrayRef<SpirvOperand> getOperands() const {
+ return {getTrailingObjects<SpirvOperand>(), NumOperands};
+ }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Opcode, Size, Alignment, getOperands());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, uint32_t Opcode,
+ uint32_t Size, uint32_t Alignment,
+ ArrayRef<SpirvOperand> Operands) {
+ ID.AddInteger(Opcode);
+ ID.AddInteger(Size);
+ ID.AddInteger(Alignment);
+ for (auto &Operand : Operands) {
+ Operand.Profile(ID);
+ }
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == HLSLInlineSpirv;
+ }
+};
+
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
@@ -8458,13 +8593,18 @@ inline bool Type::isHLSLBuiltinIntangibleType() const {
}
inline bool Type::isHLSLSpecificType() const {
- return isHLSLBuiltinIntangibleType() || isHLSLAttributedResourceType();
+ return isHLSLBuiltinIntangibleType() || isHLSLAttributedResourceType() ||
+ isHLSLInlineSpirvType();
}
inline bool Type::isHLSLAttributedResourceType() const {
return isa<HLSLAttributedResourceType>(this);
}
+inline bool Type::isHLSLInlineSpirvType() const {
+ return isa<HLSLInlineSpirvType>(this);
+}
+
inline bool Type::isTemplateTypeParmType() const {
return isa<TemplateTypeParmType>(CanonicalType);
}
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 92661b8b13fe0..53c7ea8c65df2 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -973,6 +973,25 @@ class HLSLAttributedResourceTypeLoc
}
};
+struct HLSLInlineSpirvTypeLocInfo {
+ SourceLocation Loc;
+}; // Nothing.
+
+class HLSLInlineSpirvTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc, HLSLInlineSpirvTypeLoc,
+ HLSLInlineSpirvType, HLSLInlineSpirvTypeLocInfo> {
+public:
+ SourceLocation getSpirvTypeLoc() const { return getLocalData()->Loc; }
+ void setSpirvTypeLoc(SourceLocation loc) const { getLocalData()->Loc = loc; }
+
+ SourceRange getLocalSourceRange() const {
+ return SourceRange(getSpirvTypeLoc(), getSpirvTypeLoc());
+ }
+ void initializeLocal(ASTContext &Context, SourceLocation loc) {
+ setSpirvTypeLoc(loc);
+ }
+};
+
struct ObjCObjectTypeLocInfo {
SourceLocation TypeArgsLAngleLoc;
SourceLocation TypeArgsRAngleLoc;
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 391fd26a086f7..784c2104f1bb2 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -719,6 +719,24 @@ let Class = HLSLAttributedResourceType in {
}]>;
}
+let Class = HLSLInlineSpirvType in {
+ def : Property<"opcode", UInt32> {
+ let Read = [{ node->getOpcode() }];
+ }
+ def : Property<"size", UInt32> {
+ let Read = [{ node->getSize() }];
+ }
+ def : Property<"alignment", UInt32> {
+ let Read = [{ node->getAlignment() }];
+ }
+ def : Property<"operands", Array<HLSLSpirvOperand>> {
+ let Read = [{ node->getOperands() }];
+ }
+ def : Creator<[{
+ return ctx.getHLSLInlineSpirvType(opcode, size, alignment, operands);
+ }]>;
+}
+
let Class = DependentAddressSpaceType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
diff --git a/clang/include/clang/Basic/BuiltinTemplates.td b/clang/include/clang/Basic/BuiltinTemplates.td
index d46ce063d2f7e..5b9672b395955 100644
--- a/clang/include/clang/Basic/BuiltinTemplates.td
+++ b/clang/include/clang/Basic/BuiltinTemplates.td
@@ -28,25 +28,37 @@ class BuiltinNTTP<string type_name> : TemplateArg<""> {
}
def SizeT : BuiltinNTTP<"size_t"> {}
+def Uint32T: BuiltinNTTP<"uint32_t"> {}
class BuiltinTemplate<list<TemplateArg> template_head> {
list<TemplateArg> TemplateHead = template_head;
}
+class CPlusPlusBuiltinTemplate<list<TemplateArg> template_head> : BuiltinTemplate<template_head>;
+
+class HLSLBuiltinTemplate<list<TemplateArg> template_head> : BuiltinTemplate<template_head>;
+
// template <template <class T, T... Ints> IntSeq, class T, T N>
-def __make_integer_seq : BuiltinTemplate<
+def __make_integer_seq : CPlusPlusBuiltinTemplate<
[Template<[Class<"T">, NTTP<"T", "Ints", /*is_variadic=*/1>], "IntSeq">, Class<"T">, NTTP<"T", "N">]>;
// template <size_t, class... T>
-def __type_pack_element : BuiltinTemplate<
+def __type_pack_element : CPlusPlusBuiltinTemplate<
[SizeT, Class<"T", /*is_variadic=*/1>]>;
// template <template <class... Args> BaseTemplate,
// template <class TypeMember> HasTypeMember,
// class HasNoTypeMember
// class... Ts>
-def __builtin_common_type : BuiltinTemplate<
+def __builtin_common_type : CPlusPlusBuiltinTemplate<
[Template<[Class<"Args", /*is_variadic=*/1>], "BaseTemplate">,
Template<[Class<"TypeMember">], "HasTypeMember">,
Class<"HasNoTypeMember">,
Class<"Ts", /*is_variadic=*/1>]>;
+
+// template <uint32_t Opcode,
+// uint32_t Size,
+// uint32_t Alignment,
+// typename ...Operands>
+def __hlsl_spirv_type : HLSLBuiltinTemplate<
+[Uint32T, Uint32T, Uint32T, Class<"Operands", /*is_variadic=*/1>]>;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 265bed2df43cf..287e139f02a2c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12709,6 +12709,9 @@ def err_hlsl_expect_arg_const_int_one_or_neg_one: Error<
def err_invalid_hlsl_resource_type: Error<
"invalid __hlsl_resource_t type attributes">;
+def err_hlsl_spirv_only: Error<"%0 is only available for the SPIR-V target">;
+def err_hlsl_vk_literal_must_contain_constant: Error<"the argument to vk::Literal must be a vk::integral_constant">;
+
// Layout randomization diagnostics.
def err_non_designated_init_used : Error<
"a randomized struct can only be initialized with a designated initializer">;
diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td
index 7e550ca2992f3..567b8a5ca5a4d 100644
--- a/clang/include/clang/Basic/TypeNodes.td
+++ b/clang/include/clang/Basic/TypeNodes.td
@@ -94,6 +94,7 @@ def ElaboratedType : TypeNode<Type>, NeverCanonical;
def AttributedType : TypeNode<Type>, NeverCanonical;
def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
def HLSLAttributedResourceType : TypeNode<Type>;
+def HLSLInlineSpirvType : TypeNode<Type>;
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h
index 7117b7246739b..79d33315d4fee 100644
--- a/clang/include/clang/Serialization/ASTRecordReader.h
+++ b/clang/include/clang/Serialization/ASTRecordReader.h
@@ -214,6 +214,8 @@ class ASTRecordReader
TypeCoupledDeclRefInfo readTypeCoupledDeclRefInfo();
+ SpirvOperand readHLSLSpirvOperand();
+
/// Read a declaration name, advancing Idx.
// DeclarationName readDeclarationName(); (inherited)
DeclarationNameLoc readDeclarationNameLoc(DeclarationName Name);
diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h
index 84d77e46016b7..9653b709d3ef5 100644
--- a/clang/include/clang/Serialization/ASTRecordWriter.h
+++ b/clang/include/clang/Serialization/ASTRecordWriter.h
@@ -151,6 +151,20 @@ class ASTRecordWriter
writeBool(Info.isDeref());
}
+ void writeHLSLSpirvOperand(SpirvOperand Op) {
+ QualType ResultType;
+ llvm::APInt Value;
+
+ if (Op.isConstant() || Op.isType())
+ ResultType = Op.getResultType();
+ if (Op.isConstant() || Op.isLiteral())
+ Value = Op.getValue();
+
+ Record->push_back(Op.getKind());
+ writeQualType(ResultType);
+ writeAPInt(Value);
+ }
+
/// Emit a source range.
void AddSourceRange(SourceRange Range, LocSeq *Seq = nullptr) {
return Writer->AddSourceRange(Range, *Record, Seq);
diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def
index 3c78b87805010..b8cde2e370960 100644
--- a/clang/include/clang/Serialization/TypeBitCodes.def
+++ b/clang/include/clang/Serialization/TypeBitCodes.def
@@ -68,5 +68,6 @@ TYPE_BIT_CODE(PackIndexing, PACK_INDEXING, 56)
TYPE_BIT_CODE(CountAttributed, COUNT_ATTRIBUTED, 57)
TYPE_BIT_CODE(ArrayParameter, ARRAY_PARAMETER, 58)
TYPE_BIT_CODE(HLSLAttributedResource, HLSLRESOURCE_ATTRIBUTED, 59)
+TYPE_BIT_CODE(HLSLInlineSpirv, HLSL_INLINE_SPIRV, 60)
#undef TYPE_BIT_CODE
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 552b5823add36..fb6a7b5a34175 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2454,6 +2454,19 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
return getTypeInfo(
cast<HLSLAttributedResourceType>(T)->getWrappedType().getTypePtr());
+ case Type::HLSLInlineSpirv: {
+ const auto *ST = cast<HLSLInlineSpirvType>(T);
+ // Size is specified in bytes, convert to bits
+ Width = ST->getSize() * 8;
+ Align = ST->getAlignment();
+ if (Width == 0 && Align == 0) {
+ // We are defaulting to laying out opaque SPIR-V types as 32-bit ints.
+ Width = 32;
+ Align = 32;
+ }
+ break;
+ }
+
case Type::Atomic: {
// Start with the base type information.
TypeInfo Info = getTypeInfo(cast<AtomicType>(T)->getValueType());
@@ -3458,6 +3471,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
return;
}
case Type::HLSLAttributedResource:
+ case Type::HLSLInlineSpirv:
llvm_unreachable("should never get here");
break;
case Type::DeducedTemplateSpecialization:
@@ -4179,6 +4193,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::DependentBitInt:
case Type::ArrayParameter:
case Type::HLSLAttributedResource:
+ case Type::HLSLInlineSpirv:
llvm_unreachable("type should never be variably-modified");
// These types can be variably-modified but should never need to
@@ -5444,6 +5459,31 @@ QualType ASTContext::getHLSLAttributedResourceType(
return QualType(Ty, 0);
}
+
+QualType ASTContext::getHLSLInlineSpirvType(uint32_t Opcode, uint32_t Size,
+ uint32_t Alignment,
+ ArrayRef<SpirvOperand> Operands) {
+ llvm::FoldingSetNodeID ID;
+ HLSLInlineSpirvType::Profile(ID, Opcode, Size, Alignment, Operands);
+
+ void *InsertPos = nullptr;
+ HLSLInlineSpirvType *Ty =
+ HLSLInlineSpirvTypes.FindNodeOrInsertPos(ID, InsertPos);
+ if (Ty)
+ return QualType(Ty, 0);
+
+ unsigned size = sizeof(HLSLInlineSpirvType);
+ size += Operands.size() * sizeof(SpirvOperand);
+ void *mem = Allocate(size, alignof(HLSLInlineSpirvType));
+
+ Ty = new (mem) HLSLInlineSpirvType(Opcode, Size, Alignment, Operands);
+
+ Types.push_back(Ty);
+ HLSLInlineSpirvTypes.InsertNode(Ty, InsertPos);
+
+ return QualType(Ty, 0);
+}
+
/// Retrieve a substitution-result type.
QualType ASTContext::getSubstTemplateTypeParmType(
QualType Replacement, Decl *AssociatedDecl, unsigned Index,
@@ -9335,6 +9375,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
return;
case Type::HLSLAttributedResource:
+ case Type::HLSLInlineSpirv:
...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
@philnik777 fyi for the changes to builtin templates |
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.
I've done some extra testing and playing with it. It seems to be working. However, I do not know enough about how things are done in clang to know if this is the best way to do it. It look reasonable to me. Others will have to review the implementation.
This implements the design proposed by Representing SpirvType in Clang's Type System. It creates
HLSLInlineSpirvType
as a newType
subclass, and__hlsl_spirv_type
as a new builtin type template to create such a type.This new type is lowered to the
spirv.Type
target extension type, as described in Target Extension Types for Inline SPIR-V and Decorated Types.