[clang] [HLSL] Implement `SpirvType` and `SpirvOpaqueType` (PR #134034)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 1 23:24:51 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-hlsl
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-backend-x86
Author: Cassandra Beckley (cassiebeckley)
<details>
<summary>Changes</summary>
This implements the design proposed by [Representing SpirvType in Clang's Type System](https://github.com/llvm/wg-hlsl/pull/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).
---
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:
- (modified) clang/include/clang-c/Index.h (+2-1)
- (modified) clang/include/clang/AST/ASTContext.h (+5)
- (modified) clang/include/clang/AST/ASTNodeTraverser.h (+18)
- (modified) clang/include/clang/AST/PropertiesBase.td (+1)
- (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+11)
- (modified) clang/include/clang/AST/Type.h (+141-1)
- (modified) clang/include/clang/AST/TypeLoc.h (+19)
- (modified) clang/include/clang/AST/TypeProperties.td (+18)
- (modified) clang/include/clang/Basic/BuiltinTemplates.td (+15-3)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3)
- (modified) clang/include/clang/Basic/TypeNodes.td (+1)
- (modified) clang/include/clang/Serialization/ASTRecordReader.h (+2)
- (modified) clang/include/clang/Serialization/ASTRecordWriter.h (+14)
- (modified) clang/include/clang/Serialization/TypeBitCodes.def (+1)
- (modified) clang/lib/AST/ASTContext.cpp (+59)
- (modified) clang/lib/AST/ASTImporter.cpp (+42)
- (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+17)
- (modified) clang/lib/AST/ExprConstant.cpp (+1)
- (modified) clang/lib/AST/ItaniumMangle.cpp (+39-1)
- (modified) clang/lib/AST/MicrosoftMangle.cpp (+5)
- (modified) clang/lib/AST/Type.cpp (+14)
- (modified) clang/lib/AST/TypePrinter.cpp (+48)
- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+8)
- (modified) clang/lib/CodeGen/CGDebugInfo.h (+1)
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+2)
- (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+6)
- (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+2)
- (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+89-1)
- (modified) clang/lib/Headers/CMakeLists.txt (+1)
- (modified) clang/lib/Headers/hlsl.h (+4)
- (added) clang/lib/Headers/hlsl/hlsl_spirv.h (+30)
- (modified) clang/lib/Sema/SemaExpr.cpp (+1)
- (modified) clang/lib/Sema/SemaLookup.cpp (+19-2)
- (modified) clang/lib/Sema/SemaTemplate.cpp (+102-1)
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+2)
- (modified) clang/lib/Sema/SemaType.cpp (+1)
- (modified) clang/lib/Sema/TreeTransform.h (+7)
- (modified) clang/lib/Serialization/ASTReader.cpp (+9)
- (modified) clang/lib/Serialization/ASTWriter.cpp (+4)
- (added) clang/test/AST/HLSL/Inputs/pch_spirv_type.hlsl (+6)
- (added) clang/test/AST/HLSL/ast-dump-SpirvType.hlsl (+27)
- (added) clang/test/AST/HLSL/pch_spirv_type.hlsl (+17)
- (modified) clang/test/AST/HLSL/vector-alias.hlsl (+52-53)
- (added) clang/test/CodeGenHLSL/inline/SpirvType.alignment.hlsl (+16)
- (added) clang/test/CodeGenHLSL/inline/SpirvType.dx.error.hlsl (+12)
- (added) clang/test/CodeGenHLSL/inline/SpirvType.hlsl (+68)
- (added) clang/test/CodeGenHLSL/inline/SpirvType.incomplete.hlsl (+14)
- (added) clang/test/CodeGenHLSL/inline/SpirvType.literal.error.hlsl (+11)
- (modified) clang/tools/libclang/CIndex.cpp (+5)
- (modified) clang/tools/libclang/CXType.cpp (+1)
- (modified) clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp (+59-13)
``````````diff
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]
``````````
</details>
https://github.com/llvm/llvm-project/pull/134034
More information about the cfe-commits
mailing list