902 lines · cpp
1//===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This is the code that handles AST -> LLVM type lowering.10//11//===----------------------------------------------------------------------===//12 13#include "CodeGenTypes.h"14#include "CGCXXABI.h"15#include "CGCall.h"16#include "CGDebugInfo.h"17#include "CGHLSLRuntime.h"18#include "CGOpenCLRuntime.h"19#include "CGRecordLayout.h"20#include "TargetInfo.h"21#include "clang/AST/ASTContext.h"22#include "clang/AST/DeclCXX.h"23#include "clang/AST/DeclObjC.h"24#include "clang/AST/Expr.h"25#include "clang/AST/RecordLayout.h"26#include "clang/CodeGen/CGFunctionInfo.h"27#include "llvm/IR/DataLayout.h"28#include "llvm/IR/DerivedTypes.h"29#include "llvm/IR/Module.h"30 31using namespace clang;32using namespace CodeGen;33 34CodeGenTypes::CodeGenTypes(CodeGenModule &cgm)35 : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()),36 Target(cgm.getTarget()) {37 SkippedLayout = false;38 LongDoubleReferenced = false;39}40 41CodeGenTypes::~CodeGenTypes() {42 for (llvm::FoldingSet<CGFunctionInfo>::iterator43 I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )44 delete &*I++;45}46 47CGCXXABI &CodeGenTypes::getCXXABI() const { return getCGM().getCXXABI(); }48 49const CodeGenOptions &CodeGenTypes::getCodeGenOpts() const {50 return CGM.getCodeGenOpts();51}52 53void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,54 llvm::StructType *Ty,55 StringRef suffix) {56 SmallString<256> TypeName;57 llvm::raw_svector_ostream OS(TypeName);58 OS << RD->getKindName() << '.';59 60 // FIXME: We probably want to make more tweaks to the printing policy. For61 // example, we should probably enable PrintCanonicalTypes and62 // FullyQualifiedNames.63 PrintingPolicy Policy = RD->getASTContext().getPrintingPolicy();64 Policy.SuppressInlineNamespace =65 PrintingPolicy::SuppressInlineNamespaceMode::None;66 67 // Name the codegen type after the typedef name68 // if there is no tag type name available69 if (RD->getIdentifier()) {70 // FIXME: We should not have to check for a null decl context here.71 // Right now we do it because the implicit Obj-C decls don't have one.72 if (RD->getDeclContext())73 RD->printQualifiedName(OS, Policy);74 else75 RD->printName(OS, Policy);76 } else if (const TypedefNameDecl *TDD = RD->getTypedefNameForAnonDecl()) {77 // FIXME: We should not have to check for a null decl context here.78 // Right now we do it because the implicit Obj-C decls don't have one.79 if (TDD->getDeclContext())80 TDD->printQualifiedName(OS, Policy);81 else82 TDD->printName(OS);83 } else84 OS << "anon";85 86 if (!suffix.empty())87 OS << suffix;88 89 Ty->setName(OS.str());90}91 92/// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from93/// ConvertType in that it is used to convert to the memory representation for94/// a type. For example, the scalar representation for _Bool is i1, but the95/// memory representation is usually i8 or i32, depending on the target.96///97/// We generally assume that the alloc size of this type under the LLVM98/// data layout is the same as the size of the AST type. The alignment99/// does not have to match: Clang should always use explicit alignments100/// and packed structs as necessary to produce the layout it needs.101/// But the size does need to be exactly right or else things like struct102/// layout will break.103llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {104 if (T->isConstantMatrixType()) {105 const Type *Ty = Context.getCanonicalType(T).getTypePtr();106 const ConstantMatrixType *MT = cast<ConstantMatrixType>(Ty);107 return llvm::ArrayType::get(ConvertType(MT->getElementType()),108 MT->getNumRows() * MT->getNumColumns());109 }110 111 llvm::Type *R = ConvertType(T);112 113 // Check for the boolean vector case.114 if (T->isExtVectorBoolType()) {115 auto *FixedVT = cast<llvm::FixedVectorType>(R);116 117 if (Context.getLangOpts().HLSL) {118 llvm::Type *IRElemTy = ConvertTypeForMem(Context.BoolTy);119 return llvm::FixedVectorType::get(IRElemTy, FixedVT->getNumElements());120 }121 122 // Pad to at least one byte.123 uint64_t BytePadded = std::max<uint64_t>(FixedVT->getNumElements(), 8);124 return llvm::IntegerType::get(FixedVT->getContext(), BytePadded);125 }126 127 // If T is _Bool or a _BitInt type, ConvertType will produce an IR type128 // with the exact semantic bit-width of the AST type; for example,129 // _BitInt(17) will turn into i17. In memory, however, we need to store130 // such values extended to their full storage size as decided by AST131 // layout; this is an ABI requirement. Ideally, we would always use an132 // integer type that's just the bit-size of the AST type; for example, if133 // sizeof(_BitInt(17)) == 4, _BitInt(17) would turn into i32. That is what's134 // returned by convertTypeForLoadStore. However, that type does not135 // always satisfy the size requirement on memory representation types136 // describe above. For example, a 32-bit platform might reasonably set137 // sizeof(_BitInt(65)) == 12, but i96 is likely to have to have an alloc size138 // of 16 bytes in the LLVM data layout. In these cases, we simply return139 // a byte array of the appropriate size.140 if (T->isBitIntType()) {141 if (typeRequiresSplitIntoByteArray(T, R))142 return llvm::ArrayType::get(CGM.Int8Ty,143 Context.getTypeSizeInChars(T).getQuantity());144 return llvm::IntegerType::get(getLLVMContext(),145 (unsigned)Context.getTypeSize(T));146 }147 148 if (R->isIntegerTy(1))149 return llvm::IntegerType::get(getLLVMContext(),150 (unsigned)Context.getTypeSize(T));151 152 // Else, don't map it.153 return R;154}155 156bool CodeGenTypes::typeRequiresSplitIntoByteArray(QualType ASTTy,157 llvm::Type *LLVMTy) {158 if (!LLVMTy)159 LLVMTy = ConvertType(ASTTy);160 161 CharUnits ASTSize = Context.getTypeSizeInChars(ASTTy);162 CharUnits LLVMSize =163 CharUnits::fromQuantity(getDataLayout().getTypeAllocSize(LLVMTy));164 return ASTSize != LLVMSize;165}166 167llvm::Type *CodeGenTypes::convertTypeForLoadStore(QualType T,168 llvm::Type *LLVMTy) {169 if (!LLVMTy)170 LLVMTy = ConvertType(T);171 172 if (T->isBitIntType())173 return llvm::Type::getIntNTy(174 getLLVMContext(), Context.getTypeSizeInChars(T).getQuantity() * 8);175 176 if (LLVMTy->isIntegerTy(1))177 return llvm::IntegerType::get(getLLVMContext(),178 (unsigned)Context.getTypeSize(T));179 180 if (T->isExtVectorBoolType())181 return ConvertTypeForMem(T);182 183 return LLVMTy;184}185 186/// isRecordLayoutComplete - Return true if the specified type is already187/// completely laid out.188bool CodeGenTypes::isRecordLayoutComplete(const Type *Ty) const {189 llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I =190 RecordDeclTypes.find(Ty);191 return I != RecordDeclTypes.end() && !I->second->isOpaque();192}193 194/// isFuncParamTypeConvertible - Return true if the specified type in a195/// function parameter or result position can be converted to an IR type at this196/// point. This boils down to being whether it is complete.197bool CodeGenTypes::isFuncParamTypeConvertible(QualType Ty) {198 // Some ABIs cannot have their member pointers represented in IR unless199 // certain circumstances have been reached.200 if (const auto *MPT = Ty->getAs<MemberPointerType>())201 return getCXXABI().isMemberPointerConvertible(MPT);202 203 // If this isn't a tagged type, we can convert it!204 const TagType *TT = Ty->getAs<TagType>();205 if (!TT) return true;206 207 // Incomplete types cannot be converted.208 return !TT->isIncompleteType();209}210 211 212/// Code to verify a given function type is complete, i.e. the return type213/// and all of the parameter types are complete. Also check to see if we are in214/// a RS_StructPointer context, and if so whether any struct types have been215/// pended. If so, we don't want to ask the ABI lowering code to handle a type216/// that cannot be converted to an IR type.217bool CodeGenTypes::isFuncTypeConvertible(const FunctionType *FT) {218 if (!isFuncParamTypeConvertible(FT->getReturnType()))219 return false;220 221 if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT))222 for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++)223 if (!isFuncParamTypeConvertible(FPT->getParamType(i)))224 return false;225 226 return true;227}228 229/// UpdateCompletedType - When we find the full definition for a TagDecl,230/// replace the 'opaque' type we previously made for it if applicable.231void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {232 CanQualType T = CGM.getContext().getCanonicalTagType(TD);233 // If this is an enum being completed, then we flush all non-struct types from234 // the cache. This allows function types and other things that may be derived235 // from the enum to be recomputed.236 if (const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {237 // Only flush the cache if we've actually already converted this type.238 if (TypeCache.count(T->getTypePtr())) {239 // Okay, we formed some types based on this. We speculated that the enum240 // would be lowered to i32, so we only need to flush the cache if this241 // didn't happen.242 if (!ConvertType(ED->getIntegerType())->isIntegerTy(32))243 TypeCache.clear();244 }245 // If necessary, provide the full definition of a type only used with a246 // declaration so far.247 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())248 DI->completeType(ED);249 return;250 }251 252 // If we completed a RecordDecl that we previously used and converted to an253 // anonymous type, then go ahead and complete it now.254 const RecordDecl *RD = cast<RecordDecl>(TD);255 if (RD->isDependentType()) return;256 257 // Only complete it if we converted it already. If we haven't converted it258 // yet, we'll just do it lazily.259 if (RecordDeclTypes.count(T.getTypePtr()))260 ConvertRecordDeclType(RD);261 262 // If necessary, provide the full definition of a type only used with a263 // declaration so far.264 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())265 DI->completeType(RD);266}267 268void CodeGenTypes::RefreshTypeCacheForClass(const CXXRecordDecl *RD) {269 CanQualType T = Context.getCanonicalTagType(RD);270 T = Context.getCanonicalType(T);271 272 const Type *Ty = T.getTypePtr();273 if (RecordsWithOpaqueMemberPointers.count(Ty)) {274 TypeCache.clear();275 RecordsWithOpaqueMemberPointers.clear();276 }277}278 279static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,280 const llvm::fltSemantics &format,281 bool UseNativeHalf = false) {282 if (&format == &llvm::APFloat::IEEEhalf()) {283 if (UseNativeHalf)284 return llvm::Type::getHalfTy(VMContext);285 else286 return llvm::Type::getInt16Ty(VMContext);287 }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!");301}302 303llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) {304 assert(QFT.isCanonical());305 const FunctionType *FT = cast<FunctionType>(QFT.getTypePtr());306 // First, check whether we can build the full function type. If the307 // function type depends on an incomplete type (e.g. a struct or enum), we308 // cannot lower the function type.309 if (!isFuncTypeConvertible(FT)) {310 // This function's type depends on an incomplete tag type.311 312 // Force conversion of all the relevant record types, to make sure313 // we re-convert the FunctionType when appropriate.314 if (const auto *RD = FT->getReturnType()->getAsRecordDecl())315 ConvertRecordDeclType(RD);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())319 ConvertRecordDeclType(RD);320 321 SkippedLayout = true;322 323 // Return a placeholder type.324 return llvm::StructType::get(getLLVMContext());325 }326 327 // The function type can be built; call the appropriate routines to328 // build it.329 const CGFunctionInfo *FI;330 if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {331 FI = &arrangeFreeFunctionType(332 CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0)));333 } else {334 const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(FT);335 FI = &arrangeFreeFunctionType(336 CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT, 0)));337 }338 339 llvm::Type *ResultType = nullptr;340 // If there is something higher level prodding our CGFunctionInfo, then341 // don't recurse into it again.342 if (FunctionsBeingProcessed.count(FI)) {343 344 ResultType = llvm::StructType::get(getLLVMContext());345 SkippedLayout = true;346 } else {347 348 // Otherwise, we're good to go, go ahead and convert it.349 ResultType = GetFunctionType(*FI);350 }351 352 return ResultType;353}354 355/// ConvertType - Convert the specified type to its LLVM form.356llvm::Type *CodeGenTypes::ConvertType(QualType T) {357 T = Context.getCanonicalType(T);358 359 const Type *Ty = T.getTypePtr();360 361 // For the device-side compilation, CUDA device builtin surface/texture types362 // may be represented in different types.363 if (Context.getLangOpts().CUDAIsDevice) {364 if (T->isCUDADeviceBuiltinSurfaceType()) {365 if (auto *Ty = CGM.getTargetCodeGenInfo()366 .getCUDADeviceBuiltinSurfaceDeviceType())367 return Ty;368 } else if (T->isCUDADeviceBuiltinTextureType()) {369 if (auto *Ty = CGM.getTargetCodeGenInfo()370 .getCUDADeviceBuiltinTextureDeviceType())371 return Ty;372 }373 }374 375 // RecordTypes are cached and processed specially.376 if (const auto *RT = dyn_cast<RecordType>(Ty))377 return ConvertRecordDeclType(RT->getDecl()->getDefinitionOrSelf());378 379 llvm::Type *CachedType = nullptr;380 auto TCI = TypeCache.find(Ty);381 if (TCI != TypeCache.end())382 CachedType = TCI->second;383 // With expensive checks, check that the type we compute matches the384 // cached type.385#ifndef EXPENSIVE_CHECKS386 if (CachedType)387 return CachedType;388#endif389 390 // If we don't have it in the cache, convert it now.391 llvm::Type *ResultType = nullptr;392 switch (Ty->getTypeClass()) {393 case Type::Record: // Handled above.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.");401 402 case Type::Builtin: {403 switch (cast<BuiltinType>(Ty)->getKind()) {404 case BuiltinType::Void:405 case BuiltinType::ObjCId:406 case BuiltinType::ObjCClass:407 case BuiltinType::ObjCSel:408 // LLVM void type can only be used as the result of a function call. Just409 // map to the same as char.410 ResultType = llvm::Type::getInt8Ty(getLLVMContext());411 break;412 413 case BuiltinType::Bool:414 // Note that we always return bool as i1 for use as a scalar type.415 ResultType = llvm::Type::getInt1Ty(getLLVMContext());416 break;417 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:459 ResultType = llvm::IntegerType::get(getLLVMContext(),460 static_cast<unsigned>(Context.getTypeSize(T)));461 break;462 463 case BuiltinType::Float16:464 ResultType =465 getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T),466 /* UseNativeHalf = */ true);467 break;468 469 case BuiltinType::Half:470 // Half FP can either be storage-only (lowered to i16) or native.471 ResultType = getTypeForFormat(472 getLLVMContext(), Context.getFloatTypeSemantics(T),473 Context.getLangOpts().NativeHalfType ||474 !Context.getTargetInfo().useFP16ConversionIntrinsics());475 break;476 case BuiltinType::LongDouble:477 LongDoubleReferenced = true;478 [[fallthrough]];479 case BuiltinType::BFloat16:480 case BuiltinType::Float:481 case BuiltinType::Double:482 case BuiltinType::Float128:483 case BuiltinType::Ibm128:484 ResultType = getTypeForFormat(getLLVMContext(),485 Context.getFloatTypeSemantics(T),486 /* UseNativeHalf = */ false);487 break;488 489 case BuiltinType::NullPtr:490 // Model std::nullptr_t as i8*491 ResultType = llvm::PointerType::getUnqual(getLLVMContext());492 break;493 494 case BuiltinType::UInt128:495 case BuiltinType::Int128:496 ResultType = llvm::IntegerType::get(getLLVMContext(), 128);497 break;498 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);511 break;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"517 {518 ASTContext::BuiltinVectorTypeInfo Info =519 Context.getBuiltinVectorTypeInfo(cast<BuiltinType>(Ty));520 // The `__mfp8` type maps to `<1 x i8>` which can't be used to build521 // a <N x i8> vector type, hence bypass the call to `ConvertType` for522 // the element type and create the vector type directly.523 auto *EltTy = Info.ElementType->isMFloat8Type()524 ? llvm::Type::getInt8Ty(getLLVMContext())525 : ConvertType(Info.ElementType);526 auto *VTy = llvm::VectorType::get(EltTy, Info.EC);527 switch (Info.NumVectors) {528 default:529 llvm_unreachable("Expected 1, 2, 3 or 4 vectors!");530 case 1:531 return VTy;532 case 2:533 return llvm::StructType::get(VTy, VTy);534 case 3:535 return llvm::StructType::get(VTy, VTy, VTy);536 case 4:537 return llvm::StructType::get(VTy, VTy, VTy, VTy);538 }539 }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,544 false);545#define PPC_VECTOR_TYPE(Name, Id, Size) \546 case BuiltinType::Id: \547 ResultType = \548 llvm::FixedVectorType::get(ConvertType(Context.BoolTy), Size); \549 break;550#include "clang/Basic/PPCTypes.def"551#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:552#include "clang/Basic/RISCVVTypes.def"553 {554 ASTContext::BuiltinVectorTypeInfo Info =555 Context.getBuiltinVectorTypeInfo(cast<BuiltinType>(Ty));556 if (Info.NumVectors != 1) {557 unsigned I8EltCount =558 Info.EC.getKnownMinValue() *559 ConvertType(Info.ElementType)->getScalarSizeInBits() / 8;560 return llvm::TargetExtType::get(561 getLLVMContext(), "riscv.vector.tuple",562 llvm::ScalableVectorType::get(563 llvm::Type::getInt8Ty(getLLVMContext()), I8EltCount),564 Info.NumVectors);565 }566 return llvm::ScalableVectorType::get(ConvertType(Info.ElementType),567 Info.EC.getKnownMinValue());568 }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(); \573 else \574 llvm_unreachable("Unexpected wasm reference builtin type!"); \575 } break;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", \583 {}, {Scope});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);588 break;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!");595 }596 break;597 }598 case Type::Auto:599 case Type::DeducedTemplateSpecialization:600 llvm_unreachable("Unexpected undeduced type!");601 case Type::Complex: {602 llvm::Type *EltTy = ConvertType(cast<ComplexType>(Ty)->getElementType());603 ResultType = llvm::StructType::get(EltTy, EltTy);604 break;605 }606 case Type::LValueReference:607 case Type::RValueReference: {608 const ReferenceType *RTy = cast<ReferenceType>(Ty);609 QualType ETy = RTy->getPointeeType();610 unsigned AS = getTargetAddressSpace(ETy);611 ResultType = llvm::PointerType::get(getLLVMContext(), AS);612 break;613 }614 case Type::Pointer: {615 const PointerType *PTy = cast<PointerType>(Ty);616 QualType ETy = PTy->getPointeeType();617 unsigned AS = getTargetAddressSpace(ETy);618 ResultType = llvm::PointerType::get(getLLVMContext(), AS);619 break;620 }621 622 case Type::VariableArray: {623 const VariableArrayType *A = cast<VariableArrayType>(Ty);624 assert(A->getIndexTypeCVRQualifiers() == 0 &&625 "FIXME: We only handle trivial array types so far!");626 // VLAs resolve to the innermost element type; this matches627 // the return of alloca, and there isn't any obviously better choice.628 ResultType = ConvertTypeForMem(A->getElementType());629 break;630 }631 case Type::IncompleteArray: {632 const IncompleteArrayType *A = cast<IncompleteArrayType>(Ty);633 assert(A->getIndexTypeCVRQualifiers() == 0 &&634 "FIXME: We only handle trivial array types so far!");635 // int X[] -> [0 x int], unless the element type is not sized. If it is636 // unsized (e.g. an incomplete struct) just use [0 x i8].637 ResultType = ConvertTypeForMem(A->getElementType());638 if (!ResultType->isSized()) {639 SkippedLayout = true;640 ResultType = llvm::Type::getInt8Ty(getLLVMContext());641 }642 ResultType = llvm::ArrayType::get(ResultType, 0);643 break;644 }645 case Type::ArrayParameter:646 case Type::ConstantArray: {647 const ConstantArrayType *A = cast<ConstantArrayType>(Ty);648 llvm::Type *EltTy = ConvertTypeForMem(A->getElementType());649 650 // Lower arrays of undefined struct type to arrays of i8 just to have a651 // concrete type.652 if (!EltTy->isSized()) {653 SkippedLayout = true;654 EltTy = llvm::Type::getInt8Ty(getLLVMContext());655 }656 657 ResultType = llvm::ArrayType::get(EltTy, A->getZExtSize());658 break;659 }660 case Type::ExtVector:661 case Type::Vector: {662 const auto *VT = cast<VectorType>(Ty);663 // An ext_vector_type of Bool is really a vector of bits.664 llvm::Type *IRElemTy = VT->isPackedVectorBoolType(Context)665 ? llvm::Type::getInt1Ty(getLLVMContext())666 : VT->getElementType()->isMFloat8Type()667 ? llvm::Type::getInt8Ty(getLLVMContext())668 : ConvertType(VT->getElementType());669 ResultType = llvm::FixedVectorType::get(IRElemTy, VT->getNumElements());670 break;671 }672 case Type::ConstantMatrix: {673 const ConstantMatrixType *MT = cast<ConstantMatrixType>(Ty);674 ResultType =675 llvm::FixedVectorType::get(ConvertType(MT->getElementType()),676 MT->getNumRows() * MT->getNumColumns());677 break;678 }679 case Type::FunctionNoProto:680 case Type::FunctionProto:681 ResultType = ConvertFunctionTypeInternal(T);682 break;683 case Type::ObjCObject:684 ResultType = ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());685 break;686 687 case Type::ObjCInterface: {688 // Objective-C interfaces are always opaque (outside of the689 // runtime, which can do whatever it likes); we never refine690 // these.691 llvm::Type *&T = InterfaceTypes[cast<ObjCInterfaceType>(Ty)];692 if (!T)693 T = llvm::StructType::create(getLLVMContext());694 ResultType = T;695 break;696 }697 698 case Type::ObjCObjectPointer:699 ResultType = llvm::PointerType::getUnqual(getLLVMContext());700 break;701 702 case Type::Enum: {703 const auto *ED = Ty->castAsEnumDecl();704 if (ED->isCompleteDefinition() || ED->isFixed())705 return ConvertType(ED->getIntegerType());706 // Return a placeholder 'i32' type. This can be changed later when the707 // type is defined (see UpdateCompletedType), but is likely to be the708 // "right" answer.709 ResultType = llvm::Type::getInt32Ty(getLLVMContext());710 break;711 }712 713 case Type::BlockPointer: {714 // Block pointers lower to function type. For function type,715 // getTargetAddressSpace() returns default address space for716 // function pointer i.e. program address space. Therefore, for block717 // pointers, it is important to pass the pointee AST address space when718 // calling getTargetAddressSpace(), to ensure that we get the LLVM IR719 // address space for data pointers and not function pointers.720 const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();721 unsigned AS = Context.getTargetAddressSpace(FTy.getAddressSpace());722 ResultType = llvm::PointerType::get(getLLVMContext(), AS);723 break;724 }725 726 case Type::MemberPointer: {727 auto *MPTy = cast<MemberPointerType>(Ty);728 if (!getCXXABI().isMemberPointerConvertible(MPTy)) {729 CanQualType T = CGM.getContext().getCanonicalTagType(730 MPTy->getMostRecentCXXRecordDecl());731 auto Insertion =732 RecordsWithOpaqueMemberPointers.try_emplace(T.getTypePtr());733 if (Insertion.second)734 Insertion.first->second = llvm::StructType::create(getLLVMContext());735 ResultType = Insertion.first->second;736 } else {737 ResultType = getCXXABI().ConvertMemberPointerType(MPTy);738 }739 break;740 }741 742 case Type::Atomic: {743 QualType valueType = cast<AtomicType>(Ty)->getValueType();744 ResultType = ConvertTypeForMem(valueType);745 746 // Pad out to the inflated size if necessary.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[] = {752 ResultType,753 llvm::ArrayType::get(CGM.Int8Ty, (atomicSize - valueSize) / 8)754 };755 ResultType =756 llvm::StructType::get(getLLVMContext(), llvm::ArrayRef(elts));757 }758 break;759 }760 case Type::Pipe: {761 ResultType = CGM.getOpenCLRuntime().getPipeType(cast<PipeType>(Ty));762 break;763 }764 case Type::BitInt: {765 const auto &EIT = cast<BitIntType>(Ty);766 ResultType = llvm::Type::getIntNTy(getLLVMContext(), EIT->getNumBits());767 break;768 }769 case Type::HLSLAttributedResource:770 case Type::HLSLInlineSpirv:771 ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);772 break;773 }774 775 assert(ResultType && "Didn't convert a type?");776 assert((!CachedType || CachedType == ResultType) &&777 "Cached type doesn't match computed type");778 779 TypeCache[Ty] = ResultType;780 return ResultType;781}782 783bool CodeGenModule::isPaddedAtomicType(QualType type) {784 return isPaddedAtomicType(type->castAs<AtomicType>());785}786 787bool CodeGenModule::isPaddedAtomicType(const AtomicType *type) {788 return Context.getTypeSize(type) != Context.getTypeSize(type->getValueType());789}790 791/// ConvertRecordDeclType - Lay out a tagged decl type like struct or union.792llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) {793 // TagDecl's are not necessarily unique, instead use the (clang)794 // type connected to the decl.795 const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();796 797 llvm::StructType *&Entry = RecordDeclTypes[Key];798 799 // If we don't have a StructType at all yet, create the forward declaration.800 if (!Entry) {801 Entry = llvm::StructType::create(getLLVMContext());802 addRecordTypeName(RD, Entry, "");803 }804 llvm::StructType *Ty = Entry;805 806 // If this is still a forward declaration, or the LLVM type is already807 // complete, there's nothing more to do.808 RD = RD->getDefinition();809 if (!RD || !RD->isCompleteDefinition() || !Ty->isOpaque())810 return Ty;811 812 // Force conversion of non-virtual base classes recursively.813 if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {814 for (const auto &I : CRD->bases()) {815 if (I.isVirtual()) continue;816 ConvertRecordDeclType(I.getType()->castAsRecordDecl());817 }818 }819 820 // Layout fields.821 std::unique_ptr<CGRecordLayout> Layout = ComputeRecordLayout(RD, Ty);822 CGRecordLayouts[Key] = std::move(Layout);823 824 // If this struct blocked a FunctionType conversion, then recompute whatever825 // was derived from that.826 // FIXME: This is hugely overconservative.827 if (SkippedLayout)828 TypeCache.clear();829 830 return Ty;831}832 833/// getCGRecordLayout - Return record layout info for the given record decl.834const CGRecordLayout &835CodeGenTypes::getCGRecordLayout(const RecordDecl *RD) {836 const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();837 838 auto I = CGRecordLayouts.find(Key);839 if (I != CGRecordLayouts.end())840 return *I->second;841 // Compute the type information.842 ConvertRecordDeclType(RD);843 844 // Now try again.845 I = CGRecordLayouts.find(Key);846 847 assert(I != CGRecordLayouts.end() &&848 "Unable to find record layout information for type");849 return *I->second;850}851 852bool CodeGenTypes::isPointerZeroInitializable(QualType T) {853 assert((T->isAnyPointerType() || T->isBlockPointerType() ||854 T->isNullPtrType()) &&855 "Invalid type");856 return isZeroInitializable(T);857}858 859bool CodeGenTypes::isZeroInitializable(QualType T) {860 if (T->getAs<PointerType>() || T->isNullPtrType())861 return Context.getTargetNullPointerValue(T) == 0;862 863 if (const auto *AT = Context.getAsArrayType(T)) {864 if (isa<IncompleteArrayType>(AT))865 return true;866 if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))867 if (Context.getConstantArrayElementCount(CAT) == 0)868 return true;869 T = Context.getBaseElementType(T);870 }871 872 // Records are non-zero-initializable if they contain any873 // non-zero-initializable subobjects.874 if (const auto *RD = T->getAsRecordDecl())875 return isZeroInitializable(RD);876 877 // We have to ask the ABI about member pointers.878 if (const MemberPointerType *MPT = T->getAs<MemberPointerType>())879 return getCXXABI().isZeroInitializable(MPT);880 881 // HLSL Inline SPIR-V types are non-zero-initializable.882 if (T->getAs<HLSLInlineSpirvType>())883 return false;884 885 // Everything else is okay.886 return true;887}888 889bool CodeGenTypes::isZeroInitializable(const RecordDecl *RD) {890 return getCGRecordLayout(RD).isZeroInitializable();891}892 893unsigned CodeGenTypes::getTargetAddressSpace(QualType T) const {894 // Return the address space for the type. If the type is a895 // function type without an address space qualifier, the896 // program address space is used. Otherwise, the target picks897 // the best address space based on the type information898 return T->isFunctionType() && !T.hasAddressSpace()899 ? getDataLayout().getProgramAddressSpace()900 : getContext().getTargetAddressSpace(T.getAddressSpace());901}902