mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-17 13:51:21 +00:00

constructor, and that constructor is used to initialize an object of static storage duration such that all members and bases are initialized by constant expressions, constant initialization is performed. In this case, the object can still have a non-trivial destructor, and if it does, we must emit a dynamic initializer which performs no initialization and instead simply registers that destructor. llvm-svn: 150419
175 lines
6.8 KiB
C++
175 lines
6.8 KiB
C++
//===----- CGCXXABI.cpp - Interface to C++ ABIs -----------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This provides an abstract class for C++ code generation. Concrete subclasses
|
|
// of this implement code generation for specific C++ ABIs.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CGCXXABI.h"
|
|
|
|
using namespace clang;
|
|
using namespace CodeGen;
|
|
|
|
CGCXXABI::~CGCXXABI() { }
|
|
|
|
static void ErrorUnsupportedABI(CodeGenFunction &CGF,
|
|
StringRef S) {
|
|
DiagnosticsEngine &Diags = CGF.CGM.getDiags();
|
|
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
|
|
"cannot yet compile %1 in this ABI");
|
|
Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
|
|
DiagID)
|
|
<< S;
|
|
}
|
|
|
|
static llvm::Constant *GetBogusMemberPointer(CodeGenModule &CGM,
|
|
QualType T) {
|
|
return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
|
|
}
|
|
|
|
llvm::Type *
|
|
CGCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
|
|
return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
|
|
}
|
|
|
|
llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
|
|
llvm::Value *&This,
|
|
llvm::Value *MemPtr,
|
|
const MemberPointerType *MPT) {
|
|
ErrorUnsupportedABI(CGF, "calls through member pointers");
|
|
|
|
const FunctionProtoType *FPT =
|
|
MPT->getPointeeType()->getAs<FunctionProtoType>();
|
|
const CXXRecordDecl *RD =
|
|
cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
|
|
llvm::FunctionType *FTy =
|
|
CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
|
|
FPT->isVariadic());
|
|
return llvm::Constant::getNullValue(FTy->getPointerTo());
|
|
}
|
|
|
|
llvm::Value *CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
|
|
llvm::Value *Base,
|
|
llvm::Value *MemPtr,
|
|
const MemberPointerType *MPT) {
|
|
ErrorUnsupportedABI(CGF, "loads of member pointers");
|
|
llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType())->getPointerTo();
|
|
return llvm::Constant::getNullValue(Ty);
|
|
}
|
|
|
|
llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
|
|
const CastExpr *E,
|
|
llvm::Value *Src) {
|
|
ErrorUnsupportedABI(CGF, "member function pointer conversions");
|
|
return GetBogusMemberPointer(CGM, E->getType());
|
|
}
|
|
|
|
llvm::Value *
|
|
CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
|
|
llvm::Value *L,
|
|
llvm::Value *R,
|
|
const MemberPointerType *MPT,
|
|
bool Inequality) {
|
|
ErrorUnsupportedABI(CGF, "member function pointer comparison");
|
|
return CGF.Builder.getFalse();
|
|
}
|
|
|
|
llvm::Value *
|
|
CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
|
|
llvm::Value *MemPtr,
|
|
const MemberPointerType *MPT) {
|
|
ErrorUnsupportedABI(CGF, "member function pointer null testing");
|
|
return CGF.Builder.getFalse();
|
|
}
|
|
|
|
llvm::Constant *
|
|
CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
|
|
return GetBogusMemberPointer(CGM, QualType(MPT, 0));
|
|
}
|
|
|
|
llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
|
|
return GetBogusMemberPointer(CGM,
|
|
CGM.getContext().getMemberPointerType(MD->getType(),
|
|
MD->getParent()->getTypeForDecl()));
|
|
}
|
|
|
|
llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
|
|
CharUnits offset) {
|
|
return GetBogusMemberPointer(CGM, QualType(MPT, 0));
|
|
}
|
|
|
|
llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) {
|
|
return GetBogusMemberPointer(CGM, MPT);
|
|
}
|
|
|
|
bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
|
|
// Fake answer.
|
|
return true;
|
|
}
|
|
|
|
void CGCXXABI::BuildThisParam(CodeGenFunction &CGF, FunctionArgList ¶ms) {
|
|
const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
|
|
|
|
// FIXME: I'm not entirely sure I like using a fake decl just for code
|
|
// generation. Maybe we can come up with a better way?
|
|
ImplicitParamDecl *ThisDecl
|
|
= ImplicitParamDecl::Create(CGM.getContext(), 0, MD->getLocation(),
|
|
&CGM.getContext().Idents.get("this"),
|
|
MD->getThisType(CGM.getContext()));
|
|
params.push_back(ThisDecl);
|
|
getThisDecl(CGF) = ThisDecl;
|
|
}
|
|
|
|
void CGCXXABI::EmitThisParam(CodeGenFunction &CGF) {
|
|
/// Initialize the 'this' slot.
|
|
assert(getThisDecl(CGF) && "no 'this' variable for function");
|
|
getThisValue(CGF)
|
|
= CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)),
|
|
"this");
|
|
}
|
|
|
|
void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
|
|
RValue RV, QualType ResultType) {
|
|
CGF.EmitReturnOfRValue(RV, ResultType);
|
|
}
|
|
|
|
CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
|
|
return CharUnits::Zero();
|
|
}
|
|
|
|
llvm::Value *CGCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
|
|
llvm::Value *NewPtr,
|
|
llvm::Value *NumElements,
|
|
const CXXNewExpr *expr,
|
|
QualType ElementType) {
|
|
// Should never be called.
|
|
ErrorUnsupportedABI(CGF, "array cookie initialization");
|
|
return 0;
|
|
}
|
|
|
|
void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
|
|
const CXXDeleteExpr *expr, QualType ElementType,
|
|
llvm::Value *&NumElements,
|
|
llvm::Value *&AllocPtr, CharUnits &CookieSize) {
|
|
ErrorUnsupportedABI(CGF, "array cookie reading");
|
|
|
|
// This should be enough to avoid assertions.
|
|
NumElements = 0;
|
|
AllocPtr = llvm::Constant::getNullValue(CGF.Builder.getInt8PtrTy());
|
|
CookieSize = CharUnits::Zero();
|
|
}
|
|
|
|
void CGCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
|
|
const VarDecl &D,
|
|
llvm::GlobalVariable *GV,
|
|
bool PerformInit) {
|
|
ErrorUnsupportedABI(CGF, "static local variable initialization");
|
|
}
|