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();
108 if (Context.getLangOpts().HLSL &&
T->isConstantMatrixBoolType())
110 return llvm::ArrayType::get(IRElemTy,
117 if (
T->isExtVectorBoolType()) {
120 if (Context.getLangOpts().HLSL) {
122 return llvm::FixedVectorType::get(IRElemTy, FixedVT->getNumElements());
126 uint64_t BytePadded = std::max<uint64_t>(FixedVT->getNumElements(), 8);
127 return llvm::IntegerType::get(FixedVT->getContext(), BytePadded);
143 if (
T->isBitIntType()) {
145 return llvm::ArrayType::get(CGM.Int8Ty,
146 Context.getTypeSizeInChars(
T).getQuantity());
148 (
unsigned)Context.getTypeSize(
T));
151 if (R->isIntegerTy(1))
153 (
unsigned)Context.getTypeSize(
T));
160 llvm::Type *LLVMTy) {
164 CharUnits ASTSize = Context.getTypeSizeInChars(ASTTy);
167 return ASTSize != LLVMSize;
171 llvm::Type *LLVMTy) {
175 if (
T->isBitIntType())
176 return llvm::Type::getIntNTy(
179 if (LLVMTy->isIntegerTy(1))
181 (
unsigned)Context.getTypeSize(
T));
183 if (
T->isExtVectorBoolType())
192 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I =
193 RecordDeclTypes.find(Ty);
194 return I != RecordDeclTypes.end() && !I->second->isOpaque();
207 const TagType *TT = Ty->
getAs<TagType>();
208 if (!TT)
return true;
211 return !TT->isIncompleteType();
225 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
235 CanQualType T = CGM.getContext().getCanonicalTagType(TD);
239 if (
const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
241 if (TypeCache.count(
T->getTypePtr())) {
245 if (!
ConvertType(ED->getIntegerType())->isIntegerTy(32))
251 DI->completeType(ED);
262 if (RecordDeclTypes.count(
T.getTypePtr()))
268 DI->completeType(RD);
273 T = Context.getCanonicalType(
T);
275 const Type *Ty =
T.getTypePtr();
276 if (RecordsWithOpaqueMemberPointers.count(Ty)) {
278 RecordsWithOpaqueMemberPointers.clear();
283 const llvm::fltSemantics &
format,
284 bool UseNativeHalf =
false) {
285 if (&
format == &llvm::APFloat::IEEEhalf()) {
287 return llvm::Type::getHalfTy(VMContext);
289 return llvm::Type::getInt16Ty(VMContext);
291 if (&
format == &llvm::APFloat::BFloat())
292 return llvm::Type::getBFloatTy(VMContext);
293 if (&
format == &llvm::APFloat::IEEEsingle())
294 return llvm::Type::getFloatTy(VMContext);
295 if (&
format == &llvm::APFloat::IEEEdouble())
296 return llvm::Type::getDoubleTy(VMContext);
297 if (&
format == &llvm::APFloat::IEEEquad())
298 return llvm::Type::getFP128Ty(VMContext);
299 if (&
format == &llvm::APFloat::PPCDoubleDouble())
300 return llvm::Type::getPPC_FP128Ty(VMContext);
301 if (&
format == &llvm::APFloat::x87DoubleExtended())
302 return llvm::Type::getX86_FP80Ty(VMContext);
303 llvm_unreachable(
"Unknown float format!");
306llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) {
319 if (
const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT))
320 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
321 if (
const auto *RD = FPT->getParamType(i)->getAsRecordDecl())
324 SkippedLayout =
true;
332 const CGFunctionInfo *FI;
333 if (
const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
342 llvm::Type *ResultType =
nullptr;
345 if (FunctionsBeingProcessed.count(FI)) {
348 SkippedLayout =
true;
360 T = Context.getCanonicalType(
T);
362 const Type *Ty =
T.getTypePtr();
366 if (Context.getLangOpts().CUDAIsDevice) {
367 if (
T->isCUDADeviceBuiltinSurfaceType()) {
368 if (
auto *Ty = CGM.getTargetCodeGenInfo()
369 .getCUDADeviceBuiltinSurfaceDeviceType())
371 }
else if (
T->isCUDADeviceBuiltinTextureType()) {
372 if (
auto *Ty = CGM.getTargetCodeGenInfo()
373 .getCUDADeviceBuiltinTextureDeviceType())
379 if (
const auto *RT = dyn_cast<RecordType>(Ty))
382 llvm::Type *CachedType =
nullptr;
383 auto TCI = TypeCache.find(Ty);
384 if (TCI != TypeCache.end())
385 CachedType = TCI->second;
388#ifndef EXPENSIVE_CHECKS
394 llvm::Type *ResultType =
nullptr;
397#define TYPE(Class, Base)
398#define ABSTRACT_TYPE(Class, Base)
399#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
400#define DEPENDENT_TYPE(Class, Base) case Type::Class:
401#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
402#include "clang/AST/TypeNodes.inc"
403 llvm_unreachable(
"Non-canonical or dependent types aren't possible.");
405 case Type::Builtin: {
407 case BuiltinType::Void:
408 case BuiltinType::ObjCId:
409 case BuiltinType::ObjCClass:
410 case BuiltinType::ObjCSel:
416 case BuiltinType::Bool:
421 case BuiltinType::Char_S:
422 case BuiltinType::Char_U:
423 case BuiltinType::SChar:
424 case BuiltinType::UChar:
425 case BuiltinType::Short:
426 case BuiltinType::UShort:
427 case BuiltinType::Int:
428 case BuiltinType::UInt:
429 case BuiltinType::Long:
430 case BuiltinType::ULong:
431 case BuiltinType::LongLong:
432 case BuiltinType::ULongLong:
433 case BuiltinType::WChar_S:
434 case BuiltinType::WChar_U:
435 case BuiltinType::Char8:
436 case BuiltinType::Char16:
437 case BuiltinType::Char32:
438 case BuiltinType::ShortAccum:
439 case BuiltinType::Accum:
440 case BuiltinType::LongAccum:
441 case BuiltinType::UShortAccum:
442 case BuiltinType::UAccum:
443 case BuiltinType::ULongAccum:
444 case BuiltinType::ShortFract:
445 case BuiltinType::Fract:
446 case BuiltinType::LongFract:
447 case BuiltinType::UShortFract:
448 case BuiltinType::UFract:
449 case BuiltinType::ULongFract:
450 case BuiltinType::SatShortAccum:
451 case BuiltinType::SatAccum:
452 case BuiltinType::SatLongAccum:
453 case BuiltinType::SatUShortAccum:
454 case BuiltinType::SatUAccum:
455 case BuiltinType::SatULongAccum:
456 case BuiltinType::SatShortFract:
457 case BuiltinType::SatFract:
458 case BuiltinType::SatLongFract:
459 case BuiltinType::SatUShortFract:
460 case BuiltinType::SatUFract:
461 case BuiltinType::SatULongFract:
463 static_cast<unsigned>(Context.getTypeSize(
T)));
466 case BuiltinType::Float16:
472 case BuiltinType::Half:
476 Context.getLangOpts().NativeHalfType ||
477 !Context.getTargetInfo().useFP16ConversionIntrinsics());
479 case BuiltinType::LongDouble:
480 LongDoubleReferenced =
true;
482 case BuiltinType::BFloat16:
483 case BuiltinType::Float:
484 case BuiltinType::Double:
485 case BuiltinType::Float128:
486 case BuiltinType::Ibm128:
488 Context.getFloatTypeSemantics(
T),
492 case BuiltinType::NullPtr:
497 case BuiltinType::UInt128:
498 case BuiltinType::Int128:
502#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
503 case BuiltinType::Id:
504#include "clang/Basic/OpenCLImageTypes.def"
505#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
506 case BuiltinType::Id:
507#include "clang/Basic/OpenCLExtensionTypes.def"
508 case BuiltinType::OCLSampler:
509 case BuiltinType::OCLEvent:
510 case BuiltinType::OCLClkEvent:
511 case BuiltinType::OCLQueue:
512 case BuiltinType::OCLReserveID:
513 ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty);
515#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
516 case BuiltinType::Id:
517#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
518 case BuiltinType::Id:
519#include "clang/Basic/AArch64ACLETypes.def"
529 auto *VTy = llvm::VectorType::get(EltTy, Info.
EC);
532 llvm_unreachable(
"Expected 1, 2, 3 or 4 vectors!");
536 return llvm::StructType::get(VTy, VTy);
538 return llvm::StructType::get(VTy, VTy, VTy);
540 return llvm::StructType::get(VTy, VTy, VTy, VTy);
543 case BuiltinType::SveCount:
544 return llvm::TargetExtType::get(
getLLVMContext(),
"aarch64.svcount");
545 case BuiltinType::MFloat8:
546 return llvm::VectorType::get(llvm::Type::getInt8Ty(
getLLVMContext()), 1,
548#define PPC_VECTOR_TYPE(Name, Id, Size) \
549 case BuiltinType::Id: \
551 llvm::FixedVectorType::get(ConvertType(Context.BoolTy), Size); \
553#include "clang/Basic/PPCTypes.def"
554#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
555#include "clang/Basic/RISCVVTypes.def"
560 unsigned I8EltCount =
561 Info.
EC.getKnownMinValue() *
563 return llvm::TargetExtType::get(
565 llvm::ScalableVectorType::get(
570 Info.
EC.getKnownMinValue());
572#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
573 case BuiltinType::Id: { \
574 if (BuiltinType::Id == BuiltinType::WasmExternRef) \
575 ResultType = CGM.getTargetCodeGenInfo().getWasmExternrefReferenceType(); \
577 llvm_unreachable("Unexpected wasm reference builtin type!"); \
579#include "clang/Basic/WebAssemblyReferenceTypes.def"
580#define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS) \
581 case BuiltinType::Id: \
582 return llvm::PointerType::get(getLLVMContext(), AS);
583#define AMDGPU_NAMED_BARRIER_TYPE(Name, Id, SingletonId, Width, Align, Scope) \
584 case BuiltinType::Id: \
585 return llvm::TargetExtType::get(getLLVMContext(), "amdgcn.named.barrier", \
587#include "clang/Basic/AMDGPUTypes.def"
588#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
589#include "clang/Basic/HLSLIntangibleTypes.def"
590 ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
592 case BuiltinType::Dependent:
593#define BUILTIN_TYPE(Id, SingletonId)
594#define PLACEHOLDER_TYPE(Id, SingletonId) \
595 case BuiltinType::Id:
596#include "clang/AST/BuiltinTypes.def"
597 llvm_unreachable(
"Unexpected placeholder builtin type!");
602 case Type::DeducedTemplateSpecialization:
603 llvm_unreachable(
"Unexpected undeduced type!");
604 case Type::Complex: {
606 ResultType = llvm::StructType::get(EltTy, EltTy);
609 case Type::LValueReference:
610 case Type::RValueReference: {
617 case Type::Pointer: {
625 case Type::VariableArray: {
628 "FIXME: We only handle trivial array types so far!");
634 case Type::IncompleteArray: {
637 "FIXME: We only handle trivial array types so far!");
641 if (!ResultType->isSized()) {
642 SkippedLayout =
true;
645 ResultType = llvm::ArrayType::get(ResultType, 0);
648 case Type::ArrayParameter:
649 case Type::ConstantArray: {
655 if (!EltTy->isSized()) {
656 SkippedLayout =
true;
660 ResultType = llvm::ArrayType::get(EltTy, A->
getZExtSize());
663 case Type::ExtVector:
667 llvm::Type *IRElemTy = VT->isPackedVectorBoolType(Context)
669 : VT->getElementType()->isMFloat8Type()
672 ResultType = llvm::FixedVectorType::get(IRElemTy, VT->getNumElements());
675 case Type::ConstantMatrix: {
682 case Type::FunctionNoProto:
683 case Type::FunctionProto:
684 ResultType = ConvertFunctionTypeInternal(
T);
686 case Type::ObjCObject:
690 case Type::ObjCInterface: {
701 case Type::ObjCObjectPointer:
707 if (ED->isCompleteDefinition() || ED->isFixed())
716 case Type::BlockPointer: {
729 case Type::MemberPointer: {
731 if (!
getCXXABI().isMemberPointerConvertible(MPTy)) {
733 MPTy->getMostRecentCXXRecordDecl());
735 RecordsWithOpaqueMemberPointers.try_emplace(
T.getTypePtr());
736 if (Insertion.second)
737 Insertion.first->second = llvm::StructType::create(
getLLVMContext());
738 ResultType = Insertion.first->second;
750 uint64_t valueSize = Context.getTypeSize(valueType);
751 uint64_t atomicSize = Context.getTypeSize(Ty);
752 if (valueSize != atomicSize) {
753 assert(valueSize < atomicSize);
754 llvm::Type *elts[] = {
756 llvm::ArrayType::get(CGM.Int8Ty, (atomicSize - valueSize) / 8)
764 ResultType = CGM.getOpenCLRuntime().getPipeType(
cast<PipeType>(Ty));
769 ResultType = llvm::Type::getIntNTy(
getLLVMContext(), EIT->getNumBits());
772 case Type::HLSLAttributedResource:
773 case Type::HLSLInlineSpirv:
774 ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
778 assert(ResultType &&
"Didn't convert a type?");
779 assert((!CachedType || CachedType == ResultType) &&
780 "Cached type doesn't match computed type");
782 TypeCache[Ty] = ResultType;
791 return Context.getTypeSize(
type) != Context.getTypeSize(
type->getValueType());
798 const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();
800 llvm::StructType *&Entry = RecordDeclTypes[Key];
807 llvm::StructType *Ty = Entry;
816 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
817 for (
const auto &I : CRD->bases()) {
818 if (I.isVirtual())
continue;
825 CGRecordLayouts[Key] = std::move(Layout);
839 const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();
841 auto I = CGRecordLayouts.find(Key);
842 if (I != CGRecordLayouts.end())
848 I = CGRecordLayouts.find(Key);
850 assert(I != CGRecordLayouts.end() &&
851 "Unable to find record layout information for type");
856 assert((
T->isAnyPointerType() ||
T->isBlockPointerType() ||
857 T->isNullPtrType()) &&
864 return Context.getTargetNullPointerValue(
T) == 0;
866 if (
const auto *AT = Context.getAsArrayType(
T)) {
869 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
870 if (Context.getConstantArrayElementCount(CAT) == 0)
872 T = Context.getBaseElementType(
T);
877 if (
const auto *RD =
T->getAsRecordDecl())
885 if (
T->getAs<HLSLInlineSpirvType>())
901 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.