//===--- CGVtable.cpp - Emit LLVM Code for C++ vtables --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code dealing with C++ code generation of virtual tables.
//
//===----------------------------------------------------------------------===//
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
#include "clang/AST/RecordLayout.h"
#include "llvm/ADT/DenseSet.h"
#include <cstdio>
using namespace clang;
using namespace CodeGen;
class VtableBuilder {
public:
/// Index_t - Vtable index type.
typedef uint64_t Index_t;
private:
std::vector<llvm::Constant *> &methods;
std::vector<llvm::Constant *> submethods;
llvm::Type *Ptr8Ty;
/// Class - The most derived class that this vtable is being built for.
const CXXRecordDecl *Class;
/// LayoutClass - The most derived class used for virtual base layout
/// information.
const CXXRecordDecl *LayoutClass;
/// LayoutOffset - The offset for Class in LayoutClass.
uint64_t LayoutOffset;
/// BLayout - Layout for the most derived class that this vtable is being
/// built for.
const ASTRecordLayout &BLayout;
llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
llvm::Constant *rtti;
llvm::LLVMContext &VMContext;
CodeGenModule &CGM; // Per-module state.
/// Index - Maps a method decl into a vtable index. Useful for virtual
/// dispatch codegen.
llvm::DenseMap<GlobalDecl, Index_t> Index;
llvm::DenseMap<GlobalDecl, Index_t> VCall;
llvm::DenseMap<GlobalDecl, Index_t> VCallOffset;
// This is the offset to the nearest virtual base
llvm::DenseMap<GlobalDecl, Index_t> NonVirtualOffset;
llvm::DenseMap<const CXXRecordDecl *, Index_t> VBIndex;
/// PureVirtualFunction - Points to __cxa_pure_virtual.
llvm::Constant *PureVirtualFn;
/// Thunk - Represents a single thunk.
struct Thunk {
Thunk()
: Index(0) { }
Thunk(uint64_t Index, const ThunkAdjustment &Adjustment)
: Index(Index), Adjustment(Adjustment) { }
/// Index - The index in the vtable.
uint64_t Index;
/// Adjustment - The thunk adjustment.
ThunkAdjustment Adjustment;
};
/// Thunks - The thunks in a vtable.
typedef llvm::DenseMap<GlobalDecl, Thunk> ThunksMapTy;
ThunksMapTy Thunks;
/// CovariantThunk - Represents a single covariant thunk.
struct CovariantThunk {
CovariantThunk()
: Index(0) { }
CovariantThunk(uint64_t Index, const ThunkAdjustment &ThisAdjustment,
const ThunkAdjustment &ReturnAdjustment,
CanQualType ReturnType)
: Index(Index), Adjustment(ThisAdjustment, ReturnAdjustment),
ReturnType(ReturnType) { }
// Index - The index in the vtable.
uint64_t Index;
/// Adjustment - The covariant thunk adjustment.
CovariantThunkAdjustment Adjustment;
/// ReturnType - The return type of the function.
CanQualType ReturnType;
};
/// CovariantThunks - The covariant thunks in a vtable.
typedef llvm::DenseMap<GlobalDecl, CovariantThunk> CovariantThunksMapTy;
CovariantThunksMapTy CovariantThunks;
/// PureVirtualMethods - Pure virtual methods.
typedef llvm::DenseSet<GlobalDecl> PureVirtualMethodsSetTy;
PureVirtualMethodsSetTy PureVirtualMethods;
std::vector<Index_t> VCalls;
typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
// subAddressPoints - Used to hold the AddressPoints (offsets) into the built
// vtable for use in computing the initializers for the VTT.
llvm::DenseMap<CtorVtable_t, int64_t> &subAddressPoints;
typedef CXXRecordDecl::method_iterator method_iter;
const bool Extern;
const