llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Narayan (vortex73)

<details>
<summary>Changes</summary>

This PR introduces the `QualTypeMapper` class, which bridges Clang's type 
system with the LLVM ABI type system introduced in 
https://github.com/llvm/llvm-project/pull/158329.

The `QualTypeMapper` translates Clang `QualType` instances into their 
corresponding LLVM ABI type representations, preserving all ABI-relevant 
information while abstracting away frontend-specific details. 

The mapper queries the `ASTContext` for layout information computed by the 
frontend and uses the `TypeBuilder` API(from the above merged PR) to construct 
the corresponding ABI types. This separation ensures that ABI logic remains 
independent of frontend AST details while still having access to all necessary 
type information.

This is a prerequisite for implementing target-specific ABI lowering, as 
demonstrated in https://github.com/llvm/llvm-project/pull/140112

---

Patch is 25.60 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/174634.diff


3 Files Affected:

- (added) clang/include/clang/CodeGen/QualTypeMapper.h (+81) 
- (modified) clang/lib/CodeGen/CMakeLists.txt (+1) 
- (added) clang/lib/CodeGen/QualTypeMapper.cpp (+556) 


``````````diff
diff --git a/clang/include/clang/CodeGen/QualTypeMapper.h 
b/clang/include/clang/CodeGen/QualTypeMapper.h
new file mode 100644
index 0000000000000..81dd074cdad05
--- /dev/null
+++ b/clang/include/clang/CodeGen/QualTypeMapper.h
@@ -0,0 +1,81 @@
+//==---- QualTypeMapper.h - Maps Clang QualType to LLVMABI Types 
-----------==//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Maps Clang QualType instances to corresponding LLVM ABI type
+/// representations. This mapper translates high-level type information from 
the
+/// AST into low-level ABI-specific types that encode size, alignment, and
+/// layout details required for code generation and cross-language
+/// interoperability.
+///
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_CODEGEN_QUALTYPE_MAPPER_H
+#define CLANG_CODEGEN_QUALTYPE_MAPPER_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeOrdering.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+namespace CodeGen {
+
+class QualTypeMapper {
+private:
+  clang::ASTContext &ASTCtx;
+  llvm::abi::TypeBuilder Builder;
+
+  llvm::DenseMap<QualType, const llvm::abi::Type *> TypeCache;
+
+  const llvm::abi::Type *convertBuiltinType(const clang::BuiltinType *BT);
+  const llvm::abi::Type *convertPointerType(const clang::PointerType *PT);
+  const llvm::abi::Type *convertArrayType(const clang::ArrayType *AT);
+  const llvm::abi::Type *convertVectorType(const clang::VectorType *VT);
+  const llvm::abi::Type *convertRecordType(const clang::RecordType *RT);
+  const llvm::abi::Type *convertEnumType(const clang::EnumType *ET);
+  const llvm::abi::Type *convertReferenceType(const ReferenceType *RT);
+  const llvm::abi::Type *convertComplexType(const ComplexType *CT);
+  const llvm::abi::Type *
+  convertMemberPointerType(const clang::MemberPointerType *MPT);
+  const llvm::abi::Type *convertMatrixType(const ConstantMatrixType *MT);
+
+  const llvm::abi::RecordType *convertStructType(const clang::RecordDecl *RD);
+  const llvm::abi::RecordType *convertUnionType(const clang::RecordDecl *RD,
+                                                bool IsTransparent = false);
+  const llvm::abi::Type *createPointerTypeForPointee(QualType PointeeType);
+  const llvm::abi::RecordType *convertCXXRecordType(const CXXRecordDecl *RD,
+                                                    bool CanPassInRegs);
+
+  void computeFieldInfo(const clang::RecordDecl *RD,
+                        SmallVectorImpl<llvm::abi::FieldInfo> &Fields,
+                        const clang::ASTRecordLayout &Layout);
+
+  llvm::TypeSize getTypeSize(clang::QualType QT) const;
+  llvm::Align getTypeAlign(clang::QualType QT) const;
+  llvm::Align getPreferredTypeAlign(QualType QT) const;
+  uint64_t getPointerSize() const;
+  uint64_t getPointerAlign() const;
+
+public:
+  explicit QualTypeMapper(clang::ASTContext &Ctx, llvm::BumpPtrAllocator 
&Alloc)
+      : ASTCtx(Ctx), Builder(Alloc) {}
+
+  const llvm::abi::Type *convertType(clang::QualType QT);
+
+  void clearCache() { TypeCache.clear(); }
+
+  llvm::abi::TypeBuilder getTypeBuilder() { return Builder; }
+};
+
+} // namespace CodeGen
+} // namespace clang
+
+#endif // CLANG_CODEGEN_QUALTYPE_MAPPER_H
diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt
index dbbc35b372f42..434781b3c4f02 100644
--- a/clang/lib/CodeGen/CMakeLists.txt
+++ b/clang/lib/CodeGen/CMakeLists.txt
@@ -116,6 +116,7 @@ add_clang_library(clangCodeGen
   ModuleBuilder.cpp
   ObjectFilePCHContainerWriter.cpp
   PatternInit.cpp
+  QualTypeMapper.cpp
   SanitizerMetadata.cpp
   SwiftCallingConv.cpp
   TargetBuiltins/ARM.cpp
diff --git a/clang/lib/CodeGen/QualTypeMapper.cpp 
b/clang/lib/CodeGen/QualTypeMapper.cpp
new file mode 100644
index 0000000000000..ea88d345174fd
--- /dev/null
+++ b/clang/lib/CodeGen/QualTypeMapper.cpp
@@ -0,0 +1,556 @@
+//==---- QualTypeMapper.cpp - Maps Clang QualType to LLVMABI Types 
---------==//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Maps Clang QualType instances to corresponding LLVM ABI type
+/// representations. This mapper translates high-level type information from 
the
+/// AST into low-level ABI-specific types that encode size, alignment, and
+/// layout details required for code generation and cross-language
+/// interoperability.
+///
+//===----------------------------------------------------------------------===//
+#include "clang/CodeGen/QualTypeMapper.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTFwd.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TypeSize.h"
+#include <cstdint>
+
+namespace clang {
+namespace CodeGen {
+
+/// Main entry point for converting Clang QualType to LLVM ABI Type.
+/// This method performs type canonicalization, caching, and dispatches
+/// to specialized conversion methods based on the type kind.
+///
+/// \param QT The Clang QualType to convert
+/// \return Corresponding LLVM ABI Type representation, or nullptr on error
+const llvm::abi::Type *QualTypeMapper::convertType(QualType QT) {
+  // Canonicalize type and strip qualifiers
+  // This ensures consistent type representation across different contexts
+  QT = QT.getCanonicalType().getUnqualifiedType();
+
+  // Results are cached since type conversion may be expensive
+  auto It = TypeCache.find(QT);
+  if (It != TypeCache.end())
+    return It->second;
+
+  const llvm::abi::Type *Result = nullptr;
+  if (const auto *BT = dyn_cast<BuiltinType>(QT.getTypePtr()))
+    Result = convertBuiltinType(BT);
+  else if (const auto *PT = dyn_cast<PointerType>(QT.getTypePtr()))
+    Result = convertPointerType(PT);
+  else if (const auto *RT = dyn_cast<ReferenceType>(QT.getTypePtr()))
+    Result = convertReferenceType(RT);
+  else if (const auto *AT = dyn_cast<ArrayType>(QT.getTypePtr()))
+    Result = convertArrayType(AT);
+  else if (const auto *VT = dyn_cast<VectorType>(QT.getTypePtr()))
+    Result = convertVectorType(VT);
+  else if (const auto *RT = dyn_cast<RecordType>(QT.getTypePtr()))
+    Result = convertRecordType(RT);
+  else if (const auto *ET = dyn_cast<EnumType>(QT.getTypePtr()))
+    Result = convertEnumType(ET);
+  else if (const auto *CT = dyn_cast<ComplexType>(QT.getTypePtr()))
+    Result = convertComplexType(CT);
+  else if (const auto *AT = dyn_cast<AtomicType>(QT.getTypePtr()))
+    return convertType(AT->getValueType());
+  else if (isa<BlockPointerType>(QT.getTypePtr()))
+    return createPointerTypeForPointee(ASTCtx.VoidPtrTy);
+  else if (isa<PipeType>(QT.getTypePtr()))
+    Result = createPointerTypeForPointee(ASTCtx.VoidPtrTy);
+  else if (const auto *MT = dyn_cast<ConstantMatrixType>(QT.getTypePtr())) {
+    const llvm::abi::Type *ElementType = convertType(MT->getElementType());
+    uint64_t NumElements = MT->getNumRows() * MT->getNumColumns();
+    return Builder.getArrayType(ElementType, NumElements,
+                                ASTCtx.getTypeSize(QT), true);
+  } else if (const auto *MPT = dyn_cast<MemberPointerType>(QT.getTypePtr()))
+    Result = convertMemberPointerType(MPT);
+  else if (const auto *BIT = dyn_cast<BitIntType>(QT.getTypePtr())) {
+    unsigned RawNumBits = BIT->getNumBits();
+    bool IsSigned = BIT->isSigned();
+    llvm::Align TypeAlign = getTypeAlign(QT);
+    return Builder.getIntegerType(RawNumBits, TypeAlign, IsSigned, true);
+  } else if (isa<ObjCObjectType>(QT.getTypePtr()) ||
+             isa<ObjCObjectPointerType>(QT.getTypePtr())) {
+    // Objective-C objects are represented as pointers in the ABI
+    auto PointerSize =
+        ASTCtx.getTargetInfo().getPointerWidth(QT.getAddressSpace());
+    llvm::Align PointerAlign =
+        llvm::Align(ASTCtx.getTargetInfo().getPointerAlign(LangAS::Default));
+    return Builder.getPointerType(
+        PointerSize, llvm::Align(PointerAlign.value() / 8),
+        ASTCtx.getTargetInfo().getTargetAddressSpace(QT.getAddressSpace()));
+  } else
+    llvm_unreachable("Unsupported type for ABI lowering!");
+
+  if (Result)
+    TypeCache[QT] = Result;
+  return Result;
+}
+
+/// Converts C/C++ builtin types to LLVM ABI types.
+/// This handles all fundamental scalar types including integers, floats,
+/// and special types like void and bool.
+///
+/// \param BT The BuiltinType to convert
+/// \return Corresponding LLVM ABI integer, float, or void type
+const llvm::abi::Type *
+QualTypeMapper::convertBuiltinType(const BuiltinType *BT) {
+  QualType QT(BT, 0);
+
+  switch (BT->getKind()) {
+  case BuiltinType::Void:
+    return Builder.getVoidType();
+
+  case BuiltinType::NullPtr:
+    return createPointerTypeForPointee(QT);
+
+  case BuiltinType::Bool:
+    return Builder.getIntegerType(1, getTypeAlign(QT), false, false);
+  case BuiltinType::Char_S:
+  case BuiltinType::Char_U:
+  case BuiltinType::SChar:
+  case BuiltinType::UChar:
+  case BuiltinType::WChar_S:
+  case BuiltinType::WChar_U:
+  case BuiltinType::Char8:
+  case BuiltinType::Char16:
+  case BuiltinType::Char32:
+  case BuiltinType::Short:
+  case BuiltinType::UShort:
+  case BuiltinType::Int:
+  case BuiltinType::UInt:
+  case BuiltinType::Long:
+  case BuiltinType::ULong:
+  case BuiltinType::LongLong:
+  case BuiltinType::ULongLong:
+  case BuiltinType::Int128:
+  case BuiltinType::UInt128:
+    return Builder.getIntegerType(ASTCtx.getTypeSize(QT), getTypeAlign(QT),
+                                  BT->isSignedInteger(), false);
+
+  case BuiltinType::Half:
+  case BuiltinType::Float16:
+  case BuiltinType::BFloat16:
+  case BuiltinType::Float:
+  case BuiltinType::Double:
+  case BuiltinType::LongDouble:
+  case BuiltinType::Float128:
+    return Builder.getFloatType(ASTCtx.getFloatTypeSemantics(QT),
+                                getTypeAlign(QT));
+
+  case BuiltinType::OCLImage1dRO:
+  case BuiltinType::OCLImage1dWO:
+  case BuiltinType::OCLImage1dRW:
+  case BuiltinType::OCLImage1dArrayRO:
+  case BuiltinType::OCLImage1dArrayWO:
+  case BuiltinType::OCLImage1dArrayRW:
+  case BuiltinType::OCLImage1dBufferRO:
+  case BuiltinType::OCLImage1dBufferWO:
+  case BuiltinType::OCLImage1dBufferRW:
+  case BuiltinType::OCLImage2dRO:
+  case BuiltinType::OCLImage2dWO:
+  case BuiltinType::OCLImage2dRW:
+  case BuiltinType::OCLImage2dArrayRO:
+  case BuiltinType::OCLImage2dArrayWO:
+  case BuiltinType::OCLImage2dArrayRW:
+  case BuiltinType::OCLImage2dDepthRO:
+  case BuiltinType::OCLImage2dDepthWO:
+  case BuiltinType::OCLImage2dDepthRW:
+  case BuiltinType::OCLImage2dArrayDepthRO:
+  case BuiltinType::OCLImage2dArrayDepthWO:
+  case BuiltinType::OCLImage2dArrayDepthRW:
+  case BuiltinType::OCLImage2dMSAARO:
+  case BuiltinType::OCLImage2dMSAAWO:
+  case BuiltinType::OCLImage2dMSAARW:
+  case BuiltinType::OCLImage2dArrayMSAARO:
+  case BuiltinType::OCLImage2dArrayMSAAWO:
+  case BuiltinType::OCLImage2dArrayMSAARW:
+  case BuiltinType::OCLImage2dMSAADepthRO:
+  case BuiltinType::OCLImage2dMSAADepthWO:
+  case BuiltinType::OCLImage2dMSAADepthRW:
+  case BuiltinType::OCLImage2dArrayMSAADepthRO:
+  case BuiltinType::OCLImage2dArrayMSAADepthWO:
+  case BuiltinType::OCLImage2dArrayMSAADepthRW:
+  case BuiltinType::OCLImage3dRO:
+  case BuiltinType::OCLImage3dWO:
+  case BuiltinType::OCLImage3dRW:
+    return createPointerTypeForPointee(QT);
+
+  case BuiltinType::OCLSampler:
+  case BuiltinType::OCLEvent:
+  case BuiltinType::OCLQueue:
+    return createPointerTypeForPointee(QT);
+
+  default:
+    // Unhandled BuiltinTypes are treated as unsigned integers.
+    return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)),
+                                  getTypeAlign(QualType(BT, 0)), false);
+  }
+}
+
+/// Converts array types to LLVM ABI array representations.
+/// Handles different array kinds: constant arrays, incomplete arrays,
+/// and variable-length arrays.
+///
+/// \param AT The ArrayType to convert
+/// \return LLVM ABI ArrayType or PointerType
+const llvm::abi::Type *
+QualTypeMapper::convertArrayType(const clang::ArrayType *AT) {
+  const llvm::abi::Type *ElementType = convertType(AT->getElementType());
+  uint64_t Size = ASTCtx.getTypeSize(AT);
+
+  if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
+    auto NumElements = CAT->getZExtSize();
+    return Builder.getArrayType(ElementType, NumElements, Size);
+  }
+  if (isa<IncompleteArrayType>(AT))
+    return Builder.getArrayType(ElementType, 0, 0);
+  if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
+    return createPointerTypeForPointee(VAT->getPointeeType());
+  // Fallback for other array types
+  return Builder.getArrayType(ElementType, 1, Size);
+}
+
+const llvm::abi::Type *QualTypeMapper::convertVectorType(const VectorType *VT) 
{
+  const llvm::abi::Type *ElementType = convertType(VT->getElementType());
+  QualType VectorQualType(VT, 0);
+
+  // Handle element size adjustments for sub-byte types
+  if (auto *IT = llvm::dyn_cast<llvm::abi::IntegerType>(ElementType)) {
+    unsigned BW = IT->getSizeInBits().getFixedValue();
+    if (BW != 1 && (BW & 7)) {
+      BW = llvm::bit_ceil(BW);
+      BW = std::clamp(BW, 8u, 64u);
+      ElementType =
+          Builder.getIntegerType(BW, llvm::Align(BW / 8), IT->isSigned());
+    } else if (BW < 8 && BW != 1)
+      ElementType = Builder.getIntegerType(8, llvm::Align(1), IT->isSigned());
+  }
+
+  unsigned NElems = VT->getNumElements();
+  uint64_t LogicalSizeInBits =
+      NElems * ElementType->getSizeInBits().getFixedValue();
+
+  // Only round up for small vectors (≤ 64 bits)
+  if (LogicalSizeInBits <= 64) {
+    uint64_t ABISizeInBits = ASTCtx.getTypeSize(VectorQualType);
+    if (ABISizeInBits > LogicalSizeInBits) {
+      uint64_t ElementSizeInBits = 
ElementType->getSizeInBits().getFixedValue();
+      NElems = ABISizeInBits / ElementSizeInBits;
+    }
+  }
+  // For larger vectors, keep exact element count
+
+  llvm::ElementCount NumElements = llvm::ElementCount::getFixed(NElems);
+  llvm::Align VectorAlign = getTypeAlign(VectorQualType);
+
+  return Builder.getVectorType(ElementType, NumElements, VectorAlign);
+}
+
+/// Converts complex types to LLVM ABI complex representations.
+/// Complex types consist of two components of the element type
+/// (real and imaginary parts).
+///
+/// \param CT The ComplexType to convert
+/// \return LLVM ABI ComplexType with element type and alignment
+const llvm::abi::Type *
+QualTypeMapper::convertComplexType(const ComplexType *CT) {
+  const llvm::abi::Type *ElementType = convertType(CT->getElementType());
+  llvm::Align ComplexAlign = getTypeAlign(QualType(CT, 0));
+
+  return Builder.getComplexType(ElementType, ComplexAlign);
+}
+
+/// Converts member pointer types to LLVM ABI representations.
+/// Member pointers have different layouts depending on whether they
+/// point to functions or data members.
+///
+/// \param MPT The MemberPointerType to convert
+/// \return LLVM ABI MemberPointerType
+const llvm::abi::Type *
+QualTypeMapper::convertMemberPointerType(const clang::MemberPointerType *MPT) {
+  QualType QT(MPT, 0);
+  uint64_t Size = ASTCtx.getTypeSize(QT);
+  llvm::Align Align = getTypeAlign(QT);
+
+  bool IsFunctionPointer = MPT->isMemberFunctionPointerType();
+
+  return Builder.getMemberPointerType(IsFunctionPointer, Size, Align);
+}
+
+/// Converts record types (struct/class/union) to LLVM ABI representations.
+/// This is the main dispatch method that handles different record kinds
+/// and delegates to specialized converters.
+///
+/// \param RT The RecordType to convert
+/// \return LLVM ABI RecordType
+const llvm::abi::Type *QualTypeMapper::convertRecordType(const RecordType *RT) 
{
+  const RecordDecl *RD = RT->getDecl()->getDefinition();
+  bool canPassInRegs = false;
+  if (RD) {
+    canPassInRegs = RD->canPassInRegisters();
+  }
+  if (!RD) {
+    SmallVector<llvm::abi::FieldInfo, 0> Fields;
+    return Builder.getRecordType(Fields, llvm::TypeSize::getFixed(0),
+                                 llvm::Align(1),
+                                 llvm::abi::StructPacking::Default, {}, {},
+                                 llvm::abi::RecordFlags::None);
+  }
+
+  if (RD->isUnion()) {
+    const RecordDecl *UD = RT->getDecl();
+    if (UD->hasAttr<TransparentUnionAttr>())
+      return convertUnionType(RD, true);
+    return convertUnionType(RD);
+  }
+
+  // Handle C++ classes with base classes
+  auto *const CXXRd = dyn_cast<CXXRecordDecl>(RD);
+  if (CXXRd && (CXXRd->getNumBases() > 0 || CXXRd->getNumVBases() > 0))
+    return convertCXXRecordType(CXXRd, canPassInRegs);
+  return convertStructType(RD);
+}
+
+/// Converts C++ classes with inheritance to LLVM ABI struct representations.
+/// This method handles the complex layout of C++ objects including:
+/// - Virtual table pointers for polymorphic classes
+/// - Base class subobjects (both direct and virtual bases)
+/// - Member field layout with proper offsets
+///
+/// \param RD The C++ record declaration
+/// \return LLVM ABI RecordType representing the complete object layout
+const llvm::abi::RecordType *
+QualTypeMapper::convertCXXRecordType(const CXXRecordDecl *RD,
+                                     bool canPassInRegs) {
+  const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD);
+  SmallVector<llvm::abi::FieldInfo, 16> Fields;
+  SmallVector<llvm::abi::FieldInfo, 8> BaseClasses;
+  SmallVector<llvm::abi::FieldInfo, 8> VirtualBaseClasses;
+
+  // Add vtable pointer for polymorphic classes
+  if (RD->isPolymorphic()) {
+    const llvm::abi::Type *VtablePointer =
+        createPointerTypeForPointee(ASTCtx.VoidPtrTy);
+    Fields.emplace_back(VtablePointer, 0);
+  }
+
+  for (const auto &Base : RD->bases()) {
+    if (Base.isVirtual())
+      continue;
+
+    const RecordType *BaseRT = Base.getType()->castAs<RecordType>();
+    const llvm::abi::Type *BaseType = convertType(Base.getType());
+    uint64_t BaseOffset =
+        Layout.getBaseClassOffset(BaseRT->getAsCXXRecordDecl()).getQuantity() *
+        8;
+
+    BaseClasses.emplace_back(BaseType, BaseOffset);
+  }
+
+  for (const auto &VBase : RD->vbases()) {
+    const RecordType *VBaseRT = VBase.getType()->getAs<RecordType>();
+    if (!VBaseRT)
+      continue;
+
+    const llvm::abi::Type *VBaseType = convertType(VBase.getType());
+    uint64_t VBaseOffset =
+        Layout.getVBaseClassOffset(VBaseRT->getAsCXXRecordDecl())
+            .getQuantity() *
+        8;
+
+    VirtualBaseClasses.emplace_back(VBaseType, VBaseOffset);
+  }
+
+  computeFieldInfo(RD, Fields, Layout);
+
+  llvm::sort(Fields,
+             [](const llvm::abi::FieldInfo &A, const llvm::abi::FieldInfo &B) {
+               return A.OffsetInBits < B.OffsetInBits;
+             });
+
+  llvm::TypeSize Size =
+      llvm::TypeSize::getFixed(Layout.getSize().getQuantity() * 8);
+  llvm::Align Alignment = llvm::Align(Layout.getAlignment().getQuantity());
+
+  llvm::abi::RecordFlags RecFlags = llvm::abi::RecordFlags::IsCXXRecord;
+  if (RD->isPolymorphic())
+    RecFlags |= llvm::abi::RecordFlags::IsPolymorphic;
+  if (canPassInRegs)
+    RecFlags |= llvm::abi::RecordFlags::CanPassInRegisters;
+  if (RD->hasFlexibleArrayMember())
+    RecFlags |= llvm::abi::RecordFlags::HasFlexibleArrayMember;
+
+  return Builder.getRecordType(Fields, Size, Alignment,
+                               llvm::abi::StructPacking::Default, BaseClasses,
+                               VirtualBaseClasses, RecFlags);
+}
+
+/// Converts reference types to pointer representations in the ABI.
+/// Both lvalue references (T&) and rvalue references (T&&) are represented
+/// as pointers at...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/174634
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to