//===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This provides C++ code generation targetting the Itanium C++ ABI. The class
// in this file generates structures that follow the Itanium C++ ABI, which is
// documented at:
// http://www.codesourcery.com/public/cxx-abi/abi.html
// http://www.codesourcery.com/public/cxx-abi/abi-eh.html
//
// It also supports the closely-related ARM ABI, documented at:
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
//
//===----------------------------------------------------------------------===//
#include "CGCXXABI.h"
#include "CGRecordLayout.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "Mangle.h"
#include <clang/AST/Type.h>
#include <llvm/Target/TargetData.h>
#include <llvm/Value.h>
using namespace clang;
using namespace CodeGen;
namespace {
class ItaniumCXXABI : public CodeGen::CGCXXABI {
private:
const llvm::IntegerType *PtrDiffTy;
protected:
CodeGen::MangleContext MangleCtx;
bool IsARM;
// It's a little silly for us to cache this.
const llvm::IntegerType *getPtrDiffTy() {
if (!PtrDiffTy) {
QualType T = getContext().getPointerDiffType();
const llvm::Type *Ty = CGM.getTypes().ConvertTypeRecursive(T);
PtrDiffTy = cast<llvm::IntegerType>(Ty);
}
return PtrDiffTy;
}
bool NeedsArrayCookie(QualType ElementType);
public:
ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
CGCXXABI(CGM), PtrDiffTy(0), MangleCtx(getContext(), CGM.getDiags()),
IsARM(IsARM) { }
CodeGen::MangleContext &getMangleContext() {
return MangleCtx;
}
bool isZeroInitializable(const MemberPointerType *MPT);
const llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
llvm::Value *&This,
llvm::Value *MemFnPtr,
const MemberPointerType *MPT);
llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
llvm::Value *Base,
llvm::Value *MemPtr,
const MemberPointerType *MPT);
llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
const CastExpr *E,
llvm::Value *Src);
llvm::Constant *EmitMemberPointerConversion(llvm::Constant *C,
const CastExpr *E);
llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
llvm::Constant *EmitMemberPointer(const FieldDecl *FD);
llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
llvm::Value *L,
llvm::Value *R,
const MemberPointerType *MPT,
bool Inequality);
llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
llvm::Value *Addr,
const MemberPointerType *MPT);
void BuildConstructorSignature(const CXXConstructorDecl *Ctor,