@@ -2691,6 +2691,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
26912691 bool isHLSLSpecificType () const ; // Any HLSL specific type
26922692 bool isHLSLBuiltinIntangibleType () const ; // Any HLSL builtin intangible type
26932693 bool isHLSLAttributedResourceType () const ;
2694+ bool isHLSLInlineSpirvType () const ;
26942695 bool isHLSLResourceRecord () const ;
26952696 bool isHLSLIntangibleType ()
26962697 const ; // Any HLSL intangible type (builtin, array, class)
@@ -6364,6 +6365,143 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
63646365 findHandleTypeOnResource (const Type *RT);
63656366};
63666367
6368+ // / Instances of this class represent operands to a SPIR-V type instruction.
6369+ class SpirvOperand {
6370+ public:
6371+ enum SpirvOperandKind : unsigned char {
6372+ Invalid, // /< Uninitialized.
6373+ ConstantId, // /< Integral value to represent as a SPIR-V OpConstant
6374+ // /< instruction ID.
6375+ Literal, // /< Integral value to represent as an immediate literal.
6376+ TypeId, // /< Type to represent as a SPIR-V type ID.
6377+
6378+ Max,
6379+ };
6380+
6381+ private:
6382+ SpirvOperandKind Kind = Invalid;
6383+
6384+ QualType ResultType;
6385+ llvm::APInt Value; // Signedness of constants is represented by ResultType.
6386+
6387+ public:
6388+ SpirvOperand () : Kind(Invalid), ResultType(), Value() {}
6389+
6390+ SpirvOperand (SpirvOperandKind Kind, QualType ResultType, llvm::APInt Value)
6391+ : Kind(Kind), ResultType(ResultType), Value(Value) {}
6392+
6393+ SpirvOperand (const SpirvOperand &Other) { *this = Other; }
6394+ ~SpirvOperand () {}
6395+
6396+ SpirvOperand &operator =(const SpirvOperand &Other) {
6397+ this ->Kind = Other.Kind ;
6398+ this ->ResultType = Other.ResultType ;
6399+ this ->Value = Other.Value ;
6400+ return *this ;
6401+ }
6402+
6403+ bool operator ==(const SpirvOperand &Other) const {
6404+ return Kind == Other.Kind && ResultType == Other.ResultType &&
6405+ Value == Other.Value ;
6406+ }
6407+
6408+ bool operator !=(const SpirvOperand &Other) const { return !(*this == Other); }
6409+
6410+ SpirvOperandKind getKind () const { return Kind; }
6411+
6412+ bool isValid () const { return Kind != Invalid && Kind < Max; }
6413+ bool isConstant () const { return Kind == ConstantId; }
6414+ bool isLiteral () const { return Kind == Literal; }
6415+ bool isType () const { return Kind == TypeId; }
6416+
6417+ llvm::APInt getValue () const {
6418+ assert ((isConstant () || isLiteral ()) &&
6419+ " This is not an operand with a value!" );
6420+ return Value;
6421+ }
6422+
6423+ QualType getResultType () const {
6424+ assert ((isConstant () || isType ()) &&
6425+ " This is not an operand with a result type!" );
6426+ return ResultType;
6427+ }
6428+
6429+ static SpirvOperand createConstant (QualType ResultType, llvm::APInt Val) {
6430+ return SpirvOperand (ConstantId, ResultType, Val);
6431+ }
6432+
6433+ static SpirvOperand createLiteral (llvm::APInt Val) {
6434+ return SpirvOperand (Literal, QualType (), Val);
6435+ }
6436+
6437+ static SpirvOperand createType (QualType T) {
6438+ return SpirvOperand (TypeId, T, llvm::APSInt ());
6439+ }
6440+
6441+ void Profile (llvm::FoldingSetNodeID &ID) const {
6442+ ID.AddInteger (Kind);
6443+ ID.AddPointer (ResultType.getAsOpaquePtr ());
6444+ Value.Profile (ID);
6445+ }
6446+ };
6447+
6448+ // / Represents an arbitrary, user-specified SPIR-V type instruction.
6449+ class HLSLInlineSpirvType final
6450+ : public Type,
6451+ public llvm::FoldingSetNode,
6452+ private llvm::TrailingObjects<HLSLInlineSpirvType, SpirvOperand> {
6453+ friend class ASTContext ; // ASTContext creates these
6454+ friend TrailingObjects;
6455+
6456+ private:
6457+ uint32_t Opcode;
6458+ uint32_t Size;
6459+ uint32_t Alignment;
6460+ size_t NumOperands;
6461+
6462+ HLSLInlineSpirvType (uint32_t Opcode, uint32_t Size, uint32_t Alignment,
6463+ ArrayRef<SpirvOperand> Operands)
6464+ : Type(HLSLInlineSpirv, QualType(), TypeDependence::None), Opcode(Opcode),
6465+ Size (Size), Alignment(Alignment), NumOperands(Operands.size()) {
6466+ for (size_t I = 0 ; I < NumOperands; I++) {
6467+ // Since Operands are stored as a trailing object, they have not been
6468+ // initialized yet. Call the constructor manually.
6469+ auto *Operand =
6470+ new (&getTrailingObjects<SpirvOperand>()[I]) SpirvOperand ();
6471+ *Operand = Operands[I];
6472+ }
6473+ }
6474+
6475+ public:
6476+ uint32_t getOpcode () const { return Opcode; }
6477+ uint32_t getSize () const { return Size; }
6478+ uint32_t getAlignment () const { return Alignment; }
6479+ ArrayRef<SpirvOperand> getOperands () const {
6480+ return {getTrailingObjects<SpirvOperand>(), NumOperands};
6481+ }
6482+
6483+ bool isSugared () const { return false ; }
6484+ QualType desugar () const { return QualType (this , 0 ); }
6485+
6486+ void Profile (llvm::FoldingSetNodeID &ID) {
6487+ Profile (ID, Opcode, Size, Alignment, getOperands ());
6488+ }
6489+
6490+ static void Profile (llvm::FoldingSetNodeID &ID, uint32_t Opcode,
6491+ uint32_t Size, uint32_t Alignment,
6492+ ArrayRef<SpirvOperand> Operands) {
6493+ ID.AddInteger (Opcode);
6494+ ID.AddInteger (Size);
6495+ ID.AddInteger (Alignment);
6496+ for (auto &Operand : Operands)
6497+ Operand.Profile (ID);
6498+ }
6499+
6500+ static bool classof (const Type *T) {
6501+ return T->getTypeClass () == HLSLInlineSpirv;
6502+ }
6503+ };
6504+
63676505class TemplateTypeParmType : public Type , public llvm ::FoldingSetNode {
63686506 friend class ASTContext ; // ASTContext creates these
63696507
@@ -8495,13 +8633,18 @@ inline bool Type::isHLSLBuiltinIntangibleType() const {
84958633}
84968634
84978635inline bool Type::isHLSLSpecificType () const {
8498- return isHLSLBuiltinIntangibleType () || isHLSLAttributedResourceType ();
8636+ return isHLSLBuiltinIntangibleType () || isHLSLAttributedResourceType () ||
8637+ isHLSLInlineSpirvType ();
84998638}
85008639
85018640inline bool Type::isHLSLAttributedResourceType () const {
85028641 return isa<HLSLAttributedResourceType>(this );
85038642}
85048643
8644+ inline bool Type::isHLSLInlineSpirvType () const {
8645+ return isa<HLSLInlineSpirvType>(this );
8646+ }
8647+
85058648inline bool Type::isTemplateTypeParmType () const {
85068649 return isa<TemplateTypeParmType>(CanonicalType);
85078650}
0 commit comments