================
@@ -0,0 +1,586 @@
+//==---- 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 "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;
+  switch (QT->getTypeClass()) {
+    // Non-canonical and dependent types should have been stripped by
+    // getCanonicalType() above or cannot appear during code generation.
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.inc"
+    llvm::reportFatalInternalError(
+        "Non-canonical or dependent types should not reach ABI lowering");
+
+  case Type::Builtin:
+    Result = convertBuiltinType(cast<BuiltinType>(QT));
+    break;
+  case Type::Pointer:
+    Result =
+        createPointerTypeForPointee(cast<PointerType>(QT)->getPointeeType());
+    break;
+  case Type::LValueReference:
+  case Type::RValueReference:
+    Result =
+        createPointerTypeForPointee(cast<ReferenceType>(QT)->getPointeeType());
+    break;
+  case Type::ConstantArray:
+  case Type::ArrayParameter:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+    Result = convertArrayType(cast<ArrayType>(QT));
+    break;
+  case Type::Vector:
+  case Type::ExtVector:
+    Result = convertVectorType(cast<VectorType>(QT));
+    break;
+  case Type::Record:
+    Result = convertRecordType(cast<RecordType>(QT));
+    break;
+  case Type::Enum:
+    Result = convertEnumType(cast<EnumType>(QT));
+    break;
+  case Type::Complex:
+    Result = convertComplexType(cast<ComplexType>(QT));
+    break;
+  case Type::Atomic:
+    return convertType(cast<AtomicType>(QT)->getValueType());
+  case Type::BlockPointer:
+    return createPointerTypeForPointee(ASTCtx.VoidPtrTy);
+  case Type::Pipe:
+    Result = createPointerTypeForPointee(ASTCtx.VoidPtrTy);
+    break;
+  case Type::ConstantMatrix: {
+    const auto *MT = cast<ConstantMatrixType>(QT);
+    return Builder.getArrayType(convertType(MT->getElementType()),
+                                MT->getNumRows() * MT->getNumColumns(),
+                                ASTCtx.getTypeSize(QT), /*IsMatrixType=*/true);
+  }
+  case Type::MemberPointer:
+    Result = convertMemberPointerType(cast<MemberPointerType>(QT));
+    break;
+  case Type::BitInt: {
+    const auto *BIT = cast<BitIntType>(QT);
+    return Builder.getIntegerType(BIT->getNumBits(), getTypeAlign(QT),
+                                  /*Signed=*/BIT->isSigned(),
+                                  /*IsBitInt=*/true);
+  }
+  case Type::ObjCObject:
+  case Type::ObjCInterface:
+  case Type::ObjCObjectPointer:
+    // Objective-C objects are represented as pointers in the ABI.
+    return Builder.getPointerType(
+        ASTCtx.getTargetInfo().getPointerWidth(QT.getAddressSpace()),
+        llvm::Align(ASTCtx.getTargetInfo().getPointerAlign(LangAS::Default) /
+                    8),
+        ASTCtx.getTargetInfo().getTargetAddressSpace(QT.getAddressSpace()));
+  case Type::Auto:
+  case Type::DeducedTemplateSpecialization:
+  case Type::FunctionProto:
+  case Type::FunctionNoProto:
+  case Type::HLSLAttributedResource:
+    llvm::reportFatalInternalError("Type not supported in ABI lowering");
+  }
+
+  assert(Result && "convertType returned nullptr");
+  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), /*Signed=*/false,
+                                  /*IsBitInt=*/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),
+                                  /*Signed=*/BT->isSignedInteger(),
+                                  /*IsBitInt=*/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));
+
+  // TODO: IBM 128-bit extended double
+  case BuiltinType::Ibm128:
+    llvm::reportFatalInternalError(
+        "IBM128 is not yet supported in the ABI lowering libary");
+
+  // TODO: Fixed-point types
+  case BuiltinType::ShortAccum:
+  case BuiltinType::Accum:
+  case BuiltinType::LongAccum:
+  case BuiltinType::UShortAccum:
+  case BuiltinType::UAccum:
+  case BuiltinType::ULongAccum:
+  case BuiltinType::ShortFract:
+  case BuiltinType::Fract:
+  case BuiltinType::LongFract:
+  case BuiltinType::UShortFract:
+  case BuiltinType::UFract:
+  case BuiltinType::ULongFract:
+  case BuiltinType::SatShortAccum:
+  case BuiltinType::SatAccum:
+  case BuiltinType::SatLongAccum:
+  case BuiltinType::SatUShortAccum:
+  case BuiltinType::SatUAccum:
+  case BuiltinType::SatULongAccum:
+  case BuiltinType::SatShortFract:
+  case BuiltinType::SatFract:
+  case BuiltinType::SatLongFract:
+  case BuiltinType::SatUShortFract:
+  case BuiltinType::SatUFract:
+  case BuiltinType::SatULongFract:
+    llvm::reportFatalInternalError(
+        "Fixed Point types not yet implemented in the ABI lowering library");
+
+    // OpenCL image types are represented as opaque pointers.
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   
\
+  case BuiltinType::Id:
+#include "clang/Basic/OpenCLImageTypes.def"
+    // OpenCL extension types are represented as opaque pointers.
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
+#include "clang/Basic/OpenCLExtensionTypes.def"
+  case BuiltinType::OCLSampler:
+  case BuiltinType::OCLEvent:
+  case BuiltinType::OCLClkEvent:
+  case BuiltinType::OCLQueue:
+  case BuiltinType::OCLReserveID:
+    return createPointerTypeForPointee(QT);
+
+  // Objective-C builtin types are represented as opaque pointers.
+  case BuiltinType::ObjCId:
+  case BuiltinType::ObjCClass:
+  case BuiltinType::ObjCSel:
+    return createPointerTypeForPointee(QT);
+
+    // Target-specific vector/matrix types — not yet implemented.
+#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/AArch64ACLETypes.def"
+    llvm::reportFatalInternalError(
+        "AArch64 SVE types not yet supported in ABI lowering library");
+#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
+#include "clang/Basic/PPCTypes.def"
+    llvm::reportFatalInternalError(
+        "PPC MMA types not yet supported in ABI lowering library");
+#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/RISCVVTypes.def"
+    llvm::reportFatalInternalError(
+        "RISC-V vector types not yet supported in ABI lowering library");
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+    llvm::reportFatalInternalError("WebAssembly reference types not yet "
+                                   "supported in ABI lowering library");
+#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
+#include "clang/Basic/AMDGPUTypes.def"
+    llvm::reportFatalInternalError(
+        "AMDGPU types not yet supported in ABI lowering library");
+#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/HLSLIntangibleTypes.def"
+    llvm::reportFatalInternalError(
+        "HLSL intangible types not yet Supported in ABI lowering library");
+
+    // Placeholder types should never reach ABI lowering.
+#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
+#define BUILTIN_TYPE(Id, SingletonId)
+#include "clang/AST/BuiltinTypes.def"
+    llvm::reportFatalInternalError(
+        "Placeholder type should not reach ABI lowering");
+  }
+}
+
+/// 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());
+  llvm::reportFatalInternalError(
+      "unexpected array type in ABI lowering (dependent array types should be "
+      "resolved before reaching this point)");
+}
+
+const llvm::abi::Type *QualTypeMapper::convertVectorType(const VectorType *VT) 
{
+  const llvm::abi::Type *ElementType = convertType(VT->getElementType());
+  QualType VectorQualType(VT, 0);
+
+  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;
----------------
nikic wrote:

Hm, this code looks very suspect to me. If this kind of adjustment is 
necessary, I don't think it should be happening during the QualType -> ABIType 
mapping, but sometime later. I'd omit this code for now, until we need it.

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