Slightly refactor RTTIBuilder

This commit is contained in:
Martin 2018-04-03 12:50:41 +02:00
parent 9ff736bf0f
commit e337cec78a
8 changed files with 44 additions and 61 deletions

View file

@ -613,8 +613,8 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
assert(cd->type->ty == Tclass); assert(cd->type->ty == Tclass);
IrAggr *ir = getIrAggr(cd); IrAggr *ir = getIrAggr(cd);
getClassInfoType(); // check declaration in object.d Type *const cinfoType = getClassInfoType(); // check declaration in object.d
ClassDeclaration *cinfo = Type::typeinfoclass; ClassDeclaration *const cinfo = Type::typeinfoclass;
if (cinfo->fields.dim != 12) { if (cinfo->fields.dim != 12) {
error(Loc(), "Unexpected number of fields in `object.ClassInfo`; " error(Loc(), "Unexpected number of fields in `object.ClassInfo`; "
@ -623,7 +623,7 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
} }
// use the rtti builder // use the rtti builder
RTTIBuilder b(cinfo); RTTIBuilder b(cinfoType);
LLConstant *c; LLConstant *c;
@ -664,7 +664,7 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
if (cd->baseClass && !cd->isInterfaceDeclaration()) { if (cd->baseClass && !cd->isInterfaceDeclaration()) {
b.push_classinfo(cd->baseClass); b.push_classinfo(cd->baseClass);
} else { } else {
b.push_null(cinfo->type); b.push_null(cinfoType);
} }
// destructor // destructor

View file

@ -194,8 +194,9 @@ llvm::Constant *buildLocalClasses(Module *m, size_t &count) {
} }
llvm::GlobalVariable *genModuleInfo(Module *m) { llvm::GlobalVariable *genModuleInfo(Module *m) {
getModuleInfoType(); // check declaration in object.d // check declaration in object.d
auto moduleInfoDecl = Module::moduleinfo; const auto moduleInfoType = getModuleInfoType();
const auto moduleInfoDecl = Module::moduleinfo;
// The "new-style" ModuleInfo records are variable-length, with the presence // The "new-style" ModuleInfo records are variable-length, with the presence
// of the various fields indicated by a certain flag bit. The base struct // of the various fields indicated by a certain flag bit. The base struct
@ -261,7 +262,7 @@ llvm::GlobalVariable *genModuleInfo(Module *m) {
} }
// Now, start building the initialiser for the ModuleInfo instance. // Now, start building the initialiser for the ModuleInfo instance.
RTTIBuilder b(moduleInfoDecl); RTTIBuilder b(moduleInfoType);
b.push_uint(flags); b.push_uint(flags);
b.push_uint(0); // index b.push_uint(0); // index

View file

@ -20,18 +20,16 @@
#include "ir/iraggr.h" #include "ir/iraggr.h"
#include "ir/irfunction.h" #include "ir/irfunction.h"
RTTIBuilder::RTTIBuilder(AggregateDeclaration *base_class) { RTTIBuilder::RTTIBuilder(Type *baseType) {
DtoResolveDsymbol(base_class); const auto ad = isAggregate(baseType);
assert(ad && "not an aggregate type");
base = base_class; DtoResolveDsymbol(ad);
basetype = static_cast<TypeClass *>(base->type);
baseir = getIrAggr(base); if (ad->isClassDeclaration()) {
assert(baseir && "no IrStruct for TypeInfo base class"); const auto baseir = getIrAggr(ad);
assert(baseir && "no IrAggr for TypeInfo base class");
prevFieldEnd = 0;
if (base->isClassDeclaration()) {
// just start with adding the vtbl // just start with adding the vtbl
push(baseir->getVtblSymbol()); push(baseir->getVtblSymbol());
// and monitor // and monitor

View file

@ -18,33 +18,25 @@
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Constant.h" #include "llvm/IR/Constant.h"
class AggregateDeclaration;
class ClassDeclaration; class ClassDeclaration;
class Dsymbol; class Dsymbol;
class FuncDeclaration; class FuncDeclaration;
struct IrGlobal;
struct IrAggr;
class Type; class Type;
class TypeClass;
namespace llvm { namespace llvm {
class StructType; class StructType;
class GlobalVariable; class GlobalVariable;
} }
class RTTIBuilder { class RTTIBuilder {
AggregateDeclaration *base;
TypeClass *basetype;
IrAggr *baseir;
/// The offset (in bytes) at which the previously pushed field ended. /// The offset (in bytes) at which the previously pushed field ended.
uint64_t prevFieldEnd; uint64_t prevFieldEnd = 0;
public: public:
// 15 is enough for any D2 ClassInfo including 64 bit pointer alignment // 15 is enough for any D2 ClassInfo including 64 bit pointer alignment
// padding // padding
llvm::SmallVector<llvm::Constant *, 15> inits; llvm::SmallVector<llvm::Constant *, 15> inits;
explicit RTTIBuilder(AggregateDeclaration *base_class); explicit RTTIBuilder(Type *baseType);
void push(llvm::Constant *C); void push(llvm::Constant *C);
void push_null(Type *T); void push_null(Type *T);

View file

@ -183,6 +183,8 @@ LazyClassType invariantTypeInfoTy(Type::typeinfoinvariant,
LazyClassType sharedTypeInfoTy(Type::typeinfoshared, "TypeInfo_Shared"); LazyClassType sharedTypeInfoTy(Type::typeinfoshared, "TypeInfo_Shared");
LazyClassType inoutTypeInfoTy(Type::typeinfowild, "TypeInfo_Inout"); LazyClassType inoutTypeInfoTy(Type::typeinfowild, "TypeInfo_Inout");
LazyClassType throwableTy(ClassDeclaration::throwable, "Throwable"); LazyClassType throwableTy(ClassDeclaration::throwable, "Throwable");
LazyClassType cppTypeInfoPtrTy(ClassDeclaration::cpp_type_info_ptr,
"__cpp_type_info_ptr");
using LazyAggregateType = LazyType<AggregateDeclaration>; using LazyAggregateType = LazyType<AggregateDeclaration>;
template <> const char *LazyAggregateType::getKind() { return "struct"; } template <> const char *LazyAggregateType::getKind() { return "struct"; }
@ -429,6 +431,7 @@ Type *getInvariantTypeInfoType() { return invariantTypeInfoTy.get(); }
Type *getSharedTypeInfoType() { return sharedTypeInfoTy.get(); } Type *getSharedTypeInfoType() { return sharedTypeInfoTy.get(); }
Type *getInoutTypeInfoType() { return inoutTypeInfoTy.get(); } Type *getInoutTypeInfoType() { return inoutTypeInfoTy.get(); }
Type *getThrowableType() { return throwableTy.get(); } Type *getThrowableType() { return throwableTy.get(); }
Type *getCppTypeInfoPtrType() { return cppTypeInfoPtrTy.get(); }
Type *getModuleInfoType() { return moduleInfoTy.get(); } Type *getModuleInfoType() { return moduleInfoTy.get(); }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -57,6 +57,7 @@ Type *getInvariantTypeInfoType();
Type *getSharedTypeInfoType(); Type *getSharedTypeInfoType();
Type *getInoutTypeInfoType(); Type *getInoutTypeInfoType();
Type *getThrowableType(); Type *getThrowableType();
Type *getCppTypeInfoPtrType();
Type *getModuleInfoType(); Type *getModuleInfoType();
#endif // LDC_GEN_RUNTIME_H #endif // LDC_GEN_RUNTIME_H

View file

@ -174,11 +174,13 @@ void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
mangleBuf.printf("%d%s", 18, "_cpp_type_info_ptr"); mangleBuf.printf("%d%s", 18, "_cpp_type_info_ptr");
const auto wrapperMangle = getIRMangledVarName(mangleBuf.peekString(), LINKd); const auto wrapperMangle = getIRMangledVarName(mangleBuf.peekString(), LINKd);
RTTIBuilder b(ClassDeclaration::cpp_type_info_ptr); const auto cppTypeInfoPtrType = getCppTypeInfoPtrType();
RTTIBuilder b(cppTypeInfoPtrType);
b.push(cpp_ti); b.push(cpp_ti);
auto wrapperType = llvm::cast<llvm::StructType>( auto wrapperType = llvm::cast<llvm::StructType>(
static_cast<IrTypeClass*>(ClassDeclaration::cpp_type_info_ptr->type->ctype)->getMemoryLLType()); static_cast<IrTypeClass *>(cppTypeInfoPtrType->ctype)
->getMemoryLLType());
auto wrapperInit = b.get_constant(wrapperType); auto wrapperInit = b.get_constant(wrapperType);
ci = getOrCreateGlobal( ci = getOrCreateGlobal(

View file

@ -144,8 +144,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getTypeInfoType(); // check declaration in object.d RTTIBuilder b(getTypeInfoType());
RTTIBuilder b(Type::dtypeinfo);
b.finalize(gvar); b.finalize(gvar);
} }
@ -156,8 +155,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getEnumTypeInfoType(); // check declaration in object.d RTTIBuilder b(getEnumTypeInfoType());
RTTIBuilder b(Type::typeinfoenum);
assert(decl->tinfo->ty == Tenum); assert(decl->tinfo->ty == Tenum);
TypeEnum *tc = static_cast<TypeEnum *>(decl->tinfo); TypeEnum *tc = static_cast<TypeEnum *>(decl->tinfo);
@ -192,8 +190,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getPointerTypeInfoType(); // check declaration in object.d RTTIBuilder b(getPointerTypeInfoType());
RTTIBuilder b(Type::typeinfopointer);
// TypeInfo base // TypeInfo base
b.push_typeinfo(decl->tinfo->nextOf()); b.push_typeinfo(decl->tinfo->nextOf());
// finish // finish
@ -207,8 +204,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getArrayTypeInfoType(); // check declaration in object.d RTTIBuilder b(getArrayTypeInfoType());
RTTIBuilder b(Type::typeinfoarray);
// TypeInfo base // TypeInfo base
b.push_typeinfo(decl->tinfo->nextOf()); b.push_typeinfo(decl->tinfo->nextOf());
// finish // finish
@ -225,8 +221,7 @@ public:
assert(decl->tinfo->ty == Tsarray); assert(decl->tinfo->ty == Tsarray);
TypeSArray *tc = static_cast<TypeSArray *>(decl->tinfo); TypeSArray *tc = static_cast<TypeSArray *>(decl->tinfo);
getStaticArrayTypeInfoType(); // check declaration in object.d RTTIBuilder b(getStaticArrayTypeInfoType());
RTTIBuilder b(Type::typeinfostaticarray);
// value typeinfo // value typeinfo
b.push_typeinfo(tc->nextOf()); b.push_typeinfo(tc->nextOf());
@ -249,8 +244,7 @@ public:
assert(decl->tinfo->ty == Taarray); assert(decl->tinfo->ty == Taarray);
TypeAArray *tc = static_cast<TypeAArray *>(decl->tinfo); TypeAArray *tc = static_cast<TypeAArray *>(decl->tinfo);
getAssociativeArrayTypeInfoType(); // check declaration in object.d RTTIBuilder b(getAssociativeArrayTypeInfoType());
RTTIBuilder b(Type::typeinfoassociativearray);
// value typeinfo // value typeinfo
b.push_typeinfo(tc->nextOf()); b.push_typeinfo(tc->nextOf());
@ -269,8 +263,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getFunctionTypeInfoType(); // check declaration in object.d RTTIBuilder b(getFunctionTypeInfoType());
RTTIBuilder b(Type::typeinfofunction);
// TypeInfo base // TypeInfo base
b.push_typeinfo(decl->tinfo->nextOf()); b.push_typeinfo(decl->tinfo->nextOf());
// string deco // string deco
@ -289,8 +282,7 @@ public:
assert(decl->tinfo->ty == Tdelegate); assert(decl->tinfo->ty == Tdelegate);
Type *ret_type = decl->tinfo->nextOf()->nextOf(); Type *ret_type = decl->tinfo->nextOf()->nextOf();
getDelegateTypeInfoType(); // check declaration in object.d RTTIBuilder b(getDelegateTypeInfoType());
RTTIBuilder b(Type::typeinfodelegate);
// TypeInfo base // TypeInfo base
b.push_typeinfo(ret_type); b.push_typeinfo(ret_type);
// string deco // string deco
@ -311,8 +303,9 @@ public:
TypeStruct *tc = static_cast<TypeStruct *>(decl->tinfo); TypeStruct *tc = static_cast<TypeStruct *>(decl->tinfo);
StructDeclaration *sd = tc->sym; StructDeclaration *sd = tc->sym;
getStructTypeInfoType(); // check declaration in object.d // check declaration in object.d
auto structTypeInfoDecl = Type::typeinfostruct; const auto structTypeInfoType = getStructTypeInfoType();
const auto structTypeInfoDecl = Type::typeinfostruct;
// On x86_64, class TypeInfo_Struct contains 2 additional fields // On x86_64, class TypeInfo_Struct contains 2 additional fields
// (m_arg1/m_arg2) which are used for the X86_64 System V ABI varargs // (m_arg1/m_arg2) which are used for the X86_64 System V ABI varargs
@ -329,7 +322,7 @@ public:
fatal(); fatal();
} }
RTTIBuilder b(structTypeInfoDecl); RTTIBuilder b(structTypeInfoType);
// handle opaque structs // handle opaque structs
if (!sd->members) { if (!sd->members) {
@ -492,8 +485,7 @@ public:
TypeClass *tc = static_cast<TypeClass *>(decl->tinfo); TypeClass *tc = static_cast<TypeClass *>(decl->tinfo);
DtoResolveClass(tc->sym); DtoResolveClass(tc->sym);
getInterfaceTypeInfoType(); // check declaration in object.d RTTIBuilder b(getInterfaceTypeInfoType());
RTTIBuilder b(Type::typeinfointerface);
// TypeInfo base // TypeInfo base
b.push_classinfo(tc->sym); b.push_classinfo(tc->sym);
@ -527,8 +519,7 @@ public:
LLArrayType *arrTy = LLArrayType::get(tiTy, dim); LLArrayType *arrTy = LLArrayType::get(tiTy, dim);
LLConstant *arrC = LLConstantArray::get(arrTy, arrInits); LLConstant *arrC = LLConstantArray::get(arrTy, arrInits);
getTupleTypeInfoType(); // check declaration in object.d RTTIBuilder b(getTupleTypeInfoType());
RTTIBuilder b(Type::typeinfotypelist);
// push TypeInfo[] // push TypeInfo[]
b.push_array(arrC, dim, getTypeInfoType(), nullptr); b.push_array(arrC, dim, getTypeInfoType(), nullptr);
@ -544,8 +535,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getConstTypeInfoType(); // check declaration in object.d RTTIBuilder b(getConstTypeInfoType());
RTTIBuilder b(Type::typeinfoconst);
// TypeInfo base // TypeInfo base
b.push_typeinfo(merge(decl->tinfo->mutableOf())); b.push_typeinfo(merge(decl->tinfo->mutableOf()));
// finish // finish
@ -559,8 +549,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getInvariantTypeInfoType(); // check declaration in object.d RTTIBuilder b(getInvariantTypeInfoType());
RTTIBuilder b(Type::typeinfoinvariant);
// TypeInfo base // TypeInfo base
b.push_typeinfo(merge(decl->tinfo->mutableOf())); b.push_typeinfo(merge(decl->tinfo->mutableOf()));
// finish // finish
@ -574,8 +563,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getSharedTypeInfoType(); // check declaration in object.d RTTIBuilder b(getSharedTypeInfoType());
RTTIBuilder b(Type::typeinfoshared);
// TypeInfo base // TypeInfo base
b.push_typeinfo(merge(decl->tinfo->unSharedOf())); b.push_typeinfo(merge(decl->tinfo->unSharedOf()));
// finish // finish
@ -589,8 +577,7 @@ public:
decl->toChars()); decl->toChars());
LOG_SCOPE; LOG_SCOPE;
getInoutTypeInfoType(); // check declaration in object.d RTTIBuilder b(getInoutTypeInfoType());
RTTIBuilder b(Type::typeinfowild);
// TypeInfo base // TypeInfo base
b.push_typeinfo(merge(decl->tinfo->mutableOf())); b.push_typeinfo(merge(decl->tinfo->mutableOf()));
// finish // finish
@ -607,8 +594,7 @@ public:
assert(decl->tinfo->ty == Tvector); assert(decl->tinfo->ty == Tvector);
TypeVector *tv = static_cast<TypeVector *>(decl->tinfo); TypeVector *tv = static_cast<TypeVector *>(decl->tinfo);
getVectorTypeInfoType(); // check declaration in object.d RTTIBuilder b(getVectorTypeInfoType());
RTTIBuilder b(Type::typeinfovector);
// TypeInfo base // TypeInfo base
b.push_typeinfo(tv->basetype); b.push_typeinfo(tv->basetype);
// finish // finish