[clang] [CIR][NFC] Extract record-rebuilding type converter from CXXABILowering (PR #228599)

Konstantinos Parasyris via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 2 18:58:40 PDT 2026


https://github.com/koparasy updated https://github.com/llvm/llvm-project/pull/228599

>From 95063ffc3fee5780cc29761119f709fcec3e678f Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <konstantinos.parasyris at intel.com>
Date: Fri, 2 Oct 2026 14:43:39 -0700
Subject: [PATCH 1/2] [CIR][NFC] Extract record-rebuilding type converter from
 CXXABILowering

CXXABILowering's type converter rebuilds identified records whose member
types change. Because identified records cannot be modified in place, each
one is recreated under a temporary name, recursive records are resolved with
a per-thread conversion stack, and the original names are restored once the
conversion is done.

This patch moves the `CIRABITypeConverter`` machinery into a reusable
 base class, `cir::RecordRewritingTypeConverter`.
`CIRABITypeConverter` now derives from it and only adds the C++ ABI specific
conversions (data member and method types).

The base class also gets a `shouldConvertRecord(RecordType)` hook, which
defaults to `true`. CXXABILowering does not override it, so its behavior is
unchanged.

TargetLowering needs the same record rebuilding to convert language address
spaces nested in record members. Today the following OpenCL code fails on
SPIR-V:
```
    struct S { __global int *p; int n; };
    kernel void k(__global int *g) {
      struct S s;
      s.p = g;
      *s.p = 1;
    }

    error: member type mismatch
```

TargetLowering converts the `get_member` result to
`!cir.ptr<!s32i, target_address_space(1)>`, but the field type inside `!rec_S`
stays `lang_address_space(offload_global)`, so the verifier rejects the op. The
same issue affects SYCL device code.

A follow-up will make TargetLowering's type converter derive from this class
and use `shouldConvertRecord` to rebuild only the records that contain
language address spaces. Records without them (e.g. all CUDA/HIP records) stay
untouched, so the operations using them stay legal.
---
 .../lib/CIR/Dialect/Transforms/CMakeLists.txt |   1 +
 .../CIR/Dialect/Transforms/CXXABILowering.cpp | 184 +----------------
 .../Transforms/RecordTypeConverter.cpp        | 185 ++++++++++++++++++
 .../Dialect/Transforms/RecordTypeConverter.h  |  76 +++++++
 4 files changed, 266 insertions(+), 180 deletions(-)
 create mode 100644 clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp
 create mode 100644 clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h

diff --git a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
index 3678fc0b253849..2d6d04fb24abc5 100644
--- a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
@@ -14,6 +14,7 @@ add_clang_library(MLIRCIRTransforms
   GotoSolver.cpp
   IdiomRecognizer.cpp
   LibOpt.cpp
+  RecordTypeConverter.cpp
 
   DEPENDS
   MLIRCIRPassIncGen
diff --git a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
index 9a0e40bd4f5068..735146b04c64f6 100644
--- a/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CXXABILowering.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "PassDetail.h"
+#include "RecordTypeConverter.h"
 #include "TargetLowering/LowerModule.h"
 
 #include "mlir/Dialect/OpenACC/OpenACCOpsDialect.h.inc"
@@ -24,7 +25,6 @@
 #include "clang/CIR/Dialect/Transforms/CIRTransformUtils.h"
 #include "clang/CIR/MissingFeatures.h"
 
-#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/TypeSwitch.h"
 
 using namespace mlir;
@@ -813,159 +813,12 @@ mlir::LogicalResult CIRVTableGetTypeInfoOpABILowering::matchAndRewrite(
 namespace {
 // A small type to handle type conversion for the the CXXABILoweringPass.
 // Even though this is a CIR-to-CIR pass, we are eliminating some CIR types.
-// Most importantly, this pass solves recursive type conversion problems by
-// keeping a call stack.
-class CIRABITypeConverter : public mlir::TypeConverter {
-
-  mlir::MLIRContext &context;
-
-  // Recursive structure detection.
-  // We store one entry per thread here, and rely on locking. This works the
-  // same way as the LLVM-IR lowering does it, which has a similar problem.
-  DenseMap<uint64_t, std::unique_ptr<SmallVector<cir::RecordType>>>
-      conversionCallStack;
-  llvm::sys::SmartRWMutex<true> callStackMutex;
-
-  // In order to let us 'change the names' back after the fact, we collect them
-  // along the way.  They should only be added/accessed via the thread-safe
-  // functions below.
-  llvm::SmallVector<cir::RecordType> convertedRecordTypes;
-  llvm::sys::SmartRWMutex<true> recordTypeMutex;
-
-  // This provides a stack for the RecordTypes being processed on the current
-  // thread, which lets us solve recursive conversions. This implementation is
-  // cribbed from the LLVMTypeConverter which solves a similar but not identical
-  // problem.
-  SmallVector<cir::RecordType> &getCurrentThreadRecursiveStack() {
-    {
-      // Most of the time, the entry already exists in the map.
-      std::shared_lock<decltype(callStackMutex)> lock(callStackMutex,
-                                                      std::defer_lock);
-      if (context.isMultithreadingEnabled())
-        lock.lock();
-      auto recursiveStack = conversionCallStack.find(llvm::get_threadid());
-      if (recursiveStack != conversionCallStack.end())
-        return *recursiveStack->second;
-    }
-
-    // First time this thread gets here, we have to get an exclusive access to
-    // insert in the map
-    std::unique_lock<decltype(callStackMutex)> lock(callStackMutex);
-    auto recursiveStackInserted = conversionCallStack.insert(
-        std::make_pair(llvm::get_threadid(),
-                       std::make_unique<SmallVector<cir::RecordType>>()));
-    return *recursiveStackInserted.first->second;
-  }
-
-  void addConvertedRecordType(cir::RecordType rt) {
-    std::unique_lock<decltype(recordTypeMutex)> lock(recordTypeMutex);
-    convertedRecordTypes.push_back(rt);
-  }
-
-  llvm::SmallVector<mlir::Type> convertRecordMemberTypes(cir::RecordType type) {
-    llvm::SmallVector<mlir::Type> loweredMemberTypes;
-    loweredMemberTypes.reserve(type.getNumElements());
-
-    if (mlir::failed(convertTypes(type.getMembers(), loweredMemberTypes)))
-      return {};
-
-    return loweredMemberTypes;
-  }
-
-  cir::RecordType convertRecordType(cir::RecordType type) {
-    // Unnamed record types can't be referred to recursively, so we can just
-    // convert this one. It also doesn't have uniqueness problems, so we can
-    // just do a conversion on it.
-    if (!type.getName()) {
-      llvm::SmallVector<mlir::Type> converted = convertRecordMemberTypes(type);
-      assert(converted.size() == type.getNumElements() &&
-             "member conversion must be one type in, one type out for the "
-             "kinds to carry over by index");
-      if (auto u = mlir::dyn_cast<cir::UnionType>(type)) {
-        mlir::Type loweredPadding;
-        if (mlir::Type pad = u.getPadding())
-          loweredPadding = convertType(pad);
-        return cir::UnionType::get(type.getContext(), converted,
-                                   type.getPacked(), loweredPadding,
-                                   u.getMemberKinds());
-      }
-      auto s = mlir::cast<cir::StructType>(type);
-      return cir::StructType::get(type.getContext(), converted,
-                                  type.getPacked(), s.getIsClass(),
-                                  s.getMemberKinds());
-    }
-
-    assert(!type.isIncomplete() || type.getMembers().empty());
-
-    // If the type has already been converted, we can just return, since there
-    // is nothing to do. Also, if it is incomplete, it can't have invalid
-    // members! So we can skip transforming it.
-    if (type.isIncomplete() || type.isABIConvertedRecord())
-      return type;
-
-    SmallVectorImpl<cir::RecordType> &recursiveStack =
-        getCurrentThreadRecursiveStack();
-
-    cir::RecordType convertedType;
-    if (mlir::isa<cir::UnionType>(type))
-      convertedType =
-          cir::UnionType::get(type.getContext(), type.getABIConvertedName());
-    else
-      convertedType =
-          cir::StructType::get(type.getContext(), type.getABIConvertedName(),
-                               mlir::cast<cir::StructType>(type).getIsClass());
-
-    // This type has already been converted, just return it.
-    if (convertedType.isComplete())
-      return convertedType;
-
-    // We put the existing 'type' into the vector if we're in the process of
-    // converting it (and pop it when we're done).  To prevent recursion,
-    // just return the 'incomplete' version, and the 'top level' version of this
-    // call will call 'complete' on it.
-    if (llvm::is_contained(recursiveStack, type))
-      return convertedType;
-
-    recursiveStack.push_back(type);
-    llvm::scope_exit popConvertingType(
-        [&recursiveStack]() { recursiveStack.pop_back(); });
-
-    SmallVector<mlir::Type> convertedMembers = convertRecordMemberTypes(type);
-    assert(convertedMembers.size() == type.getNumElements() &&
-           "member conversion must be one type in, one type out for the kinds "
-           "to carry over by index");
-
-    mlir::Type loweredPadding;
-    if (auto u = mlir::dyn_cast<cir::UnionType>(type))
-      if (mlir::Type pad = u.getPadding())
-        loweredPadding = convertType(pad);
-    convertedType.complete(convertedMembers, type.getPacked(), loweredPadding,
-                           type.getMemberKinds());
-    addConvertedRecordType(convertedType);
-    return convertedType;
-  }
-
+// The records that contain them are rebuilt by RecordRewritingTypeConverter.
+class CIRABITypeConverter : public cir::RecordRewritingTypeConverter {
 public:
   CIRABITypeConverter(mlir::MLIRContext &ctx, mlir::DataLayout &dataLayout,
                       cir::LowerModule &lowerModule)
-      : context(ctx) {
-    addConversion([&](mlir::Type type) -> mlir::Type { return type; });
-    // This is necessary in order to convert CIR pointer types that are
-    // pointing to CIR types that we are lowering in this pass.
-    addConversion([&](cir::PointerType type) -> mlir::Type {
-      mlir::Type loweredPointeeType = convertType(type.getPointee());
-      if (!loweredPointeeType)
-        return {};
-      return cir::PointerType::get(type.getContext(), loweredPointeeType,
-                                   type.getAddrSpace());
-    });
-    addConversion([&](cir::ArrayType type) -> mlir::Type {
-      mlir::Type loweredElementType = convertType(type.getElementType());
-      if (!loweredElementType)
-        return {};
-      return cir::ArrayType::get(loweredElementType, type.getSize());
-    });
-
+      : RecordRewritingTypeConverter(ctx) {
     addConversion([&](cir::DataMemberType type) -> mlir::Type {
       mlir::Type abiType =
           lowerModule.getCXXABI().lowerDataMemberType(type, *this);
@@ -975,35 +828,6 @@ class CIRABITypeConverter : public mlir::TypeConverter {
       mlir::Type abiType = lowerModule.getCXXABI().lowerMethodType(type, *this);
       return convertType(abiType);
     });
-    // This is necessary in order to convert CIR function types that have
-    // argument or return types that use CIR types that we are lowering in
-    // this pass.
-    addConversion([&](cir::FuncType type) -> mlir::Type {
-      llvm::SmallVector<mlir::Type> loweredInputTypes;
-      loweredInputTypes.reserve(type.getNumInputs());
-      if (mlir::failed(convertTypes(type.getInputs(), loweredInputTypes)))
-        return {};
-
-      mlir::Type loweredReturnType = convertType(type.getReturnType());
-      if (!loweredReturnType)
-        return {};
-
-      return cir::FuncType::get(loweredInputTypes, loweredReturnType,
-                                /*isVarArg=*/type.getVarArg());
-    });
-    addConversion([&](cir::StructType type) -> mlir::Type {
-      return convertRecordType(type);
-    });
-    addConversion([&](cir::UnionType type) -> mlir::Type {
-      return convertRecordType(type);
-    });
-  }
-
-  void restoreRecordTypeNames() {
-    std::unique_lock<decltype(recordTypeMutex)> lock(recordTypeMutex);
-
-    for (auto rt : convertedRecordTypes)
-      rt.removeABIConversionNamePrefix();
   }
 };
 } // namespace
diff --git a/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp b/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp
new file mode 100644
index 00000000000000..529cdccaaa7fa5
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp
@@ -0,0 +1,185 @@
+//===- RecordTypeConverter.cpp - Record-rebuilding type converter ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RecordTypeConverter.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/Threading.h"
+
+#include <mutex>
+#include <shared_mutex>
+
+using namespace cir;
+
+RecordRewritingTypeConverter::RecordRewritingTypeConverter(
+    mlir::MLIRContext &context)
+    : context(context) {
+  addConversion([&](mlir::Type type) -> mlir::Type { return type; });
+  // This is necessary in order to convert CIR pointer types that are pointing
+  // to CIR types that are being converted.
+  addConversion([&](cir::PointerType type) -> mlir::Type {
+    mlir::Type loweredPointeeType = convertType(type.getPointee());
+    if (!loweredPointeeType)
+      return {};
+    return cir::PointerType::get(type.getContext(), loweredPointeeType,
+                                 type.getAddrSpace());
+  });
+  addConversion([&](cir::ArrayType type) -> mlir::Type {
+    mlir::Type loweredElementType = convertType(type.getElementType());
+    if (!loweredElementType)
+      return {};
+    return cir::ArrayType::get(loweredElementType, type.getSize());
+  });
+  // This is necessary in order to convert CIR function types that have
+  // argument or return types that use CIR types that are being converted.
+  addConversion([&](cir::FuncType type) -> mlir::Type {
+    llvm::SmallVector<mlir::Type> loweredInputTypes;
+    loweredInputTypes.reserve(type.getNumInputs());
+    if (mlir::failed(convertTypes(type.getInputs(), loweredInputTypes)))
+      return {};
+
+    mlir::Type loweredReturnType = convertType(type.getReturnType());
+    if (!loweredReturnType)
+      return {};
+
+    return cir::FuncType::get(loweredInputTypes, loweredReturnType,
+                              /*isVarArg=*/type.getVarArg());
+  });
+  addConversion([&](cir::StructType type) -> mlir::Type {
+    return convertRecordType(type);
+  });
+  addConversion([&](cir::UnionType type) -> mlir::Type {
+    return convertRecordType(type);
+  });
+}
+
+void RecordRewritingTypeConverter::restoreRecordTypeNames() {
+  std::unique_lock<decltype(recordTypeMutex)> lock(recordTypeMutex);
+
+  for (auto rt : convertedRecordTypes)
+    rt.removeABIConversionNamePrefix();
+}
+
+// This provides a stack for the RecordTypes being processed on the current
+// thread, which lets us solve recursive conversions. This implementation is
+// cribbed from the LLVMTypeConverter which solves a similar but not identical
+// problem.
+llvm::SmallVector<cir::RecordType> &
+RecordRewritingTypeConverter::getCurrentThreadRecursiveStack() {
+  {
+    // Most of the time, the entry already exists in the map.
+    std::shared_lock<decltype(callStackMutex)> lock(callStackMutex,
+                                                    std::defer_lock);
+    if (context.isMultithreadingEnabled())
+      lock.lock();
+    auto recursiveStack = conversionCallStack.find(llvm::get_threadid());
+    if (recursiveStack != conversionCallStack.end())
+      return *recursiveStack->second;
+  }
+
+  // First time this thread gets here, we have to get an exclusive access to
+  // insert in the map
+  std::unique_lock<decltype(callStackMutex)> lock(callStackMutex);
+  auto recursiveStackInserted = conversionCallStack.insert(
+      std::make_pair(llvm::get_threadid(),
+                     std::make_unique<llvm::SmallVector<cir::RecordType>>()));
+  return *recursiveStackInserted.first->second;
+}
+
+void RecordRewritingTypeConverter::addConvertedRecordType(cir::RecordType rt) {
+  std::unique_lock<decltype(recordTypeMutex)> lock(recordTypeMutex);
+  convertedRecordTypes.push_back(rt);
+}
+
+llvm::SmallVector<mlir::Type>
+RecordRewritingTypeConverter::convertRecordMemberTypes(cir::RecordType type) {
+  llvm::SmallVector<mlir::Type> loweredMemberTypes;
+  loweredMemberTypes.reserve(type.getNumElements());
+
+  if (mlir::failed(convertTypes(type.getMembers(), loweredMemberTypes)))
+    return {};
+
+  return loweredMemberTypes;
+}
+
+cir::RecordType
+RecordRewritingTypeConverter::convertRecordType(cir::RecordType type) {
+  if (!shouldConvertRecord(type))
+    return type;
+
+  // Unnamed record types can't be referred to recursively, so we can just
+  // convert this one. It also doesn't have uniqueness problems, so we can
+  // just do a conversion on it.
+  if (!type.getName()) {
+    llvm::SmallVector<mlir::Type> converted = convertRecordMemberTypes(type);
+    assert(converted.size() == type.getNumElements() &&
+           "member conversion must be one type in, one type out for the "
+           "kinds to carry over by index");
+    if (auto u = mlir::dyn_cast<cir::UnionType>(type)) {
+      mlir::Type loweredPadding;
+      if (mlir::Type pad = u.getPadding())
+        loweredPadding = convertType(pad);
+      return cir::UnionType::get(type.getContext(), converted, type.getPacked(),
+                                 loweredPadding, u.getMemberKinds());
+    }
+    auto s = mlir::cast<cir::StructType>(type);
+    return cir::StructType::get(type.getContext(), converted, type.getPacked(),
+                                s.getIsClass(), s.getMemberKinds());
+  }
+
+  assert(!type.isIncomplete() || type.getMembers().empty());
+
+  // If the type has already been converted, we can just return, since there
+  // is nothing to do. Also, if it is incomplete, it can't have invalid
+  // members! So we can skip transforming it.
+  if (type.isIncomplete() || type.isABIConvertedRecord())
+    return type;
+
+  llvm::SmallVectorImpl<cir::RecordType> &recursiveStack =
+      getCurrentThreadRecursiveStack();
+
+  cir::RecordType convertedType;
+  if (mlir::isa<cir::UnionType>(type))
+    convertedType =
+        cir::UnionType::get(type.getContext(), type.getABIConvertedName());
+  else
+    convertedType =
+        cir::StructType::get(type.getContext(), type.getABIConvertedName(),
+                             mlir::cast<cir::StructType>(type).getIsClass());
+
+  // This type has already been converted, just return it.
+  if (convertedType.isComplete())
+    return convertedType;
+
+  // We put the existing 'type' into the vector if we're in the process of
+  // converting it (and pop it when we're done).  To prevent recursion,
+  // just return the 'incomplete' version, and the 'top level' version of this
+  // call will call 'complete' on it.
+  if (llvm::is_contained(recursiveStack, type))
+    return convertedType;
+
+  recursiveStack.push_back(type);
+  llvm::scope_exit popConvertingType(
+      [&recursiveStack]() { recursiveStack.pop_back(); });
+
+  llvm::SmallVector<mlir::Type> convertedMembers =
+      convertRecordMemberTypes(type);
+  assert(convertedMembers.size() == type.getNumElements() &&
+         "member conversion must be one type in, one type out for the kinds "
+         "to carry over by index");
+
+  mlir::Type loweredPadding;
+  if (auto u = mlir::dyn_cast<cir::UnionType>(type))
+    if (mlir::Type pad = u.getPadding())
+      loweredPadding = convertType(pad);
+  convertedType.complete(convertedMembers, type.getPacked(), loweredPadding,
+                         type.getMemberKinds());
+  addConvertedRecordType(convertedType);
+  return convertedType;
+}
diff --git a/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h b/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h
new file mode 100644
index 00000000000000..950355c603b89d
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h
@@ -0,0 +1,76 @@
+//===- RecordTypeConverter.h - Record-rebuilding type converter -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// A type converter base for CIR-to-CIR passes that rewrite types nested in
+// records.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_CIR_DIALECT_TRANSFORMS_RECORDTYPECONVERTER_H
+#define CLANG_LIB_CIR_DIALECT_TRANSFORMS_RECORDTYPECONVERTER_H
+
+#include "mlir/Transforms/DialectConversion.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/RWMutex.h"
+
+#include <memory>
+
+namespace cir {
+
+/// A type converter that converts the types nested in pointers, arrays,
+/// functions and records.
+///
+/// Identified records can't be modified in place, so each one is rebuilt under
+/// a temporary name (see RecordType::getABIConvertedName). The conversion keeps
+/// a stack of the records being converted, which resolves recursive records.
+/// Once the conversion is done, restoreRecordTypeNames() gives the rebuilt
+/// records their original names back.
+///
+/// Subclasses add conversions for the types they rewrite. The type converter
+/// tries the most recently added conversion first, so a subclass can also
+/// replace one of the conversions registered here.
+class RecordRewritingTypeConverter : public mlir::TypeConverter {
+public:
+  explicit RecordRewritingTypeConverter(mlir::MLIRContext &context);
+  virtual ~RecordRewritingTypeConverter() = default;
+
+  /// Remove the temporary name of every record rebuilt by this converter.
+  void restoreRecordTypeNames();
+
+protected:
+  /// Whether \p type has to be rebuilt. Rebuilding every record is always
+  /// correct, but makes every operation that uses one illegal.
+  virtual bool shouldConvertRecord(cir::RecordType type) { return true; }
+
+private:
+  cir::RecordType convertRecordType(cir::RecordType type);
+  llvm::SmallVector<mlir::Type> convertRecordMemberTypes(cir::RecordType type);
+  llvm::SmallVector<cir::RecordType> &getCurrentThreadRecursiveStack();
+  void addConvertedRecordType(cir::RecordType rt);
+
+  mlir::MLIRContext &context;
+
+  // Recursive structure detection.
+  // We store one entry per thread here, and rely on locking. This works the
+  // same way as the LLVM-IR lowering does it, which has a similar problem.
+  llvm::DenseMap<uint64_t, std::unique_ptr<llvm::SmallVector<cir::RecordType>>>
+      conversionCallStack;
+  llvm::sys::SmartRWMutex<true> callStackMutex;
+
+  // In order to let us 'change the names' back after the fact, we collect them
+  // along the way. They should only be added/accessed via the thread-safe
+  // functions.
+  llvm::SmallVector<cir::RecordType> convertedRecordTypes;
+  llvm::sys::SmartRWMutex<true> recordTypeMutex;
+};
+
+} // namespace cir
+
+#endif // CLANG_LIB_CIR_DIALECT_TRANSFORMS_RECORDTYPECONVERTER_H

>From 3f6587fe2b42ae30370b943af51844198bea1a7f Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <konstantinos.parasyris at intel.com>
Date: Fri, 2 Oct 2026 16:45:32 -0700
Subject: [PATCH 2/2] Remove hook

---
 clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp | 3 ---
 clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h   | 5 -----
 2 files changed, 8 deletions(-)

diff --git a/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp b/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp
index 529cdccaaa7fa5..52c355c340519b 100644
--- a/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.cpp
@@ -110,9 +110,6 @@ RecordRewritingTypeConverter::convertRecordMemberTypes(cir::RecordType type) {
 
 cir::RecordType
 RecordRewritingTypeConverter::convertRecordType(cir::RecordType type) {
-  if (!shouldConvertRecord(type))
-    return type;
-
   // Unnamed record types can't be referred to recursively, so we can just
   // convert this one. It also doesn't have uniqueness problems, so we can
   // just do a conversion on it.
diff --git a/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h b/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h
index 950355c603b89d..1b7b1fbc1ad34c 100644
--- a/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h
+++ b/clang/lib/CIR/Dialect/Transforms/RecordTypeConverter.h
@@ -44,11 +44,6 @@ class RecordRewritingTypeConverter : public mlir::TypeConverter {
   /// Remove the temporary name of every record rebuilt by this converter.
   void restoreRecordTypeNames();
 
-protected:
-  /// Whether \p type has to be rebuilt. Rebuilding every record is always
-  /// correct, but makes every operation that uses one illegal.
-  virtual bool shouldConvertRecord(cir::RecordType type) { return true; }
-
 private:
   cir::RecordType convertRecordType(cir::RecordType type);
   llvm::SmallVector<mlir::Type> convertRecordMemberTypes(cir::RecordType type);



More information about the cfe-commits mailing list