mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 09:00:33 +03:00
Refactoring: Improve Ir{Aggr,Class,Struct} encapsulation
This commit is contained in:
parent
a765bf8901
commit
e9021fd6c8
6 changed files with 122 additions and 112 deletions
110
ir/irclass.cpp
110
ir/irclass.cpp
|
@ -41,67 +41,75 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLGlobalVariable *IrClass::getVtblSymbol() {
|
||||
if (vtbl) {
|
||||
return vtbl;
|
||||
LLGlobalVariable *IrClass::getVtblSymbol(bool define) {
|
||||
if (!vtbl) {
|
||||
const auto irMangle = getIRMangledVTableSymbolName(aggrdecl);
|
||||
|
||||
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType();
|
||||
|
||||
vtbl = declareGlobal(aggrdecl->loc, gIR->module, vtblTy, irMangle,
|
||||
/*isConstant=*/true);
|
||||
}
|
||||
|
||||
// create the vtblZ symbol
|
||||
const auto irMangle = getIRMangledVTableSymbolName(aggrdecl);
|
||||
|
||||
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType();
|
||||
|
||||
vtbl = declareGlobal(aggrdecl->loc, gIR->module, vtblTy, irMangle,
|
||||
/*isConstant=*/true);
|
||||
if (define) {
|
||||
auto init = getVtblInit(); // might define vtbl
|
||||
if (!vtbl->hasInitializer())
|
||||
defineGlobal(vtbl, init, aggrdecl);
|
||||
}
|
||||
|
||||
return vtbl;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLGlobalVariable *IrClass::getClassInfoSymbol() {
|
||||
if (typeInfo) {
|
||||
return typeInfo;
|
||||
LLGlobalVariable *IrClass::getClassInfoSymbol(bool define) {
|
||||
if (!typeInfo) {
|
||||
const auto irMangle = getIRMangledClassInfoSymbolName(aggrdecl);
|
||||
|
||||
// The type is also ClassInfo for interfaces – the actual TypeInfo for them
|
||||
// is a TypeInfo_Interface instance that references __ClassZ in its "base"
|
||||
// member.
|
||||
Type *cinfoType = getClassInfoType();
|
||||
DtoType(cinfoType);
|
||||
IrTypeClass *tc = stripModifiers(cinfoType)->ctype->isClass();
|
||||
assert(tc && "invalid ClassInfo type");
|
||||
|
||||
// classinfos cannot be constants since they're used as locks for
|
||||
// synchronized
|
||||
typeInfo = declareGlobal(aggrdecl->loc, gIR->module, tc->getMemoryLLType(),
|
||||
irMangle, false);
|
||||
|
||||
// Generate some metadata on this ClassInfo if it's for a class.
|
||||
if (!aggrdecl->isInterfaceDeclaration()) {
|
||||
// regular TypeInfo metadata
|
||||
emitTypeInfoMetadata(typeInfo, aggrdecl->type);
|
||||
|
||||
// Gather information
|
||||
LLType *type = DtoType(aggrdecl->type);
|
||||
LLType *bodyType = llvm::cast<LLPointerType>(type)->getElementType();
|
||||
bool hasDestructor = (aggrdecl->dtor != nullptr);
|
||||
bool hasCustomDelete = false;
|
||||
// Construct the fields
|
||||
llvm::Metadata *mdVals[CD_NumFields];
|
||||
mdVals[CD_BodyType] =
|
||||
llvm::ConstantAsMetadata::get(llvm::UndefValue::get(bodyType));
|
||||
mdVals[CD_Finalize] = llvm::ConstantAsMetadata::get(
|
||||
LLConstantInt::get(LLType::getInt1Ty(gIR->context()), hasDestructor));
|
||||
mdVals[CD_CustomDelete] =
|
||||
llvm::ConstantAsMetadata::get(LLConstantInt::get(
|
||||
LLType::getInt1Ty(gIR->context()), hasCustomDelete));
|
||||
// Construct the metadata and insert it into the module.
|
||||
const auto metaname = getMetadataName(CD_PREFIX, typeInfo);
|
||||
llvm::NamedMDNode *node = gIR->module.getOrInsertNamedMetadata(metaname);
|
||||
node->addOperand(llvm::MDNode::get(
|
||||
gIR->context(), llvm::makeArrayRef(mdVals, CD_NumFields)));
|
||||
}
|
||||
}
|
||||
|
||||
// create the ClassZ / InterfaceZ symbol
|
||||
const auto irMangle = getIRMangledClassInfoSymbolName(aggrdecl);
|
||||
|
||||
// The type is also ClassInfo for interfaces – the actual TypeInfo for them
|
||||
// is a TypeInfo_Interface instance that references __ClassZ in its "base"
|
||||
// member.
|
||||
Type *cinfoType = getClassInfoType();
|
||||
DtoType(cinfoType);
|
||||
IrTypeClass *tc = stripModifiers(cinfoType)->ctype->isClass();
|
||||
assert(tc && "invalid ClassInfo type");
|
||||
|
||||
// classinfos cannot be constants since they're used as locks for synchronized
|
||||
typeInfo = declareGlobal(aggrdecl->loc, gIR->module, tc->getMemoryLLType(),
|
||||
irMangle, false);
|
||||
|
||||
// Generate some metadata on this ClassInfo if it's for a class.
|
||||
if (!aggrdecl->isInterfaceDeclaration()) {
|
||||
// regular TypeInfo metadata
|
||||
emitTypeInfoMetadata(typeInfo, aggrdecl->type);
|
||||
|
||||
// Gather information
|
||||
LLType *type = DtoType(aggrdecl->type);
|
||||
LLType *bodyType = llvm::cast<LLPointerType>(type)->getElementType();
|
||||
bool hasDestructor = (aggrdecl->dtor != nullptr);
|
||||
bool hasCustomDelete = false;
|
||||
// Construct the fields
|
||||
llvm::Metadata *mdVals[CD_NumFields];
|
||||
mdVals[CD_BodyType] =
|
||||
llvm::ConstantAsMetadata::get(llvm::UndefValue::get(bodyType));
|
||||
mdVals[CD_Finalize] = llvm::ConstantAsMetadata::get(
|
||||
LLConstantInt::get(LLType::getInt1Ty(gIR->context()), hasDestructor));
|
||||
mdVals[CD_CustomDelete] = llvm::ConstantAsMetadata::get(
|
||||
LLConstantInt::get(LLType::getInt1Ty(gIR->context()), hasCustomDelete));
|
||||
// Construct the metadata and insert it into the module.
|
||||
const auto metaname = getMetadataName(CD_PREFIX, typeInfo);
|
||||
llvm::NamedMDNode *node = gIR->module.getOrInsertNamedMetadata(metaname);
|
||||
node->addOperand(llvm::MDNode::get(
|
||||
gIR->context(), llvm::makeArrayRef(mdVals, CD_NumFields)));
|
||||
if (define) {
|
||||
auto init = getClassInfoInit();
|
||||
if (!typeInfo->hasInitializer())
|
||||
defineGlobal(typeInfo, init, aggrdecl);
|
||||
}
|
||||
|
||||
return typeInfo;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue