llvm/clang/lib/CodeGen/MicrosoftCXXABI.cpp

//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This provides C++ code generation targeting the Microsoft Visual C++ ABI.
// The class in this file generates structures that follow the Microsoft
// Visual C++ ABI, which is actually not very well documented at all outside
// of Microsoft.
//
//===----------------------------------------------------------------------===//

#include "ABIInfo.h"
#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGVTables.h"
#include "CodeGenModule.h"
#include "CodeGenTypes.h"
#include "TargetInfo.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/VTableBuilder.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/Intrinsics.h"

usingnamespaceclang;
usingnamespaceCodeGen;

namespace {

/// Holds all the vbtable globals for a given class.
struct VBTableGlobals {};

class MicrosoftCXXABI : public CGCXXABI {};

}

CGCXXABI::RecordArgABI
MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {}

void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
                                              const CXXDeleteExpr *DE,
                                              Address Ptr,
                                              QualType ElementType,
                                              const CXXDestructorDecl *Dtor) {}

void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {}

void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
                                     const CXXCatchStmt *S) {}

/// We need to perform a generic polymorphic operation (like a typeid
/// or a cast), which requires an object with a vfptr.  Adjust the
/// address to point to an object with a vfptr.
std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
                                       QualType SrcRecordTy) {}

bool MicrosoftCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {}

static llvm::CallBase *emitRTtypeidCall(CodeGenFunction &CGF,
                                        llvm::Value *Argument) {}

void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {}

llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
                                         QualType SrcRecordTy,
                                         Address ThisPtr,
                                         llvm::Type *StdTypeInfoPtrTy) {}

bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
                                                         QualType SrcRecordTy) {}

llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
    CodeGenFunction &CGF, Address This, QualType SrcRecordTy, QualType DestTy,
    QualType DestRecordTy, llvm::BasicBlock *CastEnd) {}

llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
                                                    Address Value,
                                                    QualType SrcRecordTy) {}

bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {}

llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
    CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl,
    const CXXRecordDecl *BaseClassDecl) {}

bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const {}

static bool isDeletingDtor(GlobalDecl GD) {}

bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {}

static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
                             CodeGenModule &CGM) {}

bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const {}

llvm::BasicBlock *
MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
                                               const CXXRecordDecl *RD) {}

llvm::BasicBlock *
MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) {}

void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
    CodeGenFunction &CGF, const CXXRecordDecl *RD) {}

static bool hasDefaultCXXMethodCC(ASTContext &Context,
                                  const CXXMethodDecl *MD) {}

void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {}

void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
                                      const CXXRecordDecl *RD) {}

CGCXXABI::AddedStructorArgCounts
MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
                                        SmallVectorImpl<CanQualType> &ArgTys) {}

void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
                                                 const CXXDestructorDecl *Dtor,
                                                 CXXDtorType DT) const {}

llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
    GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {}

void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {}

CharUnits
MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {}

Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
    CodeGenFunction &CGF, GlobalDecl GD, Address This,
    bool VirtualCall) {}

void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
                                                QualType &ResTy,
                                                FunctionArgList &Params) {}

void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {}

CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
    CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
    bool ForVirtualBase, bool Delegating) {}

llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
    CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type,
    bool ForVirtualBase, bool Delegating) {}

void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
                                         const CXXDestructorDecl *DD,
                                         CXXDtorType Type, bool ForVirtualBase,
                                         bool Delegating, Address This,
                                         QualType ThisTy) {}

void MicrosoftCXXABI::emitVTableTypeMetadata(const VPtrInfo &Info,
                                             const CXXRecordDecl *RD,
                                             llvm::GlobalVariable *VTable) {}

void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
                                            const CXXRecordDecl *RD) {}

bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
    CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {}

llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
    CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
    const CXXRecordDecl *NearestVBase) {}

static void mangleVFTableName(MicrosoftMangleContext &MangleContext,
                              const CXXRecordDecl *RD, const VPtrInfo &VFPtr,
                              SmallString<256> &Name) {}

llvm::Constant *
MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,
                                       const CXXRecordDecl *VTableClass) {}

llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
                                                       CharUnits VPtrOffset) {}

CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
                                                    GlobalDecl GD,
                                                    Address This,
                                                    llvm::Type *Ty,
                                                    SourceLocation Loc) {}

llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
    CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
    Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {}

