//===--- 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 <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;
typedef llvm::DenseMap<GlobalDecl, int> Pures_t;
Pures_t Pures;
typedef std::pair<Index_t, Index_t> CallOffset;
typedef llvm::DenseMap<GlobalDecl, CallOffset> Thunks_t;
Thunks_t Thunks;
typedef llvm::DenseMap<GlobalDecl,
std::pair<std::pair<CallOffset, CallOffset>,
CanQualType> > CovariantThunks_t;
CovariantThunks_t CovariantThunks;
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 uint32_t LLVMPointerWidth;
Index_t extra;
typedef std::vector<std::pair<const CXXRecordDecl *, int64_t> > Path_t;
llvm::Constant *cxa_pure;
static llvm::DenseMap<CtorVtable_t, int64_t>&
AllocAddressPoint(CodeGenModule &cgm, const CXXRecordDecl *l,
const CXXRecordDecl *c) {
CodeGenModule::AddrMap_t *&oref = cgm.AddressPoints[l];
if (oref == 0)
oref = new CodeGenModule::AddrMap_t;
llvm::DenseMap<CtorVtable_t, int64_t> *&ref = (*oref)[c];
if (ref == 0)
ref = new llvm::DenseMap<CtorVtable_t, int64_t>;
return *ref;
}
public:
VtableBuilder(std::vector<llvm::Constant *> &meth, const CXXRecordDecl *c,
const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm)
: methods(meth), Class(c), LayoutClass(l), LayoutOffset(lo),
BLayout(cgm.getContext().getASTRecordLayout(l)),<