328 lines · c
1//===--- CodeGenTypes.h - Type translation for LLVM CodeGen -----*- C++ -*-===//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#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H14#define LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H15 16#include "CGCall.h"17#include "clang/Basic/ABI.h"18#include "clang/CodeGen/CGFunctionInfo.h"19#include "llvm/ADT/DenseMap.h"20#include "llvm/IR/Module.h"21 22namespace llvm {23class FunctionType;24class DataLayout;25class Type;26class LLVMContext;27class StructType;28}29 30namespace clang {31class ASTContext;32template <typename> class CanQual;33class CXXConstructorDecl;34class CXXMethodDecl;35class CodeGenOptions;36class FunctionProtoType;37class QualType;38class RecordDecl;39class TagDecl;40class TargetInfo;41class Type;42typedef CanQual<Type> CanQualType;43class GlobalDecl;44 45namespace CodeGen {46class ABIInfo;47class CGCXXABI;48class CGRecordLayout;49class CodeGenModule;50class RequiredArgs;51 52/// This class organizes the cross-module state that is used while lowering53/// AST types to LLVM types.54class CodeGenTypes {55 CodeGenModule &CGM;56 // Some of this stuff should probably be left on the CGM.57 ASTContext &Context;58 llvm::Module &TheModule;59 const TargetInfo &Target;60 61 /// The opaque type map for Objective-C interfaces. All direct62 /// manipulation is done by the runtime interfaces, which are63 /// responsible for coercing to the appropriate type; these opaque64 /// types are never refined.65 llvm::DenseMap<const ObjCInterfaceType*, llvm::Type *> InterfaceTypes;66 67 /// Maps clang struct type with corresponding record layout info.68 llvm::DenseMap<const Type*, std::unique_ptr<CGRecordLayout>> CGRecordLayouts;69 70 /// Contains the LLVM IR type for any converted RecordDecl.71 llvm::DenseMap<const Type*, llvm::StructType *> RecordDeclTypes;72 73 /// Hold memoized CGFunctionInfo results.74 llvm::FoldingSet<CGFunctionInfo> FunctionInfos{FunctionInfosLog2InitSize};75 76 llvm::SmallPtrSet<const CGFunctionInfo*, 4> FunctionsBeingProcessed;77 78 /// True if we didn't layout a function due to a being inside79 /// a recursive struct conversion, set this to true.80 bool SkippedLayout;81 82 /// True if any instance of long double types are used.83 bool LongDoubleReferenced;84 85 /// This map keeps cache of llvm::Types and maps clang::Type to86 /// corresponding llvm::Type.87 llvm::DenseMap<const Type *, llvm::Type *> TypeCache;88 89 llvm::DenseMap<const Type *, llvm::Type *> RecordsWithOpaqueMemberPointers;90 91 static constexpr unsigned FunctionInfosLog2InitSize = 9;92 /// Helper for ConvertType.93 llvm::Type *ConvertFunctionTypeInternal(QualType FT);94 95public:96 CodeGenTypes(CodeGenModule &cgm);97 ~CodeGenTypes();98 99 const llvm::DataLayout &getDataLayout() const {100 return TheModule.getDataLayout();101 }102 CodeGenModule &getCGM() const { return CGM; }103 ASTContext &getContext() const { return Context; }104 const TargetInfo &getTarget() const { return Target; }105 CGCXXABI &getCXXABI() const;106 llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }107 const CodeGenOptions &getCodeGenOpts() const;108 109 /// Convert clang calling convention to LLVM callilng convention.110 unsigned ClangCallConvToLLVMCallConv(CallingConv CC);111 112 /// Derives the 'this' type for codegen purposes, i.e. ignoring method CVR113 /// qualification.114 CanQualType DeriveThisType(const CXXRecordDecl *RD, const CXXMethodDecl *MD);115 116 /// ConvertType - Convert type T into a llvm::Type.117 llvm::Type *ConvertType(QualType T);118 119 /// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from120 /// ConvertType in that it is used to convert to the memory representation for121 /// a type. For example, the scalar representation for _Bool is i1, but the122 /// memory representation is usually i8 or i32, depending on the target.123 llvm::Type *ConvertTypeForMem(QualType T);124 125 /// Check whether the given type needs to be laid out in memory126 /// using an opaque byte-array type because its load/store type127 /// does not have the correct alloc size in the LLVM data layout.128 /// If this is false, the load/store type (convertTypeForLoadStore)129 /// and memory representation type (ConvertTypeForMem) will130 /// be the same type.131 bool typeRequiresSplitIntoByteArray(QualType ASTTy,132 llvm::Type *LLVMTy = nullptr);133 134 /// Given that T is a scalar type, return the IR type that should135 /// be used for load and store operations. For example, this might136 /// be i8 for _Bool or i96 for _BitInt(65). The store size of the137 /// load/store type (as reported by LLVM's data layout) is always138 /// the same as the alloc size of the memory representation type139 /// returned by ConvertTypeForMem.140 ///141 /// As an optimization, if you already know the scalar value type142 /// for T (as would be returned by ConvertType), you can pass143 /// it as the second argument so that it does not need to be144 /// recomputed in common cases where the value type and145 /// load/store type are the same.146 llvm::Type *convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy = nullptr);147 148 /// GetFunctionType - Get the LLVM function type for \arg Info.149 llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info);150 151 llvm::FunctionType *GetFunctionType(GlobalDecl GD);152 153 /// isFuncTypeConvertible - Utility to check whether a function type can154 /// be converted to an LLVM type (i.e. doesn't depend on an incomplete tag155 /// type).156 bool isFuncTypeConvertible(const FunctionType *FT);157 bool isFuncParamTypeConvertible(QualType Ty);158 159 /// Determine if a C++ inheriting constructor should have parameters matching160 /// those of its inherited constructor.161 bool inheritingCtorHasParams(const InheritedConstructor &Inherited,162 CXXCtorType Type);163 164 /// GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable,165 /// given a CXXMethodDecl. If the method to has an incomplete return type,166 /// and/or incomplete argument types, this will return the opaque type.167 llvm::Type *GetFunctionTypeForVTable(GlobalDecl GD);168 169 const CGRecordLayout &getCGRecordLayout(const RecordDecl*);170 171 /// UpdateCompletedType - When we find the full definition for a TagDecl,172 /// replace the 'opaque' type we previously made for it if applicable.173 void UpdateCompletedType(const TagDecl *TD);174 175 /// Remove stale types from the type cache when an inheritance model176 /// gets assigned to a class.177 void RefreshTypeCacheForClass(const CXXRecordDecl *RD);178 179 // The arrangement methods are split into three families:180 // - those meant to drive the signature and prologue/epilogue181 // of a function declaration or definition,182 // - those meant for the computation of the LLVM type for an abstract183 // appearance of a function, and184 // - those meant for performing the IR-generation of a call.185 // They differ mainly in how they deal with optional (i.e. variadic)186 // arguments, as well as unprototyped functions.187 //188 // Key points:189 // - The CGFunctionInfo for emitting a specific call site must include190 // entries for the optional arguments.191 // - The function type used at the call site must reflect the formal192 // signature of the declaration being called, or else the call will193 // go awry.194 // - For the most part, unprototyped functions are called by casting to195 // a formal signature inferred from the specific argument types used196 // at the call-site. However, some targets (e.g. x86-64) screw with197 // this for compatibility reasons.198 199 const CGFunctionInfo &arrangeGlobalDeclaration(GlobalDecl GD);200 201 /// Given a function info for a declaration, return the function info202 /// for a call with the given arguments.203 ///204 /// Often this will be able to simply return the declaration info.205 const CGFunctionInfo &arrangeCall(const CGFunctionInfo &declFI,206 const CallArgList &args);207 208 /// Free functions are functions that are compatible with an ordinary209 /// C function pointer type.210 const CGFunctionInfo &arrangeFunctionDeclaration(const GlobalDecl GD);211 const CGFunctionInfo &arrangeFreeFunctionCall(const CallArgList &Args,212 const FunctionType *Ty,213 bool ChainCall);214 const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty);215 const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionNoProtoType> Ty);216 217 /// A nullary function is a freestanding function of type 'void ()'.218 /// This method works for both calls and declarations.219 const CGFunctionInfo &arrangeNullaryFunction();220 221 /// A builtin function is a freestanding function using the default222 /// C conventions.223 const CGFunctionInfo &224 arrangeBuiltinFunctionDeclaration(QualType resultType,225 const FunctionArgList &args);226 const CGFunctionInfo &227 arrangeBuiltinFunctionDeclaration(CanQualType resultType,228 ArrayRef<CanQualType> argTypes);229 const CGFunctionInfo &arrangeBuiltinFunctionCall(QualType resultType,230 const CallArgList &args);231 232 /// A device kernel caller function is an offload device entry point function233 /// with a target device dependent calling convention such as amdgpu_kernel,234 /// ptx_kernel, or spir_kernel.235 const CGFunctionInfo &236 arrangeDeviceKernelCallerDeclaration(QualType resultType,237 const FunctionArgList &args);238 239 /// Objective-C methods are C functions with some implicit parameters.240 const CGFunctionInfo &arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD);241 const CGFunctionInfo &arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,242 QualType receiverType);243 const CGFunctionInfo &arrangeUnprototypedObjCMessageSend(244 QualType returnType,245 const CallArgList &args);246 247 /// Block invocation functions are C functions with an implicit parameter.248 const CGFunctionInfo &arrangeBlockFunctionDeclaration(249 const FunctionProtoType *type,250 const FunctionArgList &args);251 const CGFunctionInfo &arrangeBlockFunctionCall(const CallArgList &args,252 const FunctionType *type);253 254 /// C++ methods have some special rules and also have implicit parameters.255 const CGFunctionInfo &arrangeCXXMethodDeclaration(const CXXMethodDecl *MD);256 const CGFunctionInfo &arrangeCXXStructorDeclaration(GlobalDecl GD);257 const CGFunctionInfo &arrangeCXXConstructorCall(const CallArgList &Args,258 const CXXConstructorDecl *D,259 CXXCtorType CtorKind,260 unsigned ExtraPrefixArgs,261 unsigned ExtraSuffixArgs,262 bool PassProtoArgs = true);263 264 const CGFunctionInfo &arrangeCXXMethodCall(const CallArgList &args,265 const FunctionProtoType *type,266 RequiredArgs required,267 unsigned numPrefixArgs);268 const CGFunctionInfo &269 arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD);270 const CGFunctionInfo &arrangeMSCtorClosure(const CXXConstructorDecl *CD,271 CXXCtorType CT);272 const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,273 const FunctionProtoType *FTP,274 const CXXMethodDecl *MD);275 276 /// "Arrange" the LLVM information for a call or type with the given277 /// signature. This is largely an internal method; other clients278 /// should use one of the above routines, which ultimately defer to279 /// this.280 ///281 /// \param argTypes - must all actually be canonical as params282 const CGFunctionInfo &arrangeLLVMFunctionInfo(283 CanQualType returnType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,284 FunctionType::ExtInfo info,285 ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,286 RequiredArgs args);287 288 /// Compute a new LLVM record layout object for the given record.289 std::unique_ptr<CGRecordLayout> ComputeRecordLayout(const RecordDecl *D,290 llvm::StructType *Ty);291 292 /// addRecordTypeName - Compute a name from the given record decl with an293 /// optional suffix and name the given LLVM type using it.294 void addRecordTypeName(const RecordDecl *RD, llvm::StructType *Ty,295 StringRef suffix);296 297 298public: // These are internal details of CGT that shouldn't be used externally.299 /// ConvertRecordDeclType - Lay out a tagged decl type like struct or union.300 llvm::StructType *ConvertRecordDeclType(const RecordDecl *TD);301 302 /// getExpandedTypes - Expand the type \arg Ty into the LLVM303 /// argument types it would be passed as. See ABIArgInfo::Expand.304 void getExpandedTypes(QualType Ty,305 SmallVectorImpl<llvm::Type *>::iterator &TI);306 307 /// IsZeroInitializable - Return whether a type can be308 /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer.309 bool isZeroInitializable(QualType T);310 311 /// Check if the pointer type can be zero-initialized (in the C++ sense)312 /// with an LLVM zeroinitializer.313 bool isPointerZeroInitializable(QualType T);314 315 /// IsZeroInitializable - Return whether a record type can be316 /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer.317 bool isZeroInitializable(const RecordDecl *RD);318 319 bool isLongDoubleReferenced() const { return LongDoubleReferenced; }320 bool isRecordLayoutComplete(const Type *Ty) const;321 unsigned getTargetAddressSpace(QualType T) const;322};323 324} // end namespace CodeGen325} // end namespace clang326 327#endif328