const VBTableGlobals &
MicrosoftCXXABI::enumerateVBTables(const CXXRecordDecl *RD) {}

llvm::Function *
MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
                                        const MethodVFTableLocation &ML) {}

void MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {}

llvm::GlobalVariable *
MicrosoftCXXABI::getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
                                  llvm::GlobalVariable::LinkageTypes Linkage) {}

void MicrosoftCXXABI::emitVBTableDefinition(const VPtrInfo &VBT,
                                            const CXXRecordDecl *RD,
                                            llvm::GlobalVariable *GV) const {}

llvm::Value *MicrosoftCXXABI::performThisAdjustment(
    CodeGenFunction &CGF, Address This,
    const CXXRecordDecl * /*UnadjustedClass*/, const ThunkInfo &TI) {}

llvm::Value *MicrosoftCXXABI::performReturnAdjustment(
    CodeGenFunction &CGF, Address Ret,
    const CXXRecordDecl * /*UnadjustedClass*/, const ReturnAdjustment &RA) {}

bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
                                   QualType elementType) {}

bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {}

CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {}

llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
                                                  Address allocPtr,
                                                  CharUnits cookieSize) {}

Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
                                               Address newPtr,
                                               llvm::Value *numElements,
                                               const CXXNewExpr *expr,
                                               QualType elementType) {}

static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD,
                                        llvm::FunctionCallee Dtor,
                                        llvm::Constant *Addr) {}

void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
                                         llvm::FunctionCallee Dtor,
                                         llvm::Constant *Addr) {}

void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
    CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
    ArrayRef<llvm::Function *> CXXThreadLocalInits,
    ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {}

static llvm::GlobalValue *getTlsGuardVar(CodeGenModule &CGM) {}

static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM) {}

static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard,
                              llvm::BasicBlock *DynInitBB,
                              llvm::BasicBlock *ContinueBB) {}

static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF,
                                             llvm::GlobalValue *TlsGuard,
                                             llvm::BasicBlock *ContinueBB) {}

static void emitDynamicTlsInitialization(CodeGenFunction &CGF) {}

LValue MicrosoftCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
                                                     const VarDecl *VD,
                                                     QualType LValType) {}

static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM) {}

static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM) {}

static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM) {}

static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM) {}

namespace {
struct ResetGuardBit final : EHScopeStack::Cleanup {};

struct CallInitThreadAbort final : EHScopeStack::Cleanup {};
}

void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
                                      llvm::GlobalVariable *GV,
                                      bool PerformInit) {}

bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {}

llvm::Type *
MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {}

void MicrosoftCXXABI::
GetNullMemberPointerFields(const MemberPointerType *MPT,
                           llvm::SmallVectorImpl<llvm::Constant *> &fields) {}

llvm::Constant *
MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {}

llvm::Constant *
MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
                                       bool IsMemberFunction,
                                       const CXXRecordDecl *RD,
                                       CharUnits NonVirtualBaseAdjustment,
                                       unsigned VBTableIndex) {}

llvm::Constant *
MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
                                       CharUnits offset) {}

llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(const CXXRecordDecl *RD,
                                                       CharUnits offset) {}

llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP,
                                                   QualType MPType) {}

llvm::Constant *
MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {}

/// Member pointers are the same if they're either bitwise identical *or* both
/// null.  Null-ness for function members is determined by the first field,
/// while for data member pointers we must compare all fields.
llvm::Value *
MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
                                             llvm::Value *L,
                                             llvm::Value *R,
                                             const MemberPointerType *MPT,
                                             bool Inequality) {}

llvm::Value *
MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
                                            llvm::Value *MemPtr,
                                            const MemberPointerType *MPT) {}

bool MicrosoftCXXABI::MemberPointerConstantIsNull(const MemberPointerType *MPT,
                                                  llvm::Constant *Val) {}

llvm::Value *
MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
                                         Address This,
                                         llvm::Value *VBPtrOffset,
                                         llvm::Value *VBTableOffset,
                                         llvm::Value **VBPtrOut) {}

// Returns an adjusted base cast to i8*, since we do more address arithmetic on
// it.
llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
    CodeGenFunction &CGF, const Expr *E, const CXXRecordDecl *RD,
    Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {}

llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
    CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr,
    const MemberPointerType *MPT) {}

