#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGRecordLayout.h"
#include "CGVTables.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
#include "TargetInfo.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/Type.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/ScopedPrinter.h"
#include <optional>
usingnamespaceclang;
usingnamespaceCodeGen;
namespace {
class ItaniumCXXABI : public CodeGen::CGCXXABI { … };
class ARMCXXABI : public ItaniumCXXABI { … };
class AppleARM64CXXABI : public ARMCXXABI { … };
class FuchsiaCXXABI final : public ItaniumCXXABI { … };
class WebAssemblyCXXABI final : public ItaniumCXXABI { … };
class XLCXXABI final : public ItaniumCXXABI { … };
}
CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) { … }
llvm::Type *
ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { … }
CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
CodeGenFunction &CGF, const Expr *E, Address ThisAddr,
llvm::Value *&ThisPtrForCall,
llvm::Value *MemFnPtr, const MemberPointerType *MPT) { … }
llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr,
const MemberPointerType *MPT) { … }
static llvm::Constant *pointerAuthResignConstant(
llvm::Value *Ptr, const CGPointerAuthInfo &CurAuthInfo,
const CGPointerAuthInfo &NewAuthInfo, CodeGenModule &CGM) { … }
llvm::Value *
ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
const CastExpr *E,
llvm::Value *src) { … }
static llvm::Constant *
pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType,
QualType SrcType, CodeGenModule &CGM) { … }
llvm::Constant *
ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
llvm::Constant *src) { … }
llvm::Constant *
ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { … }
llvm::Constant *
ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
CharUnits offset) { … }
llvm::Constant *
ItaniumCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { … }
llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,
CharUnits ThisAdjustment) { … }
llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,
QualType MPType) { … }
llvm::Value *
ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
llvm::Value *L,
llvm::Value *R,
const MemberPointerType *MPT,
bool Inequality) { … }
llvm::Value *
ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
llvm::Value *MemPtr,
const MemberPointerType *MPT) { … }
bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const { … }
bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) { … }
void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
const CXXDeleteExpr *DE,
Address Ptr,
QualType ElementType,
const CXXDestructorDecl *Dtor) { … }
void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) { … }
static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM) { … }
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM) { … }
void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { … }
static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) { … }
static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF) { … }
static CharUnits computeOffsetHint(ASTContext &Context,
const CXXRecordDecl *Src,
const CXXRecordDecl *Dst) { … }
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF) { … }
bool ItaniumCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) { … }
void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) { … }
llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
QualType SrcRecordTy,
Address ThisPtr,
llvm::Type *StdTypeInfoPtrTy) { … }
bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
QualType SrcRecordTy) { … }
llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) { … }
llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastSuccess,
llvm::BasicBlock *CastFail) { … }
llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
Address ThisAddr,
QualType SrcRecordTy) { … }
bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) { … }
llvm::Value *
ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
Address This,
const CXXRecordDecl *ClassDecl,
const CXXRecordDecl *BaseClassDecl) { … }
void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { … }
CGCXXABI::AddedStructorArgCounts
ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) { … }
void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { … }
void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
QualType &ResTy,
FunctionArgList &Params) { … }
void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { … }
CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
bool ForVirtualBase, bool Delegating) { … }
llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type,
bool ForVirtualBase, bool Delegating) { … }
void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
CXXDtorType Type, bool ForVirtualBase,
bool Delegating, Address This,
QualType ThisTy) { … }
template <typename T>
static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD) { … }
static void setVTableSelectiveDLLImportExport(CodeGenModule &CGM,
llvm::GlobalVariable *VTable,
const CXXRecordDecl *RD) { … }
void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
const CXXRecordDecl *RD) { … }
bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) { … }
llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
const CXXRecordDecl *NearestVBase) { … }
llvm::Constant *
ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
const CXXRecordDecl *VTableClass) { … }
llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
const CXXRecordDecl *NearestVBase) { … }
llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
CharUnits VPtrOffset) { … }
CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
GlobalDecl GD,
Address This,
llvm::Type *Ty,
SourceLocation Loc) { … }
llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) { … }
void ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) { … }
bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD) const { … }
bool ItaniumCXXABI::canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const { … }
static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,
Address InitialPtr,
const CXXRecordDecl *UnadjustedClass,
int64_t NonVirtualAdjustment,
int64_t VirtualAdjustment,
bool IsReturnAdjustment) { … }
llvm::Value *
ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This,
const CXXRecordDecl *UnadjustedClass,
const ThunkInfo &TI) { … }
llvm::Value *
ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
const CXXRecordDecl *UnadjustedClass,
const ReturnAdjustment &RA) { … }
void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
RValue RV, QualType ResultType) { … }
CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) { … }
Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
Address NewPtr,
llvm::Value *NumElements,
const CXXNewExpr *expr,
QualType ElementType) { … }
llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
Address allocPtr,
CharUnits cookieSize) { … }
CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) { … }
Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
Address newPtr,
llvm::Value *numElements,
const CXXNewExpr *expr,
QualType elementType) { … }
llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
Address allocPtr,
CharUnits cookieSize) { … }
static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM,
llvm::PointerType *GuardPtrTy) { … }
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM,
llvm::PointerType *GuardPtrTy) { … }
static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM,
llvm::PointerType *GuardPtrTy) { … }
namespace {
struct CallGuardAbort final : EHScopeStack::Cleanup { … };
}
void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
llvm::GlobalVariable *var,
bool shouldPerformInit) { … }
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
llvm::FunctionCallee dtor,
llvm::Constant *addr, bool TLS) { … }
static llvm::Function *createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM,
StringRef FnName) { … }
void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() { … }
void CodeGenModule::registerGlobalDtorsWithAtExit() { … }
void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
llvm::FunctionCallee dtor,
llvm::Constant *addr) { … }
static bool isThreadWrapperReplaceable(const VarDecl *VD,
CodeGen::CodeGenModule &CGM) { … }
static llvm::GlobalValue::LinkageTypes
getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) { … }
llvm::Function *
ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,
llvm::Value *Val) { … }
void ItaniumCXXABI::EmitThreadLocalInitFuncs(
CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
ArrayRef<llvm::Function *> CXXThreadLocalInits,
ArrayRef<const VarDecl *> CXXThreadLocalInitVars) { … }
LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
const VarDecl *VD,
QualType LValType) { … }
bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) { … }
llvm::Constant *
ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(const CXXMethodDecl *MD) { … }
namespace {
class ItaniumRTTIBuilder { … };
}
llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) { … }
llvm::Constant *
ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) { … }
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { … }
static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) { … }
static bool IsStandardLibraryRTTIDescriptor(QualType Ty) { … }
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
QualType Ty) { … }
static bool IsIncompleteClassType(const RecordType *RecordTy) { … }
static bool ContainsIncompleteClassType(QualType Ty) { … }
static bool CanUseSingleInheritance(const CXXRecordDecl *RD) { … }
void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) { … }
static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
QualType Ty) { … }
llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) { … }
llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty,
llvm::GlobalVariable::LinkageTypes Linkage,
llvm::GlobalValue::VisibilityTypes Visibility,
llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) { … }
void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) { … }
void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) { … }
namespace {
struct SeenBases { … };
}
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base,
SeenBases &Bases) { … }
static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) { … }
void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { … }
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type) { … }
void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) { … }
void
ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) { … }
llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) { … }
void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD) { … }
ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const { … }
namespace {
enum class StructorCodegen { … };
}
static StructorCodegen getCodegenToUse(CodeGenModule &CGM,
const CXXMethodDecl *MD) { … }
static void emitConstructorDestructorAlias(CodeGenModule &CGM,
GlobalDecl AliasDecl,
GlobalDecl TargetDecl) { … }
void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) { … }
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM) { … }
static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) { … }
static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) { … }
namespace {
struct CallEndCatch final : EHScopeStack::Cleanup { … };
}
static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,
llvm::Value *Exn,
bool EndMightThrow) { … }
static void InitCatchParam(CodeGenFunction &CGF,
const VarDecl &CatchParam,
Address ParamAddr,
SourceLocation Loc) { … }
void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *S) { … }
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM) { … }
llvm::CallInst *
ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
llvm::Value *Exn) { … }
std::pair<llvm::Value *, const CXXRecordDecl *>
ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
const CXXRecordDecl *RD) { … }
llvm::Constant *
ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD) { … }
void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *C) { … }
llvm::CallInst *
WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
llvm::Value *Exn) { … }
void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
llvm::FunctionCallee Dtor,
llvm::Constant *Addr) { … }
void XLCXXABI::emitCXXStermFinalizer(const VarDecl &D, llvm::Function *dtorStub,
llvm::Constant *addr) { … }