27#include "llvm/IR/DataLayout.h"
28#include "llvm/IR/DerivedTypes.h"
29#include "llvm/IR/Module.h"
35 : CGM(cgm), Context(cgm.
getContext()), TheModule(cgm.getModule()),
37 SkippedLayout =
false;
38 LongDoubleReferenced =
false;
42 for (llvm::FoldingSet<CGFunctionInfo>::iterator
43 I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )
50 return CGM.getCodeGenOpts();
57 llvm::raw_svector_ostream OS(
TypeName);
79 if (TDD->getDeclContext())
80 TDD->printQualifiedName(OS, Policy);
89 Ty->setName(OS.str());
104 if (
T->isConstantMatrixType()) {
105 const Type *Ty = Context.getCanonicalType(
T).getTypePtr();
114 if (
T->isExtVectorBoolType()) {
117 if (Context.getLangOpts().HLSL) {
119 return llvm::FixedVectorType::get(IRElemTy, FixedVT->getNumElements());
123 uint64_t BytePadded = std::max<uint64_t>(FixedVT->getNumElements(), 8);
124 return llvm::IntegerType::get(FixedVT->getContext(), BytePadded);
140 if (
T->isBitIntType()) {
142 return llvm::ArrayType::get(CGM.Int8Ty,
143 Context.getTypeSizeInChars(
T).getQuantity());
145 (
unsigned)Context.getTypeSize(
T));
148 if (R->isIntegerTy(1))
150 (
unsigned)Context.getTypeSize(
T));
157 llvm::Type *LLVMTy) {
161 CharUnits ASTSize = Context.getTypeSizeInChars(ASTTy);
164 return ASTSize != LLVMSize;
168 llvm::Type *LLVMTy) {
172 if (
T->isBitIntType())
173 return llvm::Type::getIntNTy(
176 if (LLVMTy->isIntegerTy(1))
178 (
unsigned)Context.getTypeSize(
T));
180 if (
T->isExtVectorBoolType())
189 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I =
190 RecordDeclTypes.find(Ty);
191 return I != RecordDeclTypes.end() && !I->second->isOpaque();
204 const TagType *TT = Ty->
getAs<TagType>();
205 if (!TT)
return true;
208 return !TT->isIncompleteType();
222 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
232 CanQualType T = CGM.getContext().getCanonicalTagType(TD);
236 if (
const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
238 if (TypeCache.count(
T->getTypePtr())) {
242 if (!
ConvertType(ED->getIntegerType())->isIntegerTy(32))
248 DI->completeType(ED);
259 if (RecordDeclTypes.count(
T.getTypePtr()))
265 DI->completeType(RD);
270 T = Context.getCanonicalType(
T);
272 const Type *Ty =
T.getTypePtr();
273 if (RecordsWithOpaqueMemberPointers.count(Ty)) {
275 RecordsWithOpaqueMemberPointers.clear();
280 const llvm::fltSemantics &
format,
281 bool UseNativeHalf =
false) {
282 if (&
format == &llvm::APFloat::IEEEhalf()) {
284 return llvm::Type::getHalfTy(VMContext);
286 return llvm::Type::getInt16Ty(VMContext);
288 if (&
format == &llvm::APFloat::BFloat())
289 return llvm::Type::getBFloatTy(VMContext);
290 if (&
format == &llvm::APFloat::IEEEsingle())
291 return llvm::Type::getFloatTy(VMContext);
292 if (&
format == &llvm::APFloat::IEEEdouble())
293 return llvm::Type::getDoubleTy(VMContext);
294 if (&
format == &llvm::APFloat::IEEEquad())
295 return llvm::Type::getFP128Ty(VMContext);
296 if (&
format == &llvm::APFloat::PPCDoubleDouble())
297 return llvm::Type::getPPC_FP128Ty(VMContext);
298 if (&
format == &llvm::APFloat::x87DoubleExtended())
299 return llvm::Type::getX86_FP80Ty(VMContext);
300 llvm_unreachable(
"Unknown float format!");
303llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) {
316 if (
const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT))
317 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
318 if (
const auto *RD = FPT->getParamType(i)->getAsRecordDecl())
321 SkippedLayout =
true;
329 const CGFunctionInfo *FI;
330 if (
const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
339 llvm::Type *ResultType =
nullptr;
342 if (FunctionsBeingProcessed.count(FI)) {
345 SkippedLayout =
true;
357 T = Context.getCanonicalType(
T);
359 const Type *Ty =
T.getTypePtr();
363 if (Context.getLangOpts().CUDAIsDevice) {
364 if (
T->isCUDADeviceBuiltinSurfaceType()) {
365 if (
auto *Ty = CGM.getTargetCodeGenInfo()
366 .getCUDADeviceBuiltinSurfaceDeviceType())
368 }
else if (
T->isCUDADeviceBuiltinTextureType()) {
369 if (
auto *Ty = CGM.getTargetCodeGenInfo()
370 .getCUDADeviceBuiltinTextureDeviceType())
376 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
379 llvm::Type *CachedType =
nullptr;
380 auto TCI = TypeCache.find(Ty);
381 if (TCI != TypeCache.end())
382 CachedType = TCI->second;
385#ifndef EXPENSIVE_CHECKS
391 llvm::Type *ResultType =
nullptr;
394#define TYPE(Class, Base)
395#define ABSTRACT_TYPE(Class, Base)
396#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
397#define DEPENDENT_TYPE(Class, Base) case Type::Class:
398#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
399#include "clang/AST/TypeNodes.inc"
400 llvm_unreachable(
"Non-canonical or dependent types aren't possible.");
402 case Type::Builtin: {
404 case BuiltinType::Void:
405 case BuiltinType::ObjCId:
406 case BuiltinType::ObjCClass:
407 case BuiltinType::ObjCSel:
413 case BuiltinType::Bool:
418 case BuiltinType::Char_S:
419 case BuiltinType::Char_U:
420 case BuiltinType::SChar:
421 case BuiltinType::UChar:
422 case BuiltinType::Short:
423 case BuiltinType::UShort:
424 case BuiltinType::Int:
425 case BuiltinType::UInt:
426 case BuiltinType::Long:
427 case BuiltinType::ULong:
428 case BuiltinType::LongLong:
429 case BuiltinType::ULongLong:
430 case BuiltinType::WChar_S:
431 case BuiltinType::WChar_U:
432 case BuiltinType::Char8:
433 case BuiltinType::Char16:
434 case BuiltinType::Char32:
435 case BuiltinType::ShortAccum:
436 case BuiltinType::Accum:
437 case BuiltinType::LongAccum:
438 case BuiltinType::UShortAccum:
439 case BuiltinType::UAccum:
440 case BuiltinType::ULongAccum:
441 case BuiltinType::ShortFract:
442 case BuiltinType::Fract:
443 case BuiltinType::LongFract:
444 case BuiltinType::UShortFract:
445 case BuiltinType::UFract:
446 case BuiltinType::ULongFract:
447 case BuiltinType::SatShortAccum:
448 case BuiltinType::SatAccum:
449 case BuiltinType::SatLongAccum:
450 case BuiltinType::SatUShortAccum:
451 case BuiltinType::SatUAccum:
452 case BuiltinType::SatULongAccum:
453 case BuiltinType::SatShortFract:
454 case BuiltinType::SatFract:
455 case BuiltinType::SatLongFract:
456 case BuiltinType::SatUShortFract:
457 case BuiltinType::SatUFract:
458 case BuiltinType::SatULongFract:
460 static_cast<unsigned>(Context.getTypeSize(
T)));
463 case BuiltinType::Float16:
469 case BuiltinType::Half:
473 Context.getLangOpts().NativeHalfType ||
474 !Context.getTargetInfo().useFP16ConversionIntrinsics());
476 case BuiltinType::LongDouble:
477 LongDoubleReferenced =
true;
479 case BuiltinType::BFloat16:
480 case BuiltinType::Float:
481 case BuiltinType::Double:
482 case BuiltinType::Float128:
483 case BuiltinType::Ibm128:
485 Context.getFloatTypeSemantics(
T),
489 case BuiltinType::NullPtr:
494 case BuiltinType::UInt128:
495 case BuiltinType::Int128:
499#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
500 case BuiltinType::Id:
501#include "clang/Basic/OpenCLImageTypes.def"
502#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
503 case BuiltinType::Id:
504#include "clang/Basic/OpenCLExtensionTypes.def"
505 case BuiltinType::OCLSampler:
506 case BuiltinType::OCLEvent:
507 case BuiltinType::OCLClkEvent:
508 case BuiltinType::OCLQueue:
509 case BuiltinType::OCLReserveID:
510 ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty);
512#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
513 case BuiltinType::Id:
514#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
515 case BuiltinType::Id:
516#include "clang/Basic/AArch64ACLETypes.def"
526 auto *VTy = llvm::VectorType::get(EltTy, Info.
EC);
529 llvm_unreachable(
"Expected 1, 2, 3 or 4 vectors!");
533 return llvm::StructType::get(VTy, VTy);
535 return llvm::StructType::get(VTy, VTy, VTy);
537 return llvm::StructType::get(VTy, VTy, VTy, VTy);
540 case BuiltinType::SveCount:
541 return llvm::TargetExtType::get(
getLLVMContext(),
"aarch64.svcount");
542 case BuiltinType::MFloat8:
543 return llvm::VectorType::get(llvm::Type::getInt8Ty(
getLLVMContext()), 1,
545#define PPC_VECTOR_TYPE(Name, Id, Size) \
546 case BuiltinType::Id: \
548 llvm::FixedVectorType::get(ConvertType(Context.BoolTy), Size); \
550#include "clang/Basic/PPCTypes.def"
551#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
552#include "clang/Basic/RISCVVTypes.def"
557 unsigned I8EltCount =
558 Info.
EC.getKnownMinValue() *
560 return llvm::TargetExtType::get(
562 llvm::ScalableVectorType::get(
567 Info.
EC.getKnownMinValue());
569#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
570 case BuiltinType::Id: { \
571 if (BuiltinType::Id == BuiltinType::WasmExternRef) \
572 ResultType = CGM.getTargetCodeGenInfo().getWasmExternrefReferenceType(); \
574 llvm_unreachable("Unexpected wasm reference builtin type!"); \
576#include "clang/Basic/WebAssemblyReferenceTypes.def"
577#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
578 case BuiltinType::Id: \
579 return llvm::PointerType::get(getLLVMContext(), AS);
580#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
581 case BuiltinType::Id: \
582 return llvm::TargetExtType::get(getLLVMContext(), "amdgcn.named.barrier", \
584#include "clang/Basic/AMDGPUTypes.def"
585#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
586#include "clang/Basic/HLSLIntangibleTypes.def"
587 ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
589 case BuiltinType::Dependent:
590#define BUILTIN_TYPE(Id, SingletonId)
591#define PLACEHOLDER_TYPE(Id, SingletonId) \
592 case BuiltinType::Id:
593#include "clang/AST/BuiltinTypes.def"
594 llvm_unreachable(
"Unexpected placeholder builtin type!");
599 case Type::DeducedTemplateSpecialization:
600 llvm_unreachable(
"Unexpected undeduced type!");
601 case Type::Complex: {
603 ResultType = llvm::StructType::get(EltTy, EltTy);
606 case Type::LValueReference:
607 case Type::RValueReference: {
614 case Type::Pointer: {
622 case Type::VariableArray: {
625 "FIXME: We only handle trivial array types so far!");
631 case Type::IncompleteArray: {
634 "FIXME: We only handle trivial array types so far!");
638 if (!ResultType->isSized()) {
639 SkippedLayout =
true;
642 ResultType = llvm::ArrayType::get(ResultType, 0);
645 case Type::ArrayParameter:
646 case Type::ConstantArray: {
652 if (!EltTy->isSized()) {
653 SkippedLayout =
true;
657 ResultType = llvm::ArrayType::get(EltTy, A->
getZExtSize());
660 case Type::ExtVector:
664 llvm::Type *IRElemTy = VT->isPackedVectorBoolType(Context)
666 : VT->getElementType()->isMFloat8Type()
669 ResultType = llvm::FixedVectorType::get(IRElemTy, VT->getNumElements());
672 case Type::ConstantMatrix: {
679 case Type::FunctionNoProto:
680 case Type::FunctionProto:
681 ResultType = ConvertFunctionTypeInternal(
T);
683 case Type::ObjCObject:
687 case Type::ObjCInterface: {
698 case Type::ObjCObjectPointer:
704 if (ED->isCompleteDefinition() || ED->isFixed())
713 case Type::BlockPointer: {
726 case Type::MemberPointer: {
728 if (!
getCXXABI().isMemberPointerConvertible(MPTy)) {
730 MPTy->getMostRecentCXXRecordDecl());
732 RecordsWithOpaqueMemberPointers.try_emplace(
T.getTypePtr());
733 if (Insertion.second)
734 Insertion.first->second = llvm::StructType::create(
getLLVMContext());
735 ResultType = Insertion.first->second;
747 uint64_t valueSize = Context.getTypeSize(valueType);
748 uint64_t atomicSize = Context.getTypeSize(Ty);
749 if (valueSize != atomicSize) {
750 assert(valueSize < atomicSize);
751 llvm::Type *elts[] = {
753 llvm::ArrayType::get(CGM.Int8Ty, (atomicSize - valueSize) / 8)
761 ResultType = CGM.getOpenCLRuntime().getPipeType(
cast<PipeType>(Ty));
766 ResultType = llvm::Type::getIntNTy(
getLLVMContext(), EIT->getNumBits());
769 case Type::HLSLAttributedResource:
770 case Type::HLSLInlineSpirv:
771 ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
775 assert(ResultType &&
"Didn't convert a type?");
776 assert((!CachedType || CachedType == ResultType) &&
777 "Cached type doesn't match computed type");
779 TypeCache[Ty] = ResultType;
788 return Context.getTypeSize(
type) != Context.getTypeSize(
type->getValueType());
795 const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();
797 llvm::StructType *&Entry = RecordDeclTypes[Key];
804 llvm::StructType *Ty = Entry;
813 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
814 for (
const auto &I : CRD->bases()) {
815 if (I.isVirtual())
continue;
822 CGRecordLayouts[Key] = std::move(Layout);
836 const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();
838 auto I = CGRecordLayouts.find(Key);
839 if (I != CGRecordLayouts.end())
845 I = CGRecordLayouts.find(Key);
847 assert(I != CGRecordLayouts.end() &&
848 "Unable to find record layout information for type");
853 assert((
T->isAnyPointerType() ||
T->isBlockPointerType() ||
854 T->isNullPtrType()) &&
861 return Context.getTargetNullPointerValue(
T) == 0;
863 if (
const auto *AT = Context.getAsArrayType(
T)) {
866 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
867 if (Context.getConstantArrayElementCount(CAT) == 0)
869 T = Context.getBaseElementType(
T);
874 if (
const auto *RD =
T->getAsRecordDecl())
882 if (
T->getAs<HLSLInlineSpirvType>())
898 return T->isFunctionType() && !
T.hasAddressSpace()
Defines the clang::ASTContext interface.
static llvm::Type * getTypeForFormat(llvm::LLVMContext &VMContext, const llvm::fltSemantics &format, bool UseNativeHalf=false)
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static CharUnits getTypeAllocSize(CodeGenModule &CGM, llvm::Type *type)
const clang::PrintingPolicy & getPrintingPolicy() const
unsigned getTargetAddressSpace(LangAS AS) const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
Represents a C++ struct/union/class.
static CanQual< T > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
CharUnits - This is an opaque type for sizes expressed in character units.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
Implements C++ ABI-specific code generation functions.
virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const
Return whether or not a member pointers type is convertible to an IR type.
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
virtual bool isZeroInitializable(const MemberPointerType *MPT)
Return true if the given member pointer can be zero-initialized (in the C++ sense) with an LLVM zeroi...
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
This class organizes the cross-function state that is used while generating LLVM code.
bool isPaddedAtomicType(QualType type)
CGCXXABI & getCXXABI() const
CodeGenTypes(CodeGenModule &cgm)
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
CGCXXABI & getCXXABI() const
bool isPointerZeroInitializable(QualType T)
Check if the pointer type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
const CodeGenOptions & getCodeGenOpts() const
ASTContext & getContext() const
const CGFunctionInfo & arrangeFreeFunctionType(CanQual< FunctionProtoType > Ty)
Arrange the argument and result information for a value of the given freestanding function type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....
const TargetInfo & getTarget() const
std::unique_ptr< CGRecordLayout > ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty)
Compute a new LLVM record layout object for the given record.
llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)
Given that T is a scalar type, return the IR type that should be used for load and store operations.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
unsigned getTargetAddressSpace(QualType T) const
llvm::StructType * ConvertRecordDeclType(const RecordDecl *TD)
ConvertRecordDeclType - Lay out a tagged decl type like struct or union.
void RefreshTypeCacheForClass(const CXXRecordDecl *RD)
Remove stale types from the type cache when an inheritance model gets assigned to a class.
bool isRecordLayoutComplete(const Type *Ty) const
isRecordLayoutComplete - Return true if the specified type is already completely laid out.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
CodeGenModule & getCGM() const
void UpdateCompletedType(const TagDecl *TD)
UpdateCompletedType - When we find the full definition for a TagDecl, replace the 'opaque' type we pr...
llvm::LLVMContext & getLLVMContext()
bool typeRequiresSplitIntoByteArray(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
Check whether the given type needs to be laid out in memory using an opaque byte-array type because i...
const llvm::DataLayout & getDataLayout() const
bool isFuncParamTypeConvertible(QualType Ty)
isFuncParamTypeConvertible - Return true if the specified type in a function parameter or result posi...
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
void addRecordTypeName(const RecordDecl *RD, llvm::StructType *Ty, StringRef suffix)
addRecordTypeName - Compute a name from the given record decl with an optional suffix and name the gi...
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
ASTContext & getASTContext() const LLVM_READONLY
DeclContext * getDeclContext()
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
Represents a C array with an unspecified size.
QualType getElementType() const
Returns type of the elements being stored in the matrix.
A pointer to member type per C++ 8.3.3 - Pointers to members.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Represents a struct/union/class.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeType() const
Represents the declaration of a struct/union/class/enum.
StringRef getKindName() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override
Pretty-print the unqualified name of this declaration.
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
bool isMFloat8Type() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
EnumDecl * castAsEnumDecl() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
Base class for declarations which introduce a typedef-name.
Represents a C array with a specified size that is not an integer-constant-expression.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.