36 if (llvm::StructType *Ty = CGM.getHLSLRuntime().getHLSLBufferLayoutType(RT))
41 RecordDecls.push_back(RT->castAsCXXRecordDecl());
42 while (RecordDecls.back()->getNumBases()) {
45 "HLSL doesn't support multiple inheritance");
50 unsigned OffsetIdx = 0;
52 for (
const auto *FD : RD->fields())
53 FieldsWithOffset.emplace_back(FD, OffsetInfo[OffsetIdx++]);
55 if (!OffsetInfo.
empty())
56 llvm::stable_sort(FieldsWithOffset, [](
const auto &LHS,
const auto &RHS) {
62 for (
auto &[FD, Offset] : FieldsWithOffset) {
63 llvm::Type *LayoutType =
layOutType(FD->getType());
65 const llvm::DataLayout &DL = CGM.getDataLayout();
70 if (LayoutType->isAggregateType() ||
78 assert(PackOffset >= NextOffset &&
79 "Offset is invalid - would overlap with previous object");
80 NextOffset = PackOffset;
83 if (NextOffset > CurrentOffset) {
84 llvm::Type *Padding = CGM.getTargetCodeGenInfo().getHLSLPadding(
85 CGM, NextOffset - CurrentOffset);
86 assert(Padding &&
"No padding type for target?");
87 Layout.emplace_back(Padding);
88 CurrentOffset = NextOffset;
90 Layout.emplace_back(LayoutType);
91 CurrentOffset += Size;
96 const auto *
Decl = RT->castAsCXXRecordDecl();
98 Decl->getName().empty() ?
"anon" :
Decl->getQualifiedNameAsString();
100 llvm::StructType *NewTy = llvm::StructType::create(Layout, Name,
102 CGM.getHLSLRuntime().addHLSLBufferLayoutType(RT, NewTy);
116 if (Count < 2 || Padding.
isZero())
117 return llvm::ArrayType::get(EltTy, Count);
119 llvm::LLVMContext &Context = CGM.getLLVMContext();
120 llvm::Type *PaddingTy =
121 CGM.getTargetCodeGenInfo().getHLSLPadding(CGM, Padding);
122 assert(PaddingTy &&
"No padding type for target?");
124 llvm::StructType::get(Context, {EltTy, PaddingTy},
true);
125 return llvm::StructType::get(
126 Context, {llvm::ArrayType::get(PaddedEltTy, Count - 1), EltTy},
131 if (
const auto *AT = CGM.getContext().getAsConstantArrayType(Ty))
139 return CGM.getTypes().ConvertTypeForMem(Ty);
static const CharUnits CBufferRowSize
C Language Family Type Representation.
QualType getElementType() const
QualType getType() const
Retrieves the type of the base class.
Represents a C++ struct/union/class.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
static const uint32_t Unspecified
static bool compareOffsets(uint32_t LHS, uint32_t RHS)
Comparison function for offsets received from operator[] suitable for use in a stable_sort.
llvm::StructType * layOutStruct(const RecordType *StructType, const CGHLSLOffsetInfo &OffsetInfo)
Lays out a struct type following HLSL buffer rules and considering any explicit offset information.
llvm::Type * layOutArray(const ConstantArrayType *AT)
Lays out an array type following HLSL buffer rules.
llvm::Type * layOutType(QualType Type)
Lays out a type following HLSL buffer rules.
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
A (possibly-)qualified type.
CXXRecordDecl * castAsCXXRecordDecl() const
bool isStructureOrClassType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
The JSON file list parser is used to communicate input to InstallAPI.