llvm::Value *
MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
                                             const CastExpr *E,
                                             llvm::Value *Src) {}

llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
    const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK,
    CastExpr::path_const_iterator PathBegin,
    CastExpr::path_const_iterator PathEnd, llvm::Value *Src,
    CGBuilderTy &Builder) {}

llvm::Constant *
MicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E,
                                             llvm::Constant *Src) {}

llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
    const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK,
    CastExpr::path_const_iterator PathBegin,
    CastExpr::path_const_iterator PathEnd, llvm::Constant *Src) {}

CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
    CodeGenFunction &CGF, const Expr *E, Address This,
    llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
    const MemberPointerType *MPT) {}

CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {}

// MS RTTI Overview:
// The run time type information emitted by cl.exe contains 5 distinct types of
// structures.  Many of them reference each other.
//
// TypeInfo:  Static classes that are returned by typeid.
//
// CompleteObjectLocator:  Referenced by vftables.  They contain information
//   required for dynamic casting, including OffsetFromTop.  They also contain
//   a reference to the TypeInfo for the type and a reference to the
//   CompleteHierarchyDescriptor for the type.
//
// ClassHierarchyDescriptor: Contains information about a class hierarchy.
//   Used during dynamic_cast to walk a class hierarchy.  References a base
//   class array and the size of said array.
//
// BaseClassArray: Contains a list of classes in a hierarchy.  BaseClassArray is
//   somewhat of a misnomer because the most derived class is also in the list
//   as well as multiple copies of virtual bases (if they occur multiple times
//   in the hierarchy.)  The BaseClassArray contains one BaseClassDescriptor for
//   every path in the hierarchy, in pre-order depth first order.  Note, we do
//   not declare a specific llvm type for BaseClassArray, it's merely an array
//   of BaseClassDescriptor pointers.
//
// BaseClassDescriptor: Contains information about a class in a class hierarchy.
//   BaseClassDescriptor is also somewhat of a misnomer for the same reason that
//   BaseClassArray is.  It contains information about a class within a
//   hierarchy such as: is this base is ambiguous and what is its offset in the
//   vbtable.  The names of the BaseClassDescriptors have all of their fields
//   mangled into them so they can be aggressively deduplicated by the linker.

static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {}

namespace {

/// A Helper struct that stores information about a class in a class
/// hierarchy.  The information stored in these structs struct is used during
/// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
// During RTTI creation, MSRTTIClasses are stored in a contiguous array with
// implicit depth first pre-order tree connectivity.  getFirstChild and
// getNextSibling allow us to walk the tree efficiently.
struct MSRTTIClass {};

/// Recursively initialize the base class array.
uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
                                 const CXXBaseSpecifier *Specifier) {}

static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {}

/// An ephemeral helper class for building MS RTTI types.  It caches some
/// calls to the module and information about the most derived class in a
/// hierarchy.
struct MSRTTIBuilder {};

} // namespace

/// Recursively serializes a class hierarchy in pre-order depth first
/// order.
static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
                                    const CXXRecordDecl *RD) {}

/// Find ambiguity among base classes.
static void
detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {}

llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {}

llvm::GlobalVariable *
MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {}

llvm::GlobalVariable *
MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {}

llvm::GlobalVariable *
MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo &Info) {}

static QualType decomposeTypeForEH(ASTContext &Context, QualType T,
                                   bool &IsConst, bool &IsVolatile,
                                   bool &IsUnaligned) {}

CatchTypeInfo
MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type,
                                              QualType CatchHandlerType) {}

/// Gets a TypeDescriptor.  Returns a llvm::Constant * rather than a
/// llvm::GlobalVariable * because different type descriptors have different
/// types, and need to be abstracted.  They are abstracting by casting the
/// address to an Int8PtrTy.
llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) {}

/// Gets or a creates a Microsoft CompleteObjectLocator.
llvm::GlobalVariable *
MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
                                            const VPtrInfo &Info) {}

void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {}

llvm::Function *
MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
                                         CXXCtorType CT) {}

llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T,
                                                  uint32_t NVOffset,
                                                  int32_t VBPtrOffset,
                                                  uint32_t VBIndex) {}

llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) {}

llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) {}

void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {}

std::pair<llvm::Value *, const CXXRecordDecl *>
MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
                               const CXXRecordDecl *RD) {}

bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
    const CXXRecordDecl *RD) const {}