================ @@ -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]; + } ---------------- llvm-beanz wrote:
nit: https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements ```suggestion for (size_t I = 0; I < NumOperands; I++) getTrailingObjects<SpirvOperand>()[I] = Operands[I]; ``` https://github.com/llvm/llvm-project/pull/134034 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits