[llvm] [DirectX] Adding support for Root Descriptors in obj2yaml/yaml2obj (PR #137259)

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Thu May 8 13:48:02 PDT 2025


================
@@ -121,16 +121,19 @@ namespace DirectX {
 struct RootParameterView {
   const dxbc::RootParameterHeader &Header;
   StringRef ParamData;
-  RootParameterView(const dxbc::RootParameterHeader &H, StringRef P)
+  RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P)
       : Header(H), ParamData(P) {}
 
-  template <typename T> Expected<T> readParameter() {
-    T Struct;
-    if (sizeof(T) != ParamData.size())
+  template <typename T, typename VersionT = T> Expected<T> readParameter() {
+    assert(sizeof(VersionT) <= sizeof(T) &&
+           "Parameter of higher version must inherit all previous version data "
+           "members");
+    if (sizeof(VersionT) != ParamData.size())
       return make_error<GenericBinaryError>(
           "Reading structure out of file bounds", object_error::parse_failed);
 
-    memcpy(&Struct, ParamData.data(), sizeof(T));
+    T Struct;
+    memcpy(&Struct, ParamData.data(), sizeof(VersionT));
----------------
bogner wrote:

memcpy-ing part of a struct is really questionable, I think we should avoid doing this this way. We can do this fairly equivalently but in a more type safe way if we define `RootDescriptorView::read` like so:
```c++

  llvm::Expected<dxbc::RST0::v1::RootDescriptor> read(uint32_t Version) {
    if (Version == 1) {
      auto Descriptor = readParameter<dxbc::RST0::v0::RootDescriptor>();
      if (Error E = Descriptor.takeError())
        return E;
      return dxbc::RST0::v1::RootDescriptor(*Descriptor);
    }
    assert(Version == 2); // or maybe error handling? I'm not sure who calls this.
    return readParameter<dxbc::RST0::v1::RootDescriptor>();
  }
```

then we just need to add a constructor for the v1 (ie, version 2) root descriptor that takes the v0 (ie, version 1) struct as an argument:
```c++
namespace v1 {
struct RootDescriptor : public v0::RootDescriptor {
  RootDescriptor() = default;
  RootDescriptor(v0::RootDescriptor &Base)
      : v0::RootDescriptor(Base), Flags(0u) {}
  // ...
```

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


More information about the llvm-commits mailing list