25#include "llvm/IR/DataLayout.h"
26#include "llvm/IR/DerivedTypes.h"
27#include "llvm/IR/Module.h"
30using namespace CodeGen;
33 : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()),
34 Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()),
35 TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) {
36 SkippedLayout =
false;
37 LongDoubleReferenced =
false;
41 for (llvm::FoldingSet<CGFunctionInfo>::iterator
42 I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )
54 llvm::raw_svector_ostream OS(
TypeName);
75 if (TDD->getDeclContext())
76 TDD->printQualifiedName(OS, Policy);
85 Ty->setName(OS.str());
104 auto *FixedVT = cast<llvm::FixedVectorType>(R);
106 uint64_t BytePadded = std::max<uint64_t>(FixedVT->getNumElements(), 8);
107 return llvm::IntegerType::get(FixedVT->getContext(), BytePadded);
124 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I =
125 RecordDeclTypes.find(Ty);
126 return I != RecordDeclTypes.end() && !I->second->isOpaque();
140 if (!TT)
return true;
157 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
170 if (
const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
172 if (TypeCache.count(ED->getTypeForDecl())) {
176 if (!
ConvertType(ED->getIntegerType())->isIntegerTy(32))
182 DI->completeType(ED);
199 DI->completeType(RD);
207 if (RecordsWithOpaqueMemberPointers.count(Ty)) {
209 RecordsWithOpaqueMemberPointers.clear();
214 const llvm::fltSemantics &format,
215 bool UseNativeHalf =
false) {
216 if (&format == &llvm::APFloat::IEEEhalf()) {
218 return llvm::Type::getHalfTy(VMContext);
220 return llvm::Type::getInt16Ty(VMContext);
222 if (&format == &llvm::APFloat::BFloat())
223 return llvm::Type::getBFloatTy(VMContext);
224 if (&format == &llvm::APFloat::IEEEsingle())
225 return llvm::Type::getFloatTy(VMContext);
226 if (&format == &llvm::APFloat::IEEEdouble())
227 return llvm::Type::getDoubleTy(VMContext);
228 if (&format == &llvm::APFloat::IEEEquad())
229 return llvm::Type::getFP128Ty(VMContext);
230 if (&format == &llvm::APFloat::PPCDoubleDouble())
231 return llvm::Type::getPPC_FP128Ty(VMContext);
232 if (&format == &llvm::APFloat::x87DoubleExtended())
233 return llvm::Type::getX86_FP80Ty(VMContext);
234 llvm_unreachable(
"Unknown float format!");
237llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(
QualType QFT) {
251 for (
unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
255 SkippedLayout =
true;
273 llvm::Type *ResultType =
nullptr;
276 if (FunctionsBeingProcessed.count(FI)) {
279 SkippedLayout =
true;
310 if (
const RecordType *RT = dyn_cast<RecordType>(Ty))
313 llvm::Type *CachedType =
nullptr;
314 auto TCI = TypeCache.find(Ty);
315 if (TCI != TypeCache.end())
316 CachedType = TCI->second;
319#ifndef EXPENSIVE_CHECKS
325 llvm::Type *ResultType =
nullptr;
328#define TYPE(Class, Base)
329#define ABSTRACT_TYPE(Class, Base)
330#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
331#define DEPENDENT_TYPE(Class, Base) case Type::Class:
332#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
333#include "clang/AST/TypeNodes.inc"
334 llvm_unreachable(
"Non-canonical or dependent types aren't possible.");
336 case Type::Builtin: {
337 switch (cast<BuiltinType>(Ty)->
getKind()) {
338 case BuiltinType::Void:
339 case BuiltinType::ObjCId:
340 case BuiltinType::ObjCClass:
341 case BuiltinType::ObjCSel:
347 case BuiltinType::Bool:
352 case BuiltinType::Char_S:
353 case BuiltinType::Char_U:
354 case BuiltinType::SChar:
355 case BuiltinType::UChar:
356 case BuiltinType::Short:
357 case BuiltinType::UShort:
358 case BuiltinType::Int:
359 case BuiltinType::UInt:
360 case BuiltinType::Long:
361 case BuiltinType::ULong:
362 case BuiltinType::LongLong:
363 case BuiltinType::ULongLong:
364 case BuiltinType::WChar_S:
365 case BuiltinType::WChar_U:
366 case BuiltinType::Char8:
367 case BuiltinType::Char16:
368 case BuiltinType::Char32:
369 case BuiltinType::ShortAccum:
370 case BuiltinType::Accum:
371 case BuiltinType::LongAccum:
372 case BuiltinType::UShortAccum:
373 case BuiltinType::UAccum:
374 case BuiltinType::ULongAccum:
375 case BuiltinType::ShortFract:
376 case BuiltinType::Fract:
377 case BuiltinType::LongFract:
378 case BuiltinType::UShortFract:
379 case BuiltinType::UFract:
380 case BuiltinType::ULongFract:
381 case BuiltinType::SatShortAccum:
382 case BuiltinType::SatAccum:
383 case BuiltinType::SatLongAccum:
384 case BuiltinType::SatUShortAccum:
385 case BuiltinType::SatUAccum:
386 case BuiltinType::SatULongAccum:
387 case BuiltinType::SatShortFract:
388 case BuiltinType::SatFract:
389 case BuiltinType::SatLongFract:
390 case BuiltinType::SatUShortFract:
391 case BuiltinType::SatUFract:
392 case BuiltinType::SatULongFract:
397 case BuiltinType::Float16:
403 case BuiltinType::Half:
410 case BuiltinType::LongDouble:
411 LongDoubleReferenced =
true;
413 case BuiltinType::BFloat16:
414 case BuiltinType::Float:
415 case BuiltinType::Double:
416 case BuiltinType::Float128:
417 case BuiltinType::Ibm128:
423 case BuiltinType::NullPtr:
428 case BuiltinType::UInt128:
429 case BuiltinType::Int128:
433#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
434 case BuiltinType::Id:
435#include "clang/Basic/OpenCLImageTypes.def"
436#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
437 case BuiltinType::Id:
438#include "clang/Basic/OpenCLExtensionTypes.def"
439 case BuiltinType::OCLSampler:
440 case BuiltinType::OCLEvent:
441 case BuiltinType::OCLClkEvent:
442 case BuiltinType::OCLQueue:
443 case BuiltinType::OCLReserveID:
446 case BuiltinType::SveInt8:
447 case BuiltinType::SveUint8:
448 case BuiltinType::SveInt8x2:
449 case BuiltinType::SveUint8x2:
450 case BuiltinType::SveInt8x3:
451 case BuiltinType::SveUint8x3:
452 case BuiltinType::SveInt8x4:
453 case BuiltinType::SveUint8x4:
454 case BuiltinType::SveInt16:
455 case BuiltinType::SveUint16:
456 case BuiltinType::SveInt16x2:
457 case BuiltinType::SveUint16x2:
458 case BuiltinType::SveInt16x3:
459 case BuiltinType::SveUint16x3:
460 case BuiltinType::SveInt16x4:
461 case BuiltinType::SveUint16x4:
462 case BuiltinType::SveInt32:
463 case BuiltinType::SveUint32:
464 case BuiltinType::SveInt32x2:
465 case BuiltinType::SveUint32x2:
466 case BuiltinType::SveInt32x3:
467 case BuiltinType::SveUint32x3:
468 case BuiltinType::SveInt32x4:
469 case BuiltinType::SveUint32x4:
470 case BuiltinType::SveInt64:
471 case BuiltinType::SveUint64:
472 case BuiltinType::SveInt64x2:
473 case BuiltinType::SveUint64x2:
474 case BuiltinType::SveInt64x3:
475 case BuiltinType::SveUint64x3:
476 case BuiltinType::SveInt64x4:
477 case BuiltinType::SveUint64x4:
478 case BuiltinType::SveBool:
479 case BuiltinType::SveBoolx2:
480 case BuiltinType::SveBoolx4:
481 case BuiltinType::SveFloat16:
482 case BuiltinType::SveFloat16x2:
483 case BuiltinType::SveFloat16x3:
484 case BuiltinType::SveFloat16x4:
485 case BuiltinType::SveFloat32:
486 case BuiltinType::SveFloat32x2:
487 case BuiltinType::SveFloat32x3:
488 case BuiltinType::SveFloat32x4:
489 case BuiltinType::SveFloat64:
490 case BuiltinType::SveFloat64x2:
491 case BuiltinType::SveFloat64x3:
492 case BuiltinType::SveFloat64x4:
493 case BuiltinType::SveBFloat16:
494 case BuiltinType::SveBFloat16x2:
495 case BuiltinType::SveBFloat16x3:
496 case BuiltinType::SveBFloat16x4: {
500 Info.
EC.getKnownMinValue() *
503 case BuiltinType::SveCount:
504 return llvm::TargetExtType::get(
getLLVMContext(),
"aarch64.svcount");
505#define PPC_VECTOR_TYPE(Name, Id, Size) \
506 case BuiltinType::Id: \
508 llvm::FixedVectorType::get(ConvertType(Context.BoolTy), Size); \
510#include "clang/Basic/PPCTypes.def"
511#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
512#include "clang/Basic/RISCVVTypes.def"
520 llvm::Type *EltTy = llvm::ScalableVectorType::get(
526 Info.
EC.getKnownMinValue() *
529#define WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS) \
530 case BuiltinType::Id: { \
531 if (BuiltinType::Id == BuiltinType::WasmExternRef) \
532 ResultType = CGM.getTargetCodeGenInfo().getWasmExternrefReferenceType(); \
534 llvm_unreachable("Unexpected wasm reference builtin type!"); \
536#include "clang/Basic/WebAssemblyReferenceTypes.def"
537 case BuiltinType::Dependent:
538#define BUILTIN_TYPE(Id, SingletonId)
539#define PLACEHOLDER_TYPE(Id, SingletonId) \
540 case BuiltinType::Id:
541#include "clang/AST/BuiltinTypes.def"
542 llvm_unreachable(
"Unexpected placeholder builtin type!");
547 case Type::DeducedTemplateSpecialization:
548 llvm_unreachable(
"Unexpected undeduced type!");
549 case Type::Complex: {
550 llvm::Type *EltTy =
ConvertType(cast<ComplexType>(Ty)->getElementType());
551 ResultType = llvm::StructType::get(EltTy, EltTy);
554 case Type::LValueReference:
555 case Type::RValueReference: {
562 case Type::Pointer: {
570 case Type::VariableArray: {
573 "FIXME: We only handle trivial array types so far!");
579 case Type::IncompleteArray: {
582 "FIXME: We only handle trivial array types so far!");
586 if (!ResultType->isSized()) {
587 SkippedLayout =
true;
590 ResultType = llvm::ArrayType::get(ResultType, 0);
593 case Type::ConstantArray: {
599 if (!EltTy->isSized()) {
600 SkippedLayout =
true;
604 ResultType = llvm::ArrayType::get(EltTy, A->
getSize().getZExtValue());
607 case Type::ExtVector:
609 const auto *VT = cast<VectorType>(Ty);
611 llvm::Type *IRElemTy = VT->isExtVectorBoolType()
614 ResultType = llvm::FixedVectorType::get(IRElemTy, VT->getNumElements());
617 case Type::ConstantMatrix: {
624 case Type::FunctionNoProto:
625 case Type::FunctionProto:
626 ResultType = ConvertFunctionTypeInternal(T);
628 case Type::ObjCObject:
629 ResultType =
ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
632 case Type::ObjCInterface: {
636 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];
643 case Type::ObjCObjectPointer:
648 const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
658 case Type::BlockPointer: {
671 case Type::MemberPointer: {
672 auto *MPTy = cast<MemberPointerType>(Ty);
673 if (!
getCXXABI().isMemberPointerConvertible(MPTy)) {
674 auto *
C = MPTy->getClass();
675 auto Insertion = RecordsWithOpaqueMemberPointers.insert({
C,
nullptr});
676 if (Insertion.second)
677 Insertion.first->second = llvm::StructType::create(
getLLVMContext());
678 ResultType = Insertion.first->second;
686 QualType valueType = cast<AtomicType>(Ty)->getValueType();
690 uint64_t valueSize = Context.
getTypeSize(valueType);
692 if (valueSize != atomicSize) {
693 assert(valueSize < atomicSize);
694 llvm::Type *elts[] = {
696 llvm::ArrayType::get(CGM.
Int8Ty, (atomicSize - valueSize) / 8)
708 const auto &EIT = cast<BitIntType>(Ty);
709 ResultType = llvm::Type::getIntNTy(
getLLVMContext(), EIT->getNumBits());
714 assert(ResultType &&
"Didn't convert a type?");
715 assert((!CachedType || CachedType == ResultType) &&
716 "Cached type doesn't match computed type");
718 TypeCache[Ty] = ResultType;
736 llvm::StructType *&Entry = RecordDeclTypes[Key];
743 llvm::StructType *Ty = Entry;
752 if (
const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
753 for (
const auto &I : CRD->bases()) {
754 if (I.isVirtual())
continue;
761 CGRecordLayouts[Key] = std::move(Layout);
777 auto I = CGRecordLayouts.find(Key);
778 if (I != CGRecordLayouts.end())
784 I = CGRecordLayouts.find(Key);
786 assert(I != CGRecordLayouts.end() &&
787 "Unable to find record layout information for type");
801 if (isa<IncompleteArrayType>(AT))
803 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
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....
BuiltinVectorTypeInfo getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const
Returns the element type, element count and number of vectors (in case of tuple) for a builtin vector...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
QualType getRecordType(const RecordDecl *Decl) const
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const TargetInfo & getTargetInfo() const
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
unsigned getTargetAddressSpace(LangAS AS) const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
Represents a C++ struct/union/class.
Represents a canonical, potentially-qualified type.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
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...
CGFunctionInfo - Class to encapsulate the information about a function definition.
virtual llvm::Type * getPipeType(const PipeType *T, StringRef Name, llvm::Type *&PipeTy)
virtual llvm::Type * convertOpenCLSpecificType(const Type *T)
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.
CGDebugInfo * getModuleDebugInfo()
bool isPaddedAtomicType(QualType type)
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
CodeGenTypes(CodeGenModule &cgm)
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
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....
std::unique_ptr< CGRecordLayout > ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty)
Compute a new LLVM record layout object for the given record.
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.
void UpdateCompletedType(const TagDecl *TD)
UpdateCompletedType - When we find the full definition for a TagDecl, replace the 'opaque' type we pr...
llvm::LLVMContext & getLLVMContext()
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() 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...
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
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...
virtual llvm::Type * getCUDADeviceBuiltinSurfaceDeviceType() const
Return the device-side type for the CUDA device builtin surface type.
virtual llvm::Type * getCUDADeviceBuiltinTextureDeviceType() const
Return the device-side type for the CUDA device builtin texture type.
Represents the canonical version of C arrays with a specified constant size.
const llvm::APInt & getSize() const
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()
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
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.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
Represents a struct/union/class.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
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...
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isConstantMatrixType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorBoolType() const
bool isBitIntType() const
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isAnyPointerType() 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.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
@ C
Languages that the frontend can parse and compile.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces, where the name is u...