[clang] [llvm] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)

Alex Sepkowski via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 12 09:44:06 PDT 2025


================
@@ -89,14 +99,57 @@ llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType(
     RecordTypes.pop_back();
 
     for (const auto *FD : RT->getDecl()->fields()) {
-      assert((!Packoffsets || Index < Packoffsets->size()) &&
-             "number of elements in layout struct does not "
-             "match number of packoffset annotations");
+      unsigned FieldOffset = UINT_MAX;
+      llvm::Type *FieldType = nullptr;
+
+      if (Packoffsets) {
+        // have packoffset/register(c#) annotations
+        assert(Index < Packoffsets->size() &&
+               "number of elements in layout struct does not match number of "
+               "packoffset annotations");
+        int PO = (*Packoffsets)[Index++];
+        if (PO != -1) {
+          if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO))
+            return nullptr;
+        } else {
+          // No packoffset/register(cX) annotation on this field;
+          // Delay the layout until after all of the other elements
+          // annotated with packoffsets/register(cX) are processed.
+          DelayLayoutFields.emplace_back(FD, LayoutElements.size());
+          // reserve space for this field in the layout vector and elements list
+          Layout.push_back(UINT_MAX);
+          LayoutElements.push_back(nullptr);
+          continue;
+        }
+      } else {
+        if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
+          return nullptr;
+      }
+
+      assert(FieldOffset != UINT_MAX && FieldType != nullptr);
+      Layout.push_back((unsigned)FieldOffset);
+      LayoutElements.push_back(FieldType);
+    }
+  }
 
-      if (!layoutField(FD, EndOffset, Layout, LayoutElements,
-                       Packoffsets ? (*Packoffsets)[Index] : -1))
+  // process delayed layouts
+  if (!DelayLayoutFields.empty()) {
+    for (auto I : DelayLayoutFields) {
+      const FieldDecl *FD = I.first;
+      unsigned IndexInLayoutElements = I.second;
+      // the first item in layout vector is size, so we need to offset the index
+      // by 1
+      unsigned IndexInLayout = IndexInLayoutElements + 1;
+      assert(Layout[IndexInLayout] == UINT_MAX &&
+             LayoutElements[IndexInLayoutElements] == nullptr);
+
+      unsigned FieldOffset = UINT_MAX;
+      llvm::Type *FieldType = nullptr;
+      if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
         return nullptr;
-      Index++;
+
+      Layout[IndexInLayout] = (unsigned)FieldOffset;
----------------
alsepkow wrote:

Cast no longer needed

https://github.com/llvm/llvm-project/pull/128991


More information about the cfe-commits mailing list