@@ -66,8 +66,9 @@ namespace CodeGen {
6666// annotation though. For those that don't, the PackOffsets array will contain
6767// -1 value instead. These elements must be placed at the end of the layout
6868// after all of the elements with specific offset.
69- llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType (
70- const RecordType *RT, const llvm::SmallVector<int32_t > *PackOffsets) {
69+ llvm::TargetExtType *
70+ HLSLBufferLayoutBuilder::createLayoutType (const RecordType *RT,
71+ const CGHLSLOffsetInfo &OffsetInfo) {
7172
7273 // check if we already have the layout type for this struct
7374 if (llvm::TargetExtType *Ty =
@@ -101,14 +102,10 @@ llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType(
101102 const CXXRecordDecl *RD = RecordDecls.pop_back_val ();
102103
103104 for (const auto *FD : RD->fields ()) {
104- assert ((!PackOffsets || Index < PackOffsets->size ()) &&
105- " number of elements in layout struct does not match number of "
106- " packoffset annotations" );
107-
108105 // No PackOffset info at all, or have a valid packoffset/register(c#)
109106 // annotations value -> layout the field.
110- const int PO = PackOffsets ? (*PackOffsets) [Index++] : - 1 ;
111- if (!PackOffsets || PO != - 1 ) {
107+ const uint32_t PO = OffsetInfo [Index++];
108+ if (PO != CGHLSLOffsetInfo::Unspecified ) {
112109 if (!layoutField (FD, EndOffset, FieldOffset, FieldType, PO))
113110 return nullptr ;
114111 Layout.push_back (FieldOffset);
@@ -175,7 +172,7 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD,
175172 unsigned &EndOffset,
176173 unsigned &FieldOffset,
177174 llvm::Type *&FieldType,
178- int Packoffset) {
175+ uint32_t Packoffset) {
179176
180177 // Size of element; for arrays this is a size of a single element in the
181178 // array. Total array size of calculated as (ArrayCount-1) * ArrayStride +
@@ -201,8 +198,10 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD,
201198 // For array of structures, create a new array with a layout type
202199 // instead of the structure type.
203200 if (Ty->isStructureOrClassType ()) {
201+ // TODO: Can we have offsets if we get here from `ConstantBuffer<T>`?
202+ CGHLSLOffsetInfo EmptyOffsets;
204203 llvm::Type *NewTy = cast<llvm::TargetExtType>(
205- createLayoutType (Ty->getAsCanonical <RecordType>()));
204+ createLayoutType (Ty->getAsCanonical <RecordType>(), EmptyOffsets ));
206205 if (!NewTy)
207206 return false ;
208207 assert (isa<llvm::TargetExtType>(NewTy) && " expected target type" );
@@ -216,17 +215,21 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD,
216215 ElemLayoutTy = CGM.getTypes ().ConvertTypeForMem (FieldTy);
217216 }
218217 ArrayStride = llvm::alignTo (ElemSize, CBufferRowSizeInBytes);
219- ElemOffset = (Packoffset != -1 ) ? Packoffset : NextRowOffset;
218+ ElemOffset = (Packoffset != CGHLSLOffsetInfo::Unspecified) ? Packoffset
219+ : NextRowOffset;
220220
221221 } else if (FieldTy->isStructureOrClassType ()) {
222222 // Create a layout type for the structure
223+ // TODO: Can we have offsets if we get here from `ConstantBuffer<T>`?
224+ CGHLSLOffsetInfo EmptyOffsets;
223225 ElemLayoutTy = createLayoutType (
224- cast<RecordType>(FieldTy->getAsCanonical <RecordType>()));
226+ cast<RecordType>(FieldTy->getAsCanonical <RecordType>()), EmptyOffsets );
225227 if (!ElemLayoutTy)
226228 return false ;
227229 assert (isa<llvm::TargetExtType>(ElemLayoutTy) && " expected target type" );
228230 ElemSize = cast<llvm::TargetExtType>(ElemLayoutTy)->getIntParameter (0 );
229- ElemOffset = (Packoffset != -1 ) ? Packoffset : NextRowOffset;
231+ ElemOffset = (Packoffset != CGHLSLOffsetInfo::Unspecified) ? Packoffset
232+ : NextRowOffset;
230233
231234 } else {
232235 // scalar or vector - find element size and alignment
@@ -246,7 +249,7 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD,
246249 }
247250
248251 // calculate or get element offset for the vector or scalar
249- if (Packoffset != - 1 ) {
252+ if (Packoffset != CGHLSLOffsetInfo::Unspecified ) {
250253 ElemOffset = Packoffset;
251254 } else {
252255 ElemOffset = llvm::alignTo (EndOffset, Align);
@@ -269,5 +272,13 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD,
269272 return true ;
270273}
271274
275+ bool HLSLBufferLayoutBuilder::layoutField (const FieldDecl *FD,
276+ unsigned &EndOffset,
277+ unsigned &FieldOffset,
278+ llvm::Type *&FieldType) {
279+ return layoutField (FD, EndOffset, FieldOffset, FieldType,
280+ CGHLSLOffsetInfo::Unspecified);
281+ }
282+
272283} // namespace CodeGen
273284} // namespace clang
0 commit comments