https://github.com/vortex73 updated https://github.com/llvm/llvm-project/pull/140112
>From 322c1cfb925f3073f3d3b30abe1b2e35ae7745f3 Mon Sep 17 00:00:00 2001 From: Narayan Sreekumar <nsreekum...@gmail.com> Date: Thu, 15 May 2025 23:13:50 +0530 Subject: [PATCH 1/5] [LLVM ABI] The Typesystem --- llvm/include/llvm/ABI/Types.h | 121 ++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 llvm/include/llvm/ABI/Types.h diff --git a/llvm/include/llvm/ABI/Types.h b/llvm/include/llvm/ABI/Types.h new file mode 100644 index 0000000000000..443a6c1eab4e7 --- /dev/null +++ b/llvm/include/llvm/ABI/Types.h @@ -0,0 +1,121 @@ +#ifndef LLVM_ABI_TYPES_H +#define LLVM_ABI_TYPES_H + +#include <cstdint> +#include <memory> +#include <string> + +namespace llvm { +namespace abi { + +enum class TypeKind { + Void, + Integer, + Float, + Pointer, + Array, + Vector, + Struct, + Union, + Function +}; +class Type { +protected: + TypeKind Kind; + uint64_t SizeInBits; + uint64_t AlignInBits; + bool IsExplicitlyAligned; + + Type(TypeKind K, uint64_t Size, uint64_t Align, bool ExplicitAlign = false) + : Kind(K), SizeInBits(Size), AlignInBits(Align), + IsExplicitlyAligned(ExplicitAlign) {} + +public: + virtual ~Type() = default; + + TypeKind getKind() const { return Kind; } + uint64_t getSizeInBits() const { return SizeInBits; } + uint64_t getAlignInBits() const { return AlignInBits; } + bool hasExplicitAlignment() const { return IsExplicitlyAligned; } + + void setExplicitAlignment(uint64_t Align) { + AlignInBits = Align; + IsExplicitlyAligned = true; + } + + bool isVoid() const { return Kind == TypeKind::Void; } + bool isInteger() const { return Kind == TypeKind::Integer; } + bool isFloat() const { return Kind == TypeKind::Float; } + bool isPointer() const { return Kind == TypeKind::Pointer; } + bool isArray() const { return Kind == TypeKind::Array; } + bool isVector() const { return Kind == TypeKind::Vector; } + bool isStruct() const { return Kind == TypeKind::Struct; } + bool isUnion() const { return Kind == TypeKind::Union; } + bool isFunction() const { return Kind == TypeKind::Function; } + + static bool classof(const Type *) { return true; } +}; +class VoidType : public Type { +public: + VoidType() : Type(TypeKind::Void, 0, 0) {} + + static bool classof(const Type *T) { return T->getKind() == TypeKind::Void; } +}; + +class IntegerType : public Type { +private: + bool IsSigned; + bool IsAltRepresentation; + std::string TypeName; + +public: + IntegerType(uint64_t BitWidth, uint64_t Align, bool Signed, + bool AltRep = false, const std::string &Name = "") + : Type(TypeKind::Integer, BitWidth, Align), IsSigned(Signed), + IsAltRepresentation(AltRep), TypeName(Name) {} + + bool isSigned() const { return IsSigned; } + bool isAltRepresentation() const { return IsAltRepresentation; } + const std::string &getTypeName() const { return TypeName; } + + static bool classof(const Type *T) { + return T->getKind() == TypeKind::Integer; + } +}; +class FloatType : public Type { +private: + std::string TypeName; + +public: + FloatType(uint64_t BitWidth, uint64_t Align, const std::string &Name) + : Type(TypeKind::Float, BitWidth, Align), TypeName(Name) {} + + const std::string &getTypeName() const { return TypeName; } + + static bool classof(const Type *T) { return T->getKind() == TypeKind::Float; } +}; +class PointerType : public Type { +private: + std::unique_ptr<Type> PointeeType; + bool IsConst; + bool IsVolatile; + +public: + PointerType(std::unique_ptr<Type> Pointee, uint64_t Size, uint64_t Align, + bool Const = false, bool Volatile = false) + : Type(TypeKind::Pointer, Size, Align), PointeeType(std::move(Pointee)), + IsConst(Const), IsVolatile(Volatile) {} + + const Type *getPointeeType() const { return PointeeType.get(); } + bool isConst() const { return IsConst; } + bool isVolatile() const { return IsVolatile; } + + static bool classof(const Type *T) { + return T->getKind() == TypeKind::Pointer; + } +}; + +} // namespace abi +} // namespace llvm + +#endif >From 0858b1f327c7a49c2e2825124a8d5cabbd8654fd Mon Sep 17 00:00:00 2001 From: Narayan Sreekumar <nsreekum...@gmail.com> Date: Fri, 23 May 2025 17:53:53 +0530 Subject: [PATCH 2/5] [LLVMABI] API for Creating types --- llvm/include/llvm/ABI/Types.h | 244 +++++++++++++++++++++++++++++----- 1 file changed, 213 insertions(+), 31 deletions(-) diff --git a/llvm/include/llvm/ABI/Types.h b/llvm/include/llvm/ABI/Types.h index 443a6c1eab4e7..84cb586832dbd 100644 --- a/llvm/include/llvm/ABI/Types.h +++ b/llvm/include/llvm/ABI/Types.h @@ -1,9 +1,9 @@ #ifndef LLVM_ABI_TYPES_H #define LLVM_ABI_TYPES_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/Allocator.h" #include <cstdint> -#include <memory> -#include <string> namespace llvm { namespace abi { @@ -19,6 +19,7 @@ enum class TypeKind { Union, Function }; + class Type { protected: TypeKind Kind; @@ -31,8 +32,6 @@ class Type { IsExplicitlyAligned(ExplicitAlign) {} public: - virtual ~Type() = default; - TypeKind getKind() const { return Kind; } uint64_t getSizeInBits() const { return SizeInBits; } uint64_t getAlignInBits() const { return AlignInBits; } @@ -52,9 +51,8 @@ class Type { bool isStruct() const { return Kind == TypeKind::Struct; } bool isUnion() const { return Kind == TypeKind::Union; } bool isFunction() const { return Kind == TypeKind::Function; } - - static bool classof(const Type *) { return true; } }; + class VoidType : public Type { public: VoidType() : Type(TypeKind::Void, 0, 0) {} @@ -65,53 +63,237 @@ class VoidType : public Type { class IntegerType : public Type { private: bool IsSigned; - bool IsAltRepresentation; - std::string TypeName; public: - IntegerType(uint64_t BitWidth, uint64_t Align, bool Signed, - bool AltRep = false, const std::string &Name = "") - : Type(TypeKind::Integer, BitWidth, Align), IsSigned(Signed), - IsAltRepresentation(AltRep), TypeName(Name) {} + IntegerType(uint64_t BitWidth, uint64_t Align, bool Signed) + : Type(TypeKind::Integer, BitWidth, Align), IsSigned(Signed) {} bool isSigned() const { return IsSigned; } - bool isAltRepresentation() const { return IsAltRepresentation; } - const std::string &getTypeName() const { return TypeName; } static bool classof(const Type *T) { return T->getKind() == TypeKind::Integer; } }; + class FloatType : public Type { +public: + FloatType(uint64_t BitWidth, uint64_t Align) + : Type(TypeKind::Float, BitWidth, Align) {} + + static bool classof(const Type *T) { return T->getKind() == TypeKind::Float; } +}; + +class PointerType : public Type { +public: + PointerType(uint64_t Size, uint64_t Align) + : Type(TypeKind::Pointer, Size, Align) {} + + static bool classof(const Type *T) { + return T->getKind() == TypeKind::Pointer; + } +}; + +class ArrayType : public Type { private: - std::string TypeName; + const Type *ElementType; + uint64_t NumElements; public: - FloatType(uint64_t BitWidth, uint64_t Align, const std::string &Name) - : Type(TypeKind::Float, BitWidth, Align), TypeName(Name) {} + ArrayType(const Type *ElemType, uint64_t NumElems) + : Type(TypeKind::Array, ElemType->getSizeInBits() * NumElems, + ElemType->getAlignInBits()), + ElementType(ElemType), NumElements(NumElems) {} - const std::string &getTypeName() const { return TypeName; } + const Type *getElementType() const { return ElementType; } + uint64_t getNumElements() const { return NumElements; } - static bool classof(const Type *T) { return T->getKind() == TypeKind::Float; } + static bool classof(const Type *T) { return T->getKind() == TypeKind::Array; } }; -class PointerType : public Type { + +class VectorType : public Type { private: - std::unique_ptr<Type> PointeeType; - bool IsConst; - bool IsVolatile; + const Type *ElementType; + uint64_t NumElements; public: - PointerType(std::unique_ptr<Type> Pointee, uint64_t Size, uint64_t Align, - bool Const = false, bool Volatile = false) - : Type(TypeKind::Pointer, Size, Align), PointeeType(std::move(Pointee)), - IsConst(Const), IsVolatile(Volatile) {} + VectorType(const Type *ElemType, uint64_t NumElems, uint64_t Align) + : Type(TypeKind::Vector, ElemType->getSizeInBits() * NumElems, Align), + ElementType(ElemType), NumElements(NumElems) {} - const Type *getPointeeType() const { return PointeeType.get(); } - bool isConst() const { return IsConst; } - bool isVolatile() const { return IsVolatile; } + const Type *getElementType() const { return ElementType; } + uint64_t getNumElements() const { return NumElements; } static bool classof(const Type *T) { - return T->getKind() == TypeKind::Pointer; + return T->getKind() == TypeKind::Vector; + } +}; + +struct FieldInfo { + const Type *FieldType; + uint64_t OffsetInBits; + bool IsBitField; + uint64_t BitFieldWidth; + + FieldInfo(const Type *Type, uint64_t Offset = 0, bool BitField = false, + uint64_t BFWidth = 0) + : FieldType(Type), OffsetInBits(Offset), IsBitField(BitField), + BitFieldWidth(BFWidth) {} +}; + +enum class StructPacking { Default, Packed, ExplicitPacking }; + +class StructType : public Type { +private: + const FieldInfo *Fields; + uint32_t NumFields; + StructPacking Packing; + +public: + StructType(const FieldInfo *StructFields, uint32_t FieldCount, uint64_t Size, + uint64_t Align, StructPacking Pack = StructPacking::Default) + : Type(TypeKind::Struct, Size, Align), Fields(StructFields), + NumFields(FieldCount), Packing(Pack) {} + + const FieldInfo *getFields() const { return Fields; } + uint32_t getNumFields() const { return NumFields; } + StructPacking getPacking() const { return Packing; } + + static bool classof(const Type *T) { + return T->getKind() == TypeKind::Struct; + } +}; + +class UnionType : public Type { +private: + const FieldInfo *Fields; + uint32_t NumFields; + StructPacking Packing; + +public: + UnionType(const FieldInfo *UnionFields, uint32_t FieldCount, uint64_t Size, + uint64_t Align, StructPacking Pack = StructPacking::Default) + : Type(TypeKind::Union, Size, Align), Fields(UnionFields), + NumFields(FieldCount), Packing(Pack) {} + + const FieldInfo *getFields() const { return Fields; } + uint32_t getNumFields() const { return NumFields; } + StructPacking getPacking() const { return Packing; } + + static bool classof(const Type *T) { return T->getKind() == TypeKind::Union; } +}; + +enum class CallConv { + C, + // TODO: extend for more CallConvs +}; + +class FunctionType : public Type { +private: + const Type *ReturnType; + const Type *const *ParameterTypes; + uint32_t NumParams; + bool IsVarArg; + CallConv CC; + +public: + FunctionType(const Type *RetType, const Type *const *ParamTypes, + uint32_t ParamCount, bool VarArgs, CallConv CallConv) + : Type(TypeKind::Function, 0, 0), ReturnType(RetType), + ParameterTypes(ParamTypes), NumParams(ParamCount), IsVarArg(VarArgs), + CC(CallConv) {} + + const Type *getReturnType() const { return ReturnType; } + const Type *const *getParameterTypes() const { return ParameterTypes; } + uint32_t getNumParameters() const { return NumParams; } + const Type *getParameterType(uint32_t Index) const { + assert(Index < NumParams && "Parameter index out of bounds"); + return ParameterTypes[Index]; + } + bool isVarArg() const { return IsVarArg; } + CallConv getCallingConv() const { return CC; } + + static bool classof(const Type *T) { + return T->getKind() == TypeKind::Function; + } +}; + +// API for creating ABI Types +class TypeBuilder { +private: + BumpPtrAllocator &Allocator; + +public: + explicit TypeBuilder(BumpPtrAllocator &Alloc) : Allocator(Alloc) {} + + const VoidType *getVoidType() { + return new (Allocator.Allocate<VoidType>()) VoidType(); + } + + const IntegerType *getIntegerType(uint64_t BitWidth, uint64_t Align, + bool Signed) { + return new (Allocator.Allocate<IntegerType>()) + IntegerType(BitWidth, Align, Signed); + } + + const FloatType *getFloatType(uint64_t BitWidth, uint64_t Align) { + return new (Allocator.Allocate<FloatType>()) FloatType(BitWidth, Align); + } + + const PointerType *getPointerType(uint64_t Size, uint64_t Align) { + return new (Allocator.Allocate<PointerType>()) PointerType(Size, Align); + } + + const ArrayType *getArrayType(const Type *ElementType, uint64_t NumElements) { + return new (Allocator.Allocate<ArrayType>()) + ArrayType(ElementType, NumElements); + } + + const VectorType *getVectorType(const Type *ElementType, uint64_t NumElements, + uint64_t Align) { + return new (Allocator.Allocate<VectorType>()) + VectorType(ElementType, NumElements, Align); + } + + const StructType *getStructType(ArrayRef<FieldInfo> Fields, uint64_t Size, + uint64_t Align, + StructPacking Pack = StructPacking::Default) { + FieldInfo *FieldArray = Allocator.Allocate<FieldInfo>(Fields.size()); + + for (size_t I = 0; I < Fields.size(); ++I) { + new (&FieldArray[I]) FieldInfo(Fields[I]); + } + + return new (Allocator.Allocate<StructType>()) StructType( + FieldArray, static_cast<uint32_t>(Fields.size()), Size, Align, Pack); + } + + const UnionType *getUnionType(ArrayRef<FieldInfo> Fields, uint64_t Size, + uint64_t Align, + StructPacking Pack = StructPacking::Default) { + FieldInfo *FieldArray = Allocator.Allocate<FieldInfo>(Fields.size()); + + for (size_t I = 0; I < Fields.size(); ++I) { + new (&FieldArray[I]) FieldInfo(Fields[I]); + } + + return new (Allocator.Allocate<UnionType>()) UnionType( + FieldArray, static_cast<uint32_t>(Fields.size()), Size, Align, Pack); + } + + const FunctionType *getFunctionType(const Type *ReturnType, + ArrayRef<const Type *> ParamTypes, + bool IsVarArg, + CallConv CC = CallConv::C) { + const Type **ParamArray = + Allocator.Allocate<const Type *>(ParamTypes.size()); + + for (size_t I = 0; I < ParamTypes.size(); ++I) { + ParamArray[I] = ParamTypes[I]; + } + + return new (Allocator.Allocate<FunctionType>()) + FunctionType(ReturnType, ParamArray, + static_cast<uint32_t>(ParamTypes.size()), IsVarArg, CC); } }; >From 114cab7c06c080bf9661c31f405b39b2a8575d6d Mon Sep 17 00:00:00 2001 From: Narayan Sreekumar <nsreekum...@gmail.com> Date: Tue, 27 May 2025 03:07:20 +0530 Subject: [PATCH 3/5] [LLVMABI] Mapper Interface --- llvm/include/llvm/ABI/QualTypeMapper.h | 52 +++++++++++ llvm/include/llvm/ABI/Types.h | 117 ++++++++----------------- llvm/lib/ABI/CMakeLists.txt | 17 ++++ llvm/lib/ABI/QualTypeMapper.cpp | 16 ++++ llvm/lib/CMakeLists.txt | 1 + 5 files changed, 123 insertions(+), 80 deletions(-) create mode 100644 llvm/include/llvm/ABI/QualTypeMapper.h create mode 100644 llvm/lib/ABI/CMakeLists.txt create mode 100644 llvm/lib/ABI/QualTypeMapper.cpp diff --git a/llvm/include/llvm/ABI/QualTypeMapper.h b/llvm/include/llvm/ABI/QualTypeMapper.h new file mode 100644 index 0000000000000..f408325dad007 --- /dev/null +++ b/llvm/include/llvm/ABI/QualTypeMapper.h @@ -0,0 +1,52 @@ +#ifndef LLVM_ABI_QUALTYPE_MAPPER_H +#define LLVM_ABI_QUALTYPE_MAPPER_H + +#include "llvm/Support/Allocator.h" +#include <clang/AST/ASTContext.h> +#include <clang/AST/Type.h> +#include <llvm/ABI/Types.h> +#include <llvm/ADT/DenseMap.h> + +namespace llvm { +namespace abi { + +class QualTypeMapper { +private: + clang::ASTContext &ASTCtx; + TypeBuilder Builder; + + // llvm::DenseMap<clang::QualType , const Type*> TypeCache; + + const Type *convertBuiltinType(const clang::BuiltinType *BT); + const Type *convertPointerType(const clang::PointerType *PT); + const Type *convertArrayType(const clang::ArrayType *AT); + const Type *convertVectorType(const clang::VectorType *VT); + const Type *convertRecordType(const clang::RecordType *RT); + const Type *convertFunctionType(const clang::FunctionProtoType *FT); + const Type *convertEnumType(const clang::EnumType *ET); + + void computeRecordLayout(const clang::RecordDecl *RD, + llvm::SmallVectorImpl<FieldInfo> &Fields, + uint64_t &TotalSize, uint64_t &Alignment, + StructPacking &Packing); + + uint64_t getTypeSize(clang::QualType QT) const; + uint64_t getTypeAlign(clang::QualType QT) const; + uint64_t getPointerSize() const; + uint64_t getPointerAlign() const; + +public: + explicit QualTypeMapper(clang::ASTContext &Ctx, BumpPtrAllocator &Alloc) + : ASTCtx(Ctx), Builder(Alloc) {} + + const Type *convertType(clang::QualType QT); + + // void clearCache() {TypeCache.clear();} + + TypeBuilder getTypeBuilder() { return Builder; } +}; + +} // namespace abi +} // namespace llvm + +#endif // !LLVM_ABI_QUALTYPE_MAPPER_H diff --git a/llvm/include/llvm/ABI/Types.h b/llvm/include/llvm/ABI/Types.h index 84cb586832dbd..e99bee35acf77 100644 --- a/llvm/include/llvm/ABI/Types.h +++ b/llvm/include/llvm/ABI/Types.h @@ -1,9 +1,13 @@ #ifndef LLVM_ABI_TYPES_H #define LLVM_ABI_TYPES_H +#include "llvm/ADT/APFloat.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/TypeSize.h" #include <cstdint> +#include <llvm/IR/CallingConv.h> namespace llvm { namespace abi { @@ -17,27 +21,26 @@ enum class TypeKind { Vector, Struct, Union, - Function }; class Type { protected: TypeKind Kind; - uint64_t SizeInBits; - uint64_t AlignInBits; + TypeSize SizeInBits; + Align AlignInBits; bool IsExplicitlyAligned; - Type(TypeKind K, uint64_t Size, uint64_t Align, bool ExplicitAlign = false) + Type(TypeKind K, TypeSize Size, Align Align, bool ExplicitAlign = false) : Kind(K), SizeInBits(Size), AlignInBits(Align), IsExplicitlyAligned(ExplicitAlign) {} public: TypeKind getKind() const { return Kind; } - uint64_t getSizeInBits() const { return SizeInBits; } - uint64_t getAlignInBits() const { return AlignInBits; } + TypeSize getSizeInBits() const { return SizeInBits; } + Align getAlignInBits() const { return AlignInBits; } bool hasExplicitAlignment() const { return IsExplicitlyAligned; } - void setExplicitAlignment(uint64_t Align) { + void setExplicitAlignment(Align Align) { AlignInBits = Align; IsExplicitlyAligned = true; } @@ -50,12 +53,11 @@ class Type { bool isVector() const { return Kind == TypeKind::Vector; } bool isStruct() const { return Kind == TypeKind::Struct; } bool isUnion() const { return Kind == TypeKind::Union; } - bool isFunction() const { return Kind == TypeKind::Function; } }; class VoidType : public Type { public: - VoidType() : Type(TypeKind::Void, 0, 0) {} + VoidType() : Type(TypeKind::Void, TypeSize::getFixed(0), Align(1)) {} static bool classof(const Type *T) { return T->getKind() == TypeKind::Void; } }; @@ -65,8 +67,9 @@ class IntegerType : public Type { bool IsSigned; public: - IntegerType(uint64_t BitWidth, uint64_t Align, bool Signed) - : Type(TypeKind::Integer, BitWidth, Align), IsSigned(Signed) {} + IntegerType(uint64_t BitWidth, Align Align, bool Signed) + : Type(TypeKind::Integer, TypeSize::getFixed(BitWidth), Align), + IsSigned(Signed) {} bool isSigned() const { return IsSigned; } @@ -76,17 +79,22 @@ class IntegerType : public Type { }; class FloatType : public Type { +private: + const fltSemantics *Semantics; + public: - FloatType(uint64_t BitWidth, uint64_t Align) - : Type(TypeKind::Float, BitWidth, Align) {} + FloatType(const fltSemantics &FloatSemantics, Align Align) + : Type(TypeKind::Float, + TypeSize::getFixed(APFloat::getSizeInBits(FloatSemantics)), Align), + Semantics(&FloatSemantics) {} static bool classof(const Type *T) { return T->getKind() == TypeKind::Float; } }; class PointerType : public Type { public: - PointerType(uint64_t Size, uint64_t Align) - : Type(TypeKind::Pointer, Size, Align) {} + PointerType(uint64_t Size, Align Align) + : Type(TypeKind::Pointer, TypeSize::getFixed(Size), Align) {} static bool classof(const Type *T) { return T->getKind() == TypeKind::Pointer; @@ -116,7 +124,7 @@ class VectorType : public Type { uint64_t NumElements; public: - VectorType(const Type *ElemType, uint64_t NumElems, uint64_t Align) + VectorType(const Type *ElemType, uint64_t NumElems, Align Align) : Type(TypeKind::Vector, ElemType->getSizeInBits() * NumElems, Align), ElementType(ElemType), NumElements(NumElems) {} @@ -149,8 +157,8 @@ class StructType : public Type { StructPacking Packing; public: - StructType(const FieldInfo *StructFields, uint32_t FieldCount, uint64_t Size, - uint64_t Align, StructPacking Pack = StructPacking::Default) + StructType(const FieldInfo *StructFields, uint32_t FieldCount, TypeSize Size, + Align Align, StructPacking Pack = StructPacking::Default) : Type(TypeKind::Struct, Size, Align), Fields(StructFields), NumFields(FieldCount), Packing(Pack) {} @@ -170,8 +178,8 @@ class UnionType : public Type { StructPacking Packing; public: - UnionType(const FieldInfo *UnionFields, uint32_t FieldCount, uint64_t Size, - uint64_t Align, StructPacking Pack = StructPacking::Default) + UnionType(const FieldInfo *UnionFields, uint32_t FieldCount, TypeSize Size, + Align Align, StructPacking Pack = StructPacking::Default) : Type(TypeKind::Union, Size, Align), Fields(UnionFields), NumFields(FieldCount), Packing(Pack) {} @@ -182,41 +190,6 @@ class UnionType : public Type { static bool classof(const Type *T) { return T->getKind() == TypeKind::Union; } }; -enum class CallConv { - C, - // TODO: extend for more CallConvs -}; - -class FunctionType : public Type { -private: - const Type *ReturnType; - const Type *const *ParameterTypes; - uint32_t NumParams; - bool IsVarArg; - CallConv CC; - -public: - FunctionType(const Type *RetType, const Type *const *ParamTypes, - uint32_t ParamCount, bool VarArgs, CallConv CallConv) - : Type(TypeKind::Function, 0, 0), ReturnType(RetType), - ParameterTypes(ParamTypes), NumParams(ParamCount), IsVarArg(VarArgs), - CC(CallConv) {} - - const Type *getReturnType() const { return ReturnType; } - const Type *const *getParameterTypes() const { return ParameterTypes; } - uint32_t getNumParameters() const { return NumParams; } - const Type *getParameterType(uint32_t Index) const { - assert(Index < NumParams && "Parameter index out of bounds"); - return ParameterTypes[Index]; - } - bool isVarArg() const { return IsVarArg; } - CallConv getCallingConv() const { return CC; } - - static bool classof(const Type *T) { - return T->getKind() == TypeKind::Function; - } -}; - // API for creating ABI Types class TypeBuilder { private: @@ -229,17 +202,17 @@ class TypeBuilder { return new (Allocator.Allocate<VoidType>()) VoidType(); } - const IntegerType *getIntegerType(uint64_t BitWidth, uint64_t Align, + const IntegerType *getIntegerType(uint64_t BitWidth, Align Align, bool Signed) { return new (Allocator.Allocate<IntegerType>()) IntegerType(BitWidth, Align, Signed); } - const FloatType *getFloatType(uint64_t BitWidth, uint64_t Align) { - return new (Allocator.Allocate<FloatType>()) FloatType(BitWidth, Align); + const FloatType *getFloatType(const fltSemantics &Semantics, Align Align) { + return new (Allocator.Allocate<FloatType>()) FloatType(Semantics, Align); } - const PointerType *getPointerType(uint64_t Size, uint64_t Align) { + const PointerType *getPointerType(uint64_t Size, Align Align) { return new (Allocator.Allocate<PointerType>()) PointerType(Size, Align); } @@ -249,13 +222,13 @@ class TypeBuilder { } const VectorType *getVectorType(const Type *ElementType, uint64_t NumElements, - uint64_t Align) { + Align Align) { return new (Allocator.Allocate<VectorType>()) VectorType(ElementType, NumElements, Align); } - const StructType *getStructType(ArrayRef<FieldInfo> Fields, uint64_t Size, - uint64_t Align, + const StructType *getStructType(ArrayRef<FieldInfo> Fields, TypeSize Size, + Align Align, StructPacking Pack = StructPacking::Default) { FieldInfo *FieldArray = Allocator.Allocate<FieldInfo>(Fields.size()); @@ -267,8 +240,8 @@ class TypeBuilder { FieldArray, static_cast<uint32_t>(Fields.size()), Size, Align, Pack); } - const UnionType *getUnionType(ArrayRef<FieldInfo> Fields, uint64_t Size, - uint64_t Align, + const UnionType *getUnionType(ArrayRef<FieldInfo> Fields, TypeSize Size, + Align Align, StructPacking Pack = StructPacking::Default) { FieldInfo *FieldArray = Allocator.Allocate<FieldInfo>(Fields.size()); @@ -279,22 +252,6 @@ class TypeBuilder { return new (Allocator.Allocate<UnionType>()) UnionType( FieldArray, static_cast<uint32_t>(Fields.size()), Size, Align, Pack); } - - const FunctionType *getFunctionType(const Type *ReturnType, - ArrayRef<const Type *> ParamTypes, - bool IsVarArg, - CallConv CC = CallConv::C) { - const Type **ParamArray = - Allocator.Allocate<const Type *>(ParamTypes.size()); - - for (size_t I = 0; I < ParamTypes.size(); ++I) { - ParamArray[I] = ParamTypes[I]; - } - - return new (Allocator.Allocate<FunctionType>()) - FunctionType(ReturnType, ParamArray, - static_cast<uint32_t>(ParamTypes.size()), IsVarArg, CC); - } }; } // namespace abi diff --git a/llvm/lib/ABI/CMakeLists.txt b/llvm/lib/ABI/CMakeLists.txt new file mode 100644 index 0000000000000..d6aa9b542cc05 --- /dev/null +++ b/llvm/lib/ABI/CMakeLists.txt @@ -0,0 +1,17 @@ +add_llvm_component_library(LLVMABI + QualTypeMapper.cpp + + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/ABI + + DEPENDS + intrinsics_gen + + LINK_COMPONENTS + Core + Support +) + +target_include_directories(LLVMABI PRIVATE + ${LLVM_MAIN_INCLUDE_DIR} +) diff --git a/llvm/lib/ABI/QualTypeMapper.cpp b/llvm/lib/ABI/QualTypeMapper.cpp new file mode 100644 index 0000000000000..fcf3555aaf369 --- /dev/null +++ b/llvm/lib/ABI/QualTypeMapper.cpp @@ -0,0 +1,16 @@ +//===-- llvm/ABI/QualTypeMapper.cpp - QualType to ABI Mapping -------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This File contains the logic for converting clang::Qualtype to +// llvm::abi::Type for ABI Lowering +// +//===----------------------------------------------------------------------===// + +#include <llvm/ABI/QualTypeMapper.h> + +// TODO: Implementation of Qualtype -> abi::Type Mapping diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt index f6465612d30c0..b888f6637a925 100644 --- a/llvm/lib/CMakeLists.txt +++ b/llvm/lib/CMakeLists.txt @@ -3,6 +3,7 @@ include(LLVM-Build) # `Demangle', `Support' and `TableGen' libraries are added on the top-level # CMakeLists.txt +add_subdirectory(ABI) add_subdirectory(IR) add_subdirectory(FuzzMutate) add_subdirectory(FileCheck) >From 3a5827125418875f6976b40751b7628d5faf6d4f Mon Sep 17 00:00:00 2001 From: Narayan Sreekumar <nsreekum...@gmail.com> Date: Fri, 30 May 2025 03:00:01 +0530 Subject: [PATCH 4/5] [LLVMABI] QualType Mapper Implementation --- clang/include/clang/ABI/QualTypeMapper.h | 78 +++++++++ clang/lib/ABI/CMakeLists.txt | 9 + clang/lib/ABI/QualTypeMapper.cpp | 209 +++++++++++++++++++++++ clang/lib/CMakeLists.txt | 1 + llvm/include/llvm/ABI/QualTypeMapper.h | 52 ------ llvm/lib/ABI/CMakeLists.txt | 17 -- llvm/lib/ABI/QualTypeMapper.cpp | 16 -- llvm/lib/CMakeLists.txt | 2 +- 8 files changed, 298 insertions(+), 86 deletions(-) create mode 100644 clang/include/clang/ABI/QualTypeMapper.h create mode 100644 clang/lib/ABI/CMakeLists.txt create mode 100644 clang/lib/ABI/QualTypeMapper.cpp delete mode 100644 llvm/include/llvm/ABI/QualTypeMapper.h delete mode 100644 llvm/lib/ABI/CMakeLists.txt delete mode 100644 llvm/lib/ABI/QualTypeMapper.cpp diff --git a/clang/include/clang/ABI/QualTypeMapper.h b/clang/include/clang/ABI/QualTypeMapper.h new file mode 100644 index 0000000000000..70ae9e0f83130 --- /dev/null +++ b/clang/include/clang/ABI/QualTypeMapper.h @@ -0,0 +1,78 @@ +#ifndef LLVM_ABI_QUALTYPE_MAPPER_H +#define LLVM_ABI_QUALTYPE_MAPPER_H + +#include "llvm/IR/DerivedTypes.h" +#include "llvm/Support/Allocator.h" +#include <clang/AST/ASTContext.h> +#include <clang/AST/Decl.h> +#include <clang/AST/Type.h> +#include <llvm/ABI/Types.h> +#include <llvm/ADT/DenseMap.h> + +// Specialization for QualType +template <> struct llvm::DenseMapInfo<clang::QualType> { + static inline clang::QualType getEmptyKey() { + return clang::QualType::getFromOpaquePtr( + reinterpret_cast<clang::Type *>(-1)); + } + + static inline clang::QualType getTombstoneKey() { + return clang::QualType::getFromOpaquePtr( + reinterpret_cast<clang::Type *>(-2)); + } + + static unsigned getHashValue(const clang::QualType &Val) { + return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^ + ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9)); + } + + static bool isEqual(const clang::QualType &LHS, const clang::QualType &RHS) { + return LHS == RHS; + } +}; + +namespace clang { +namespace mapper { + +class QualTypeMapper { +private: + clang::ASTContext &ASTCtx; + llvm::abi::TypeBuilder Builder; + + llvm::DenseMap<clang::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::StructType *convertStructType(const clang::RecordDecl *RD); + const llvm::abi::UnionType *convertUnionType(const clang::RecordDecl *RD); + const llvm::abi::Type *createPointerTypeForPointee(QualType PointeeType); + + 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; + 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 mapper +} // namespace clang + +#endif // !LLVM_ABI_QUALTYPE_MAPPER_H diff --git a/clang/lib/ABI/CMakeLists.txt b/clang/lib/ABI/CMakeLists.txt new file mode 100644 index 0000000000000..86a8324b5716a --- /dev/null +++ b/clang/lib/ABI/CMakeLists.txt @@ -0,0 +1,9 @@ +add_clang_library(clangABI + QualTypeMapper.cpp + + LINK_LIBS + clangAST + clangBasic + LLVMABI + LLVMSupport +) diff --git a/clang/lib/ABI/QualTypeMapper.cpp b/clang/lib/ABI/QualTypeMapper.cpp new file mode 100644 index 0000000000000..22070f250026e --- /dev/null +++ b/clang/lib/ABI/QualTypeMapper.cpp @@ -0,0 +1,209 @@ +#include "clang/AST/RecordLayout.h" +#include "clang/AST/Type.h" +#include "clang/Analysis/Analyses/ThreadSafetyTIL.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/ABI/Types.h" +#include "llvm/Support/Alignment.h" +#include "llvm/Support/Casting.h" +#include <clang/ABI/QualTypeMapper.h> + +namespace clang { +namespace mapper { + +const llvm::abi::Type *QualTypeMapper::convertType(QualType QT) { + QT = QT.getCanonicalType().getUnqualifiedType(); + + 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 *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 { + // TODO: Write Fallback logic for unsupported types. + } + TypeCache[QT] = Result; + return Result; +} + +const llvm::abi::Type * +QualTypeMapper::convertBuiltinType(const BuiltinType *BT) { + switch (BT->getKind()) { + case BuiltinType::Void: + return Builder.getVoidType(); + + case BuiltinType::Bool: + case BuiltinType::UChar: + case BuiltinType::Char_U: + case BuiltinType::UShort: + return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)), + getTypeAlign(QualType(BT, 0)), false); + + case BuiltinType::Char_S: + case BuiltinType::SChar: + case BuiltinType::Short: + return Builder.getIntegerType(ASTCtx.getCharWidth(), + getTypeAlign(QualType(BT, 0)), true); + + case BuiltinType::WChar_U: + return Builder.getIntegerType(ASTCtx.getCharWidth(), + getTypeAlign(QualType(BT, 0)), false); + + case BuiltinType::WChar_S: + return Builder.getIntegerType(ASTCtx.getCharWidth(), + getTypeAlign(QualType(BT, 0)), true); + + case BuiltinType::Char8: + return Builder.getIntegerType(8, getTypeAlign(QualType(BT, 0)), false); + + case BuiltinType::Char16: + return Builder.getIntegerType(16, getTypeAlign(QualType(BT, 0)), false); + + case BuiltinType::Char32: + return Builder.getIntegerType(32, getTypeAlign(QualType(BT, 0)), false); + + case BuiltinType::Int: + case BuiltinType::UInt: + return Builder.getIntegerType(ASTCtx.getIntWidth(QualType(BT, 0)), + getTypeAlign(QualType(BT, 0)), + BT->getKind() == BuiltinType::Int); + + case BuiltinType::Long: + case BuiltinType::ULong: + return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)), + getTypeAlign(QualType(BT, 0)), + BT->getKind() == BuiltinType::Long); + + case BuiltinType::LongLong: + case BuiltinType::ULongLong: + return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)), + getTypeAlign(QualType(BT, 0)), + BT->getKind() == BuiltinType::LongLong); + + case BuiltinType::Int128: + case BuiltinType::UInt128: + return Builder.getIntegerType(128, getTypeAlign(QualType(BT, 0)), + BT->getKind() == BuiltinType::Int128); + + case BuiltinType::Half: + case BuiltinType::Float16: + return Builder.getFloatType(llvm::APFloat::IEEEhalf(), + getTypeAlign(QualType(BT, 0))); + + case BuiltinType::Float: + return Builder.getFloatType(llvm::APFloat::IEEEsingle(), + getTypeAlign(QualType(BT, 0))); + + case BuiltinType::Double: + return Builder.getFloatType(llvm::APFloat::IEEEdouble(), + getTypeAlign(QualType(BT, 0))); + + case BuiltinType::LongDouble: + return Builder.getFloatType(ASTCtx.getFloatTypeSemantics(QualType(BT, 0)), + getTypeAlign(QualType(BT, 0))); + + case BuiltinType::BFloat16: + return Builder.getFloatType(llvm::APFloat::BFloat(), + getTypeAlign(QualType(BT, 0))); + + case BuiltinType::Float128: + return Builder.getFloatType(llvm::APFloat::IEEEquad(), + getTypeAlign(QualType(BT, 0))); + + default: + return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)), + getTypeAlign(QualType(BT, 0)), false); + } +} + +const llvm::abi::Type * +QualTypeMapper::convertArrayType(const clang::ArrayType *AT) { + const llvm::abi::Type *ElementType = convertType(AT->getElementType()); + + if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) { + auto NumElements = CAT->getZExtSize(); + return Builder.getArrayType(ElementType, NumElements); + } + if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT)) + return Builder.getArrayType(ElementType, 0); + if (const auto *VAT = dyn_cast<VariableArrayType>(AT)) + return createPointerTypeForPointee(VAT->getPointeeType()); + // TODO: This of a better fallback. + return Builder.getArrayType(ElementType, 1); +} + +const llvm::abi::Type *QualTypeMapper::convertVectorType(const VectorType *VT) { + const llvm::abi::Type *ElementType = convertType(VT->getElementType()); + uint64_t NumElements = VT->getNumElements(); + + llvm::Align VectorAlign = getTypeAlign(QualType(VT, 0)); + + return Builder.getVectorType(ElementType, NumElements, VectorAlign); +} + +const llvm::abi::Type *QualTypeMapper::convertRecordType(const RecordType *RT) { + const RecordDecl *RD = RT->getDecl()->getDefinition(); + if (!RD) { + SmallVector<llvm::abi::FieldInfo, 0> Fields; + return Builder.getStructType(Fields, llvm::TypeSize::getFixed(0), + llvm::Align(1)); + } + + if (RD->isUnion()) + return convertUnionType(RD); + return convertStructType(RD); +} + +const llvm::abi::Type * +QualTypeMapper::convertPointerType(const clang::PointerType *PT) { + return createPointerTypeForPointee(PT->getPointeeType()); +} + +llvm::Align QualTypeMapper::getTypeAlign(QualType QT) const { + return llvm::Align(ASTCtx.getTypeAlign(QT)); +} + +const llvm::abi::Type * +QualTypeMapper::createPointerTypeForPointee(QualType PointeeType) { + auto AddrSpace = PointeeType.getAddressSpace(); + auto PointerSize = ASTCtx.getTargetInfo().getPointerWidth(AddrSpace); + llvm::Align Alignment = + llvm::Align(ASTCtx.getTargetInfo().getPointerAlign(AddrSpace)); + return Builder.getPointerType(PointerSize, Alignment); +} + +void QualTypeMapper::computeFieldInfo( + const RecordDecl *RD, SmallVectorImpl<llvm::abi::FieldInfo> &Fields, + const ASTRecordLayout &Layout) { + unsigned FieldIndex = 0; + + for (const auto *FD : RD->fields()) { + const llvm::abi::Type *FieldType = convertType(FD->getType()); + uint64_t OffsetInBits = Layout.getFieldOffset(FieldIndex); + + bool IsBitField = FD->isBitField(); + uint64_t BitFieldWidth = 0; + + if (IsBitField) { + BitFieldWidth = FD->getBitWidthValue(); + } + + Fields.emplace_back(FieldType, OffsetInBits, IsBitField, BitFieldWidth); + ++FieldIndex; + } +} + +} // namespace mapper +} // namespace clang diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index 4f2218b583e41..f034622c06c2f 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(ABI) add_subdirectory(Headers) add_subdirectory(Basic) add_subdirectory(APINotes) diff --git a/llvm/include/llvm/ABI/QualTypeMapper.h b/llvm/include/llvm/ABI/QualTypeMapper.h deleted file mode 100644 index f408325dad007..0000000000000 --- a/llvm/include/llvm/ABI/QualTypeMapper.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef LLVM_ABI_QUALTYPE_MAPPER_H -#define LLVM_ABI_QUALTYPE_MAPPER_H - -#include "llvm/Support/Allocator.h" -#include <clang/AST/ASTContext.h> -#include <clang/AST/Type.h> -#include <llvm/ABI/Types.h> -#include <llvm/ADT/DenseMap.h> - -namespace llvm { -namespace abi { - -class QualTypeMapper { -private: - clang::ASTContext &ASTCtx; - TypeBuilder Builder; - - // llvm::DenseMap<clang::QualType , const Type*> TypeCache; - - const Type *convertBuiltinType(const clang::BuiltinType *BT); - const Type *convertPointerType(const clang::PointerType *PT); - const Type *convertArrayType(const clang::ArrayType *AT); - const Type *convertVectorType(const clang::VectorType *VT); - const Type *convertRecordType(const clang::RecordType *RT); - const Type *convertFunctionType(const clang::FunctionProtoType *FT); - const Type *convertEnumType(const clang::EnumType *ET); - - void computeRecordLayout(const clang::RecordDecl *RD, - llvm::SmallVectorImpl<FieldInfo> &Fields, - uint64_t &TotalSize, uint64_t &Alignment, - StructPacking &Packing); - - uint64_t getTypeSize(clang::QualType QT) const; - uint64_t getTypeAlign(clang::QualType QT) const; - uint64_t getPointerSize() const; - uint64_t getPointerAlign() const; - -public: - explicit QualTypeMapper(clang::ASTContext &Ctx, BumpPtrAllocator &Alloc) - : ASTCtx(Ctx), Builder(Alloc) {} - - const Type *convertType(clang::QualType QT); - - // void clearCache() {TypeCache.clear();} - - TypeBuilder getTypeBuilder() { return Builder; } -}; - -} // namespace abi -} // namespace llvm - -#endif // !LLVM_ABI_QUALTYPE_MAPPER_H diff --git a/llvm/lib/ABI/CMakeLists.txt b/llvm/lib/ABI/CMakeLists.txt deleted file mode 100644 index d6aa9b542cc05..0000000000000 --- a/llvm/lib/ABI/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -add_llvm_component_library(LLVMABI - QualTypeMapper.cpp - - ADDITIONAL_HEADER_DIRS - ${LLVM_MAIN_INCLUDE_DIR}/llvm/ABI - - DEPENDS - intrinsics_gen - - LINK_COMPONENTS - Core - Support -) - -target_include_directories(LLVMABI PRIVATE - ${LLVM_MAIN_INCLUDE_DIR} -) diff --git a/llvm/lib/ABI/QualTypeMapper.cpp b/llvm/lib/ABI/QualTypeMapper.cpp deleted file mode 100644 index fcf3555aaf369..0000000000000 --- a/llvm/lib/ABI/QualTypeMapper.cpp +++ /dev/null @@ -1,16 +0,0 @@ -//===-- llvm/ABI/QualTypeMapper.cpp - QualType to ABI Mapping -------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This File contains the logic for converting clang::Qualtype to -// llvm::abi::Type for ABI Lowering -// -//===----------------------------------------------------------------------===// - -#include <llvm/ABI/QualTypeMapper.h> - -// TODO: Implementation of Qualtype -> abi::Type Mapping diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt index b888f6637a925..c84690abda028 100644 --- a/llvm/lib/CMakeLists.txt +++ b/llvm/lib/CMakeLists.txt @@ -3,7 +3,7 @@ include(LLVM-Build) # `Demangle', `Support' and `TableGen' libraries are added on the top-level # CMakeLists.txt -add_subdirectory(ABI) +# add_subdirectory(ABI) add_subdirectory(IR) add_subdirectory(FuzzMutate) add_subdirectory(FileCheck) >From 283264277936dfc5f8b86cc30af4fa468910c887 Mon Sep 17 00:00:00 2001 From: Narayan Sreekumar <nsreekum...@gmail.com> Date: Sun, 1 Jun 2025 22:05:23 +0530 Subject: [PATCH 5/5] [LLVMABI] Added mappings for record types --- .../QualtypeMapper.h} | 58 ++++---- clang/lib/ABI/CMakeLists.txt | 9 -- clang/lib/CMakeLists.txt | 1 - clang/lib/CodeGen/CMakeLists.txt | 1 + .../QualtypeMapper.cpp} | 128 ++++++++++-------- llvm/include/llvm/ABI/Types.h | 26 +++- 6 files changed, 117 insertions(+), 106 deletions(-) rename clang/include/clang/{ABI/QualTypeMapper.h => CodeGen/QualtypeMapper.h} (59%) delete mode 100644 clang/lib/ABI/CMakeLists.txt rename clang/lib/{ABI/QualTypeMapper.cpp => CodeGen/QualtypeMapper.cpp} (67%) diff --git a/clang/include/clang/ABI/QualTypeMapper.h b/clang/include/clang/CodeGen/QualtypeMapper.h similarity index 59% rename from clang/include/clang/ABI/QualTypeMapper.h rename to clang/include/clang/CodeGen/QualtypeMapper.h index 70ae9e0f83130..e99c6847a67b0 100644 --- a/clang/include/clang/ABI/QualTypeMapper.h +++ b/clang/include/clang/CodeGen/QualtypeMapper.h @@ -1,35 +1,29 @@ -#ifndef LLVM_ABI_QUALTYPE_MAPPER_H -#define LLVM_ABI_QUALTYPE_MAPPER_H - -#include "llvm/IR/DerivedTypes.h" +//==---- 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" -#include <clang/AST/ASTContext.h> -#include <clang/AST/Decl.h> -#include <clang/AST/Type.h> -#include <llvm/ABI/Types.h> -#include <llvm/ADT/DenseMap.h> - -// Specialization for QualType -template <> struct llvm::DenseMapInfo<clang::QualType> { - static inline clang::QualType getEmptyKey() { - return clang::QualType::getFromOpaquePtr( - reinterpret_cast<clang::Type *>(-1)); - } - - static inline clang::QualType getTombstoneKey() { - return clang::QualType::getFromOpaquePtr( - reinterpret_cast<clang::Type *>(-2)); - } - - static unsigned getHashValue(const clang::QualType &Val) { - return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^ - ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9)); - } - - static bool isEqual(const clang::QualType &LHS, const clang::QualType &RHS) { - return LHS == RHS; - } -}; namespace clang { namespace mapper { @@ -75,4 +69,4 @@ class QualTypeMapper { } // namespace mapper } // namespace clang -#endif // !LLVM_ABI_QUALTYPE_MAPPER_H +#endif // !CLANG_CODEGEN_QUALTYPE_MAPPER_H diff --git a/clang/lib/ABI/CMakeLists.txt b/clang/lib/ABI/CMakeLists.txt deleted file mode 100644 index 86a8324b5716a..0000000000000 --- a/clang/lib/ABI/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_clang_library(clangABI - QualTypeMapper.cpp - - LINK_LIBS - clangAST - clangBasic - LLVMABI - LLVMSupport -) diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index f034622c06c2f..4f2218b583e41 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(ABI) add_subdirectory(Headers) add_subdirectory(Basic) add_subdirectory(APINotes) diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index a05b31f971e18..c70862a05d35d 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -115,6 +115,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/ABI/QualTypeMapper.cpp b/clang/lib/CodeGen/QualtypeMapper.cpp similarity index 67% rename from clang/lib/ABI/QualTypeMapper.cpp rename to clang/lib/CodeGen/QualtypeMapper.cpp index 22070f250026e..f1577383af4dc 100644 --- a/clang/lib/ABI/QualTypeMapper.cpp +++ b/clang/lib/CodeGen/QualtypeMapper.cpp @@ -1,12 +1,28 @@ +//==---- 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/Decl.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/Type.h" -#include "clang/Analysis/Analyses/ThreadSafetyTIL.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ABI/Types.h" #include "llvm/Support/Alignment.h" -#include "llvm/Support/Casting.h" -#include <clang/ABI/QualTypeMapper.h> +#include "llvm/Support/TypeSize.h" namespace clang { namespace mapper { @@ -40,87 +56,44 @@ const llvm::abi::Type *QualTypeMapper::convertType(QualType QT) { const llvm::abi::Type * QualTypeMapper::convertBuiltinType(const BuiltinType *BT) { + QualType QT(BT, 0); + switch (BT->getKind()) { case BuiltinType::Void: return Builder.getVoidType(); case BuiltinType::Bool: - case BuiltinType::UChar: - case BuiltinType::Char_U: - case BuiltinType::UShort: - return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)), - getTypeAlign(QualType(BT, 0)), false); - case BuiltinType::Char_S: + case BuiltinType::Char_U: case BuiltinType::SChar: - case BuiltinType::Short: - return Builder.getIntegerType(ASTCtx.getCharWidth(), - getTypeAlign(QualType(BT, 0)), true); - - case BuiltinType::WChar_U: - return Builder.getIntegerType(ASTCtx.getCharWidth(), - getTypeAlign(QualType(BT, 0)), false); - + case BuiltinType::UChar: case BuiltinType::WChar_S: - return Builder.getIntegerType(ASTCtx.getCharWidth(), - getTypeAlign(QualType(BT, 0)), true); - + case BuiltinType::WChar_U: case BuiltinType::Char8: - return Builder.getIntegerType(8, getTypeAlign(QualType(BT, 0)), false); - case BuiltinType::Char16: - return Builder.getIntegerType(16, getTypeAlign(QualType(BT, 0)), false); - case BuiltinType::Char32: - return Builder.getIntegerType(32, getTypeAlign(QualType(BT, 0)), false); - + case BuiltinType::Short: + case BuiltinType::UShort: case BuiltinType::Int: case BuiltinType::UInt: - return Builder.getIntegerType(ASTCtx.getIntWidth(QualType(BT, 0)), - getTypeAlign(QualType(BT, 0)), - BT->getKind() == BuiltinType::Int); - case BuiltinType::Long: case BuiltinType::ULong: - return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)), - getTypeAlign(QualType(BT, 0)), - BT->getKind() == BuiltinType::Long); - case BuiltinType::LongLong: case BuiltinType::ULongLong: - return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)), - getTypeAlign(QualType(BT, 0)), - BT->getKind() == BuiltinType::LongLong); - case BuiltinType::Int128: case BuiltinType::UInt128: - return Builder.getIntegerType(128, getTypeAlign(QualType(BT, 0)), - BT->getKind() == BuiltinType::Int128); + return Builder.getIntegerType(ASTCtx.getTypeSize(QT), getTypeAlign(QT), + BT->isSignedInteger()); case BuiltinType::Half: case BuiltinType::Float16: - return Builder.getFloatType(llvm::APFloat::IEEEhalf(), - getTypeAlign(QualType(BT, 0))); - + case BuiltinType::BFloat16: case BuiltinType::Float: - return Builder.getFloatType(llvm::APFloat::IEEEsingle(), - getTypeAlign(QualType(BT, 0))); - case BuiltinType::Double: - return Builder.getFloatType(llvm::APFloat::IEEEdouble(), - getTypeAlign(QualType(BT, 0))); - case BuiltinType::LongDouble: - return Builder.getFloatType(ASTCtx.getFloatTypeSemantics(QualType(BT, 0)), - getTypeAlign(QualType(BT, 0))); - - case BuiltinType::BFloat16: - return Builder.getFloatType(llvm::APFloat::BFloat(), - getTypeAlign(QualType(BT, 0))); - case BuiltinType::Float128: - return Builder.getFloatType(llvm::APFloat::IEEEquad(), - getTypeAlign(QualType(BT, 0))); + return Builder.getFloatType(ASTCtx.getFloatTypeSemantics(QT), + getTypeAlign(QT)); default: return Builder.getIntegerType(ASTCtx.getTypeSize(QualType(BT, 0)), @@ -171,6 +144,45 @@ QualTypeMapper::convertPointerType(const clang::PointerType *PT) { return createPointerTypeForPointee(PT->getPointeeType()); } +const llvm::abi::Type * +QualTypeMapper::convertEnumType(const clang::EnumType *ET) { + const EnumDecl *ED = ET->getDecl(); + QualType UnderlyingType = ED->getIntegerType(); + + if (UnderlyingType.isNull()) + UnderlyingType = ASTCtx.IntTy; + + return convertType(UnderlyingType); +} + +const llvm::abi::StructType * +QualTypeMapper::convertStructType(const clang::RecordDecl *RD) { + const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD); + + SmallVector<llvm::abi::FieldInfo, 16> Fields; + computeFieldInfo(RD, Fields, Layout); + + llvm::TypeSize Size = + llvm::TypeSize::getFixed(Layout.getSize().getQuantity() * 8); + llvm::Align Alignment = llvm::Align(Layout.getAlignment().getQuantity()); + + return Builder.getStructType(Fields, Size, Alignment); +} + +const llvm::abi::UnionType * +QualTypeMapper::convertUnionType(const clang::RecordDecl *RD) { + const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD); + + SmallVector<llvm::abi::FieldInfo, 16> Fields; + computeFieldInfo(RD, Fields, Layout); + + llvm::TypeSize Size = + llvm::TypeSize::getFixed(Layout.getSize().getQuantity() * 8); + llvm::Align Alignment = llvm::Align(Layout.getAlignment().getQuantity()); + + return Builder.getUnionType(Fields, Size, Alignment); +} + llvm::Align QualTypeMapper::getTypeAlign(QualType QT) const { return llvm::Align(ASTCtx.getTypeAlign(QT)); } diff --git a/llvm/include/llvm/ABI/Types.h b/llvm/include/llvm/ABI/Types.h index e99bee35acf77..2b91b72e9daf1 100644 --- a/llvm/include/llvm/ABI/Types.h +++ b/llvm/include/llvm/ABI/Types.h @@ -1,13 +1,27 @@ +//===- ABI/Types.h ----------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines the Types and related helper methods concerned to the +/// LLVMABI library which mirrors ABI related type information from +/// the LLVM frontend. +/// +//===----------------------------------------------------------------------===// #ifndef LLVM_ABI_TYPES_H #define LLVM_ABI_TYPES_H #include "llvm/ADT/APFloat.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/CallingConv.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/TypeSize.h" #include <cstdint> -#include <llvm/IR/CallingConv.h> namespace llvm { namespace abi { @@ -27,21 +41,21 @@ class Type { protected: TypeKind Kind; TypeSize SizeInBits; - Align AlignInBits; + Align Alignment; bool IsExplicitlyAligned; Type(TypeKind K, TypeSize Size, Align Align, bool ExplicitAlign = false) - : Kind(K), SizeInBits(Size), AlignInBits(Align), + : Kind(K), SizeInBits(Size), Alignment(Align), IsExplicitlyAligned(ExplicitAlign) {} public: TypeKind getKind() const { return Kind; } TypeSize getSizeInBits() const { return SizeInBits; } - Align getAlignInBits() const { return AlignInBits; } + Align getAlignment() const { return Alignment; } bool hasExplicitAlignment() const { return IsExplicitlyAligned; } void setExplicitAlignment(Align Align) { - AlignInBits = Align; + Alignment = Align; IsExplicitlyAligned = true; } @@ -109,7 +123,7 @@ class ArrayType : public Type { public: ArrayType(const Type *ElemType, uint64_t NumElems) : Type(TypeKind::Array, ElemType->getSizeInBits() * NumElems, - ElemType->getAlignInBits()), + ElemType->getAlignment()), ElementType(ElemType), NumElements(NumElems) {} const Type *getElementType() const { return ElementType; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits