llvm/clang/lib/CodeGen/CGVTables.cpp

//===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===//
//
// 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 contains code dealing with C++ code generation of virtual tables.
//
//===----------------------------------------------------------------------===//

#include "CGCXXABI.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/Support/Format.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include <algorithm>
#include <cstdio>
#include <utility>

usingnamespaceclang;
usingnamespaceCodeGen;

CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
    :{}

llvm::Constant *CodeGenModule::GetAddrOfThunk(StringRef Name, llvm::Type *FnTy,
                                              GlobalDecl GD) {}

static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
                               llvm::Function *ThunkFn, bool ForVTable,
                               GlobalDecl GD) {}

#ifndef NDEBUG
static bool similar(const ABIArgInfo &infoL, CanQualType typeL,
                    const ABIArgInfo &infoR, CanQualType typeR) {
  return (infoL.getKind() == infoR.getKind() &&
          (typeL == typeR ||
           (isa<PointerType>(typeL) && isa<PointerType>(typeR)) ||
           (isa<ReferenceType>(typeL) && isa<ReferenceType>(typeR))));
}
#endif

static RValue PerformReturnAdjustment(CodeGenFunction &CGF,
                                      QualType ResultType, RValue RV,
                                      const ThunkInfo &Thunk) {}

/// This function clones a function's DISubprogram node and enters it into
/// a value map with the intent that the map can be utilized by the cloner
/// to short-circuit Metadata node mapping.
/// Furthermore, the function resolves any DILocalVariable nodes referenced
/// by dbg.value intrinsics so they can be properly mapped during cloning.
static void resolveTopLevelMetadata(llvm::Function *Fn,
                                    llvm::ValueToValueMapTy &VMap) {}

// This function does roughly the same thing as GenerateThunk, but in a
// very different way, so that va_start and va_end work correctly.
// FIXME: This function assumes "this" is the first non-sret LLVM argument of
//        a function, and that there is an alloca built in the entry block
//        for all accesses to "this".
// FIXME: This function assumes there is only one "ret" statement per function.
// FIXME: Cloning isn't correct in the presence of indirect goto!
// FIXME: This implementation of thunks bloats codesize by duplicating the
//        function definition.  There are alternatives:
//        1. Add some sort of stub support to LLVM for cases where we can
//           do a this adjustment, then a sibcall.
//        2. We could transform the definition to take a va_list instead of an
//           actual variable argument list, then have the thunks (including a
//           no-op thunk for the regular definition) call va_start/va_end.
//           There's a bit of per-call overhead for this solution, but it's
//           better for codesize if the definition is long.
llvm::Function *
CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn,
                                      const CGFunctionInfo &FnInfo,
                                      GlobalDecl GD, const ThunkInfo &Thunk) {}

void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
                                 const CGFunctionInfo &FnInfo,
                                 bool IsUnprototyped) {}

void CodeGenFunction::FinishThunk() {}

void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
                                                const ThunkInfo *Thunk,
                                                bool IsUnprototyped) {}

void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
                                        llvm::Value *AdjustedThisPtr,
                                        llvm::FunctionCallee Callee) {}

void CodeGenFunction::generateThunk(llvm::Function *Fn,
                                    const CGFunctionInfo &FnInfo, GlobalDecl GD,
                                    const ThunkInfo &Thunk,
                                    bool IsUnprototyped) {}

static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD,
                                  bool IsUnprototyped, bool ForVTable) {}

llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
                                               const ThunkInfo &TI,
                                               bool ForVTable) {}

void CodeGenVTables::EmitThunks(GlobalDecl GD) {}

void CodeGenVTables::addRelativeComponent(ConstantArrayBuilder &builder,
                                          llvm::Constant *component,
                                          unsigned vtableAddressPoint,
                                          bool vtableHasLocalLinkage,
                                          bool isCompleteDtor) const {}

static bool UseRelativeLayout(const CodeGenModule &CGM) {}

bool CodeGenVTables::useRelativeLayout() const {}

llvm::Type *CodeGenModule::getVTableComponentType() const {}

llvm::Type *CodeGenVTables::getVTableComponentType() const {}

static void AddPointerLayoutOffset(const CodeGenModule &CGM,
                                   ConstantArrayBuilder &builder,
                                   CharUnits offset) {}

static void AddRelativeLayoutOffset(const CodeGenModule &CGM,
                                    ConstantArrayBuilder &builder,
                                    CharUnits offset) {}

void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
                                        const VTableLayout &layout,
                                        unsigned componentIndex,
                                        llvm::Constant *rtti,
                                        unsigned &nextVTableThunkIndex,
                                        unsigned vtableAddressPoint,
                                        bool vtableHasLocalLinkage) {}

llvm::Type *CodeGenVTables::getVTableType(const VTableLayout &layout) {}

void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder,
                                             const VTableLayout &layout,
                                             llvm::Constant *rtti,
                                             bool vtableHasLocalLinkage) {}

llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable(
    const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual,
    llvm::GlobalVariable::LinkageTypes Linkage,
    VTableAddressPointsMapTy &AddressPoints) {}

// Ensure this vtable is not instrumented by hwasan. That is, a global alias is
// not generated for it. This is mainly used by the relative-vtables ABI where
// vtables instead contain 32-bit offsets between the vtable and function
// pointers. Hwasan is disabled for these vtables for now because the tag in a
// vtable pointer may fail the overflow check when resolving 32-bit PLT
// relocations. A future alternative for this would be finding which usages of
// the vtable can continue to use the untagged hwasan value without any loss of
// value in hwasan.
void CodeGenVTables::RemoveHwasanMetadata(llvm::GlobalValue *GV) const {}

// If the VTable is not dso_local, then we will not be able to indicate that
// the VTable does not need a relocation and move into rodata. A frequent
// time this can occur is for classes that should be made public from a DSO
// (like in libc++). For cases like these, we can make the vtable hidden or
// internal and create a public alias with the same visibility and linkage as
// the original vtable type.
void CodeGenVTables::GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable,
                                                 llvm::StringRef AliasNameRef) {}

static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM,
                                                const CXXRecordDecl *RD) {}

/// Compute the required linkage of the vtable for the given class.
///
/// Note that we only call this at the end of the translation unit.
llvm::GlobalVariable::LinkageTypes
CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {}

/// This is a callback from Sema to tell us that a particular vtable is
/// required to be emitted in this translation unit.
///
/// This is only called for vtables that _must_ be emitted (mainly due to key
/// functions).  For weak vtables, CodeGen tracks when they are needed and
/// emits them as-needed.
void CodeGenModule::EmitVTable(CXXRecordDecl *theClass) {}

void
CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {}

/// At this point in the translation unit, does it appear that can we
/// rely on the vtable being defined elsewhere in the program?
///
/// The response is really only definitive when called at the end of
/// the translation unit.
///
/// The only semantic restriction here is that the object file should
/// not contain a vtable definition when that vtable is defined
/// strongly elsewhere.  Otherwise, we'd just like to avoid emitting
/// vtables when unnecessary.
bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {}

/// Given that we're currently at the end of the translation unit, and
/// we've emitted a reference to the vtable for this class, should
/// we define that vtable?
static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,
                                                   const CXXRecordDecl *RD) {}

/// Given that at some point we emitted a reference to one or more
/// vtables, and that we are now at the end of the translation unit,
/// decide whether we should emit them.
void CodeGenModule::EmitDeferredVTables() {}

bool CodeGenModule::AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD) {}

bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {}

llvm::GlobalObject::VCallVisibility CodeGenModule::GetVCallVisibilityLevel(
    const CXXRecordDecl *RD, llvm::DenseSet<const CXXRecordDecl *> &Visited) {}

void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
                                           llvm::GlobalVariable *VTable,
                                           const VTableLayout &VTLayout) {}