mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 16:41:06 +03:00
Complete IrStruct->IrAggr rename.
This commit is contained in:
parent
b15588ed15
commit
1215ffacd3
11 changed files with 36 additions and 36 deletions
|
@ -57,9 +57,9 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||||
DtoType(cd->type);
|
DtoType(cd->type);
|
||||||
|
|
||||||
// create IrAggr
|
// create IrAggr
|
||||||
assert(cd->ir.irStruct == NULL);
|
assert(cd->ir.irAggr == NULL);
|
||||||
IrAggr* irAggr = new IrAggr(cd);
|
IrAggr* irAggr = new IrAggr(cd);
|
||||||
cd->ir.irStruct = irAggr;
|
cd->ir.irAggr = irAggr;
|
||||||
|
|
||||||
// make sure all fields really get their ir field
|
// make sure all fields really get their ir field
|
||||||
ArrayIter<VarDeclaration> it(cd->fields);
|
ArrayIter<VarDeclaration> it(cd->fields);
|
||||||
|
@ -152,7 +152,7 @@ DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, _d_allocclass);
|
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, _d_allocclass);
|
||||||
LLConstant* ci = DtoBitCast(tc->sym->ir.irStruct->getClassInfoSymbol(), DtoType(ClassDeclaration::classinfo->type));
|
LLConstant* ci = DtoBitCast(tc->sym->ir.irAggr->getClassInfoSymbol(), DtoType(ClassDeclaration::classinfo->type));
|
||||||
mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction();
|
mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction();
|
||||||
mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
|
mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ void DtoInitClass(TypeClass* tc, LLValue* dst)
|
||||||
|
|
||||||
// set vtable field seperately, this might give better optimization
|
// set vtable field seperately, this might give better optimization
|
||||||
LLValue* tmp = DtoGEPi(dst,0,0,"vtbl");
|
LLValue* tmp = DtoGEPi(dst,0,0,"vtbl");
|
||||||
LLValue* val = DtoBitCast(tc->sym->ir.irStruct->getVtblSymbol(), tmp->getType()->getContainedType(0));
|
LLValue* val = DtoBitCast(tc->sym->ir.irAggr->getVtblSymbol(), tmp->getType()->getContainedType(0));
|
||||||
DtoStore(val, tmp);
|
DtoStore(val, tmp);
|
||||||
|
|
||||||
// monitor always defaults to zero
|
// monitor always defaults to zero
|
||||||
|
@ -219,7 +219,7 @@ void DtoInitClass(TypeClass* tc, LLValue* dst)
|
||||||
LLValue* dstarr = DtoGEPi(dst,0,2,"tmp");
|
LLValue* dstarr = DtoGEPi(dst,0,2,"tmp");
|
||||||
|
|
||||||
// init symbols might not have valid types
|
// init symbols might not have valid types
|
||||||
LLValue* initsym = tc->sym->ir.irStruct->getInitSymbol();
|
LLValue* initsym = tc->sym->ir.irAggr->getInitSymbol();
|
||||||
initsym = DtoBitCast(initsym, DtoType(tc));
|
initsym = DtoBitCast(initsym, DtoType(tc));
|
||||||
LLValue* srcarr = DtoGEPi(initsym,0,2,"tmp");
|
LLValue* srcarr = DtoGEPi(initsym,0,2,"tmp");
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ DValue* DtoDynamicCastObject(DValue* val, Type* _to)
|
||||||
TypeClass* to = static_cast<TypeClass*>(_to->toBasetype());
|
TypeClass* to = static_cast<TypeClass*>(_to->toBasetype());
|
||||||
to->sym->codegen(Type::sir);
|
to->sym->codegen(Type::sir);
|
||||||
|
|
||||||
LLValue* cinfo = to->sym->ir.irStruct->getClassInfoSymbol();
|
LLValue* cinfo = to->sym->ir.irAggr->getClassInfoSymbol();
|
||||||
// unfortunately this is needed as the implementation of object differs somehow from the declaration
|
// unfortunately this is needed as the implementation of object differs somehow from the declaration
|
||||||
// this could happen in user code as well :/
|
// this could happen in user code as well :/
|
||||||
cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
|
cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
|
||||||
|
@ -441,7 +441,7 @@ DValue* DtoDynamicCastInterface(DValue* val, Type* _to)
|
||||||
// ClassInfo c
|
// ClassInfo c
|
||||||
TypeClass* to = static_cast<TypeClass*>(_to->toBasetype());
|
TypeClass* to = static_cast<TypeClass*>(_to->toBasetype());
|
||||||
to->sym->codegen(Type::sir);
|
to->sym->codegen(Type::sir);
|
||||||
LLValue* cinfo = to->sym->ir.irStruct->getClassInfoSymbol();
|
LLValue* cinfo = to->sym->ir.irAggr->getClassInfoSymbol();
|
||||||
// unfortunately this is needed as the implementation of object differs somehow from the declaration
|
// unfortunately this is needed as the implementation of object differs somehow from the declaration
|
||||||
// this could happen in user code as well :/
|
// this could happen in user code as well :/
|
||||||
cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
|
cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
|
||||||
|
@ -580,14 +580,14 @@ static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
|
||||||
|
|
||||||
static LLConstant* build_offti_array(ClassDeclaration* cd, LLType* arrayT)
|
static LLConstant* build_offti_array(ClassDeclaration* cd, LLType* arrayT)
|
||||||
{
|
{
|
||||||
IrStruct* irstruct = cd->ir.irStruct;
|
IrAggr* iraggr = cd->ir.irAggr;
|
||||||
|
|
||||||
size_t nvars = irstruct->varDecls.size();
|
size_t nvars = iraggr->varDecls.size();
|
||||||
std::vector<LLConstant*> arrayInits(nvars);
|
std::vector<LLConstant*> arrayInits(nvars);
|
||||||
|
|
||||||
for (size_t i=0; i<nvars; i++)
|
for (size_t i=0; i<nvars; i++)
|
||||||
{
|
{
|
||||||
arrayInits[i] = build_offti_entry(cd, irstruct->varDecls[i]);
|
arrayInits[i] = build_offti_entry(cd, iraggr->varDecls[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLConstant* size = DtoConstSize_t(nvars);
|
LLConstant* size = DtoConstSize_t(nvars);
|
||||||
|
@ -691,7 +691,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||||
assert(cd->type->ty == Tclass);
|
assert(cd->type->ty == Tclass);
|
||||||
TypeClass* cdty = static_cast<TypeClass*>(cd->type);
|
TypeClass* cdty = static_cast<TypeClass*>(cd->type);
|
||||||
|
|
||||||
IrAggr* ir = cd->ir.irStruct;
|
IrAggr* ir = cd->ir.irAggr;
|
||||||
assert(ir);
|
assert(ir);
|
||||||
|
|
||||||
ClassDeclaration* cinfo = ClassDeclaration::classinfo;
|
ClassDeclaration* cinfo = ClassDeclaration::classinfo;
|
||||||
|
|
|
@ -1279,7 +1279,7 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
|
||||||
{
|
{
|
||||||
Logger::println("const struct initializer");
|
Logger::println("const struct initializer");
|
||||||
si->ad->codegen(Type::sir);
|
si->ad->codegen(Type::sir);
|
||||||
return si->ad->ir.irStruct->createStructInitializer(si);
|
return si->ad->ir.irAggr->createStructInitializer(si);
|
||||||
}
|
}
|
||||||
else if (ArrayInitializer* ai = init->isArrayInitializer())
|
else if (ArrayInitializer* ai = init->isArrayInitializer())
|
||||||
{
|
{
|
||||||
|
@ -1851,7 +1851,7 @@ DValue* DtoSymbolAddress(const Loc& loc, Type* type, Declaration* decl)
|
||||||
{
|
{
|
||||||
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
|
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
|
||||||
cid->cd->codegen(Type::sir);;
|
cid->cd->codegen(Type::sir);;
|
||||||
return new DVarValue(type, vd, cid->cd->ir.irStruct->getClassInfoSymbol());
|
return new DVarValue(type, vd, cid->cd->ir.irAggr->getClassInfoSymbol());
|
||||||
}
|
}
|
||||||
// typeinfo
|
// typeinfo
|
||||||
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
|
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
|
||||||
|
@ -1960,7 +1960,7 @@ DValue* DtoSymbolAddress(const Loc& loc, Type* type, Declaration* decl)
|
||||||
assert(ts->sym);
|
assert(ts->sym);
|
||||||
ts->sym->codegen(Type::sir);
|
ts->sym->codegen(Type::sir);
|
||||||
|
|
||||||
LLValue* initsym = ts->sym->ir.irStruct->getInitSymbol();
|
LLValue* initsym = ts->sym->ir.irAggr->getInitSymbol();
|
||||||
initsym = DtoBitCast(initsym, DtoType(ts->pointerTo()));
|
initsym = DtoBitCast(initsym, DtoType(ts->pointerTo()));
|
||||||
return new DVarValue(type, initsym);
|
return new DVarValue(type, initsym);
|
||||||
}
|
}
|
||||||
|
|
|
@ -431,7 +431,7 @@ void Module::genmoduleinfo()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Logger::println("class: %s", cd->toPrettyChars());
|
Logger::println("class: %s", cd->toPrettyChars());
|
||||||
LLConstant *c = DtoBitCast(cd->ir.irStruct->getClassInfoSymbol(), classinfoTy);
|
LLConstant *c = DtoBitCast(cd->ir.irAggr->getClassInfoSymbol(), classinfoTy);
|
||||||
classInits.push_back(c);
|
classInits.push_back(c);
|
||||||
}
|
}
|
||||||
// has class array?
|
// has class array?
|
||||||
|
|
|
@ -26,7 +26,7 @@ RTTIBuilder::RTTIBuilder(AggregateDeclaration* base_class)
|
||||||
base = base_class;
|
base = base_class;
|
||||||
basetype = static_cast<TypeClass*>(base->type);
|
basetype = static_cast<TypeClass*>(base->type);
|
||||||
|
|
||||||
baseir = base->ir.irStruct;
|
baseir = base->ir.irAggr;
|
||||||
assert(baseir && "no IrStruct for TypeInfo base class");
|
assert(baseir && "no IrStruct for TypeInfo base class");
|
||||||
|
|
||||||
if (base->isClassDeclaration()) {
|
if (base->isClassDeclaration()) {
|
||||||
|
@ -59,7 +59,7 @@ void RTTIBuilder::push_typeinfo(Type* t)
|
||||||
|
|
||||||
void RTTIBuilder::push_classinfo(ClassDeclaration* cd)
|
void RTTIBuilder::push_classinfo(ClassDeclaration* cd)
|
||||||
{
|
{
|
||||||
inits.push_back(cd->ir.irStruct->getClassInfoSymbol());
|
inits.push_back(cd->ir.irAggr->getClassInfoSymbol());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTTIBuilder::push_string(const char* str)
|
void RTTIBuilder::push_string(const char* str)
|
||||||
|
|
|
@ -45,8 +45,8 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// create the IrAggr
|
// create the IrAggr
|
||||||
IrAggr* irstruct = new IrAggr(sd);
|
IrAggr* iraggr = new IrAggr(sd);
|
||||||
sd->ir.irStruct = irstruct;
|
sd->ir.irAggr = iraggr;
|
||||||
|
|
||||||
// Set up our field metadata.
|
// Set up our field metadata.
|
||||||
for (ArrayIter<VarDeclaration> it(sd->fields); !it.done(); it.next())
|
for (ArrayIter<VarDeclaration> it(sd->fields); !it.done(); it.next())
|
||||||
|
@ -61,10 +61,10 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||||
if (emitGlobalData)
|
if (emitGlobalData)
|
||||||
{
|
{
|
||||||
// emit the initZ symbol
|
// emit the initZ symbol
|
||||||
LLGlobalVariable* initZ = irstruct->getInitSymbol();
|
LLGlobalVariable* initZ = iraggr->getInitSymbol();
|
||||||
|
|
||||||
// set initZ initializer
|
// set initZ initializer
|
||||||
initZ->setInitializer(irstruct->getDefaultInit());
|
initZ->setInitializer(iraggr->getDefaultInit());
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit members
|
// emit members
|
||||||
|
|
12
gen/toir.cpp
12
gen/toir.cpp
|
@ -134,7 +134,7 @@ LLConstant* VarExp::toConstElem(IRState* p)
|
||||||
TypeStruct* ts = static_cast<TypeStruct*>(sdecltype);
|
TypeStruct* ts = static_cast<TypeStruct*>(sdecltype);
|
||||||
ts->sym->codegen(Type::sir);
|
ts->sym->codegen(Type::sir);
|
||||||
|
|
||||||
return ts->sym->ir.irStruct->getDefaultInit();
|
return ts->sym->ir.irAggr->getDefaultInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
|
if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
|
||||||
|
@ -2038,7 +2038,7 @@ DValue* NewExp::toElem(IRState* p)
|
||||||
else {
|
else {
|
||||||
assert(ts->sym);
|
assert(ts->sym);
|
||||||
ts->sym->codegen(Type::sir);
|
ts->sym->codegen(Type::sir);
|
||||||
DtoAggrCopy(mem, ts->sym->ir.irStruct->getInitSymbol());
|
DtoAggrCopy(mem, ts->sym->ir.irAggr->getInitSymbol());
|
||||||
}
|
}
|
||||||
if (ts->sym->isNested() && ts->sym->vthis)
|
if (ts->sym->isNested() && ts->sym->vthis)
|
||||||
DtoResolveNestedContext(loc, ts->sym, mem);
|
DtoResolveNestedContext(loc, ts->sym, mem);
|
||||||
|
@ -2937,7 +2937,7 @@ DValue* StructLiteralExp::toElem(IRState* p)
|
||||||
assert(ts->sym);
|
assert(ts->sym);
|
||||||
ts->sym->codegen(Type::sir);
|
ts->sym->codegen(Type::sir);
|
||||||
|
|
||||||
LLValue* initsym = ts->sym->ir.irStruct->getInitSymbol();
|
LLValue* initsym = ts->sym->ir.irAggr->getInitSymbol();
|
||||||
initsym = DtoBitCast(initsym, DtoType(ts->pointerTo()));
|
initsym = DtoBitCast(initsym, DtoType(ts->pointerTo()));
|
||||||
return new DVarValue(type, initsym);
|
return new DVarValue(type, initsym);
|
||||||
}
|
}
|
||||||
|
@ -3051,7 +3051,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p)
|
||||||
TypeStruct* ts = static_cast<TypeStruct*>(sdecltype);
|
TypeStruct* ts = static_cast<TypeStruct*>(sdecltype);
|
||||||
ts->sym->codegen(Type::sir);
|
ts->sym->codegen(Type::sir);
|
||||||
|
|
||||||
return ts->sym->ir.irStruct->getDefaultInit();
|
return ts->sym->ir.irAggr->getDefaultInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the struct is resolved
|
// make sure the struct is resolved
|
||||||
|
@ -3067,7 +3067,7 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sd->ir.irStruct->createInitializerConstant(varInits);
|
return sd->ir.irAggr->createInitializerConstant(varInits);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Constant* ClassReferenceExp::toConstElem(IRState *p)
|
llvm::Constant* ClassReferenceExp::toConstElem(IRState *p)
|
||||||
|
@ -3124,7 +3124,7 @@ llvm::Constant* ClassReferenceExp::toConstElem(IRState *p)
|
||||||
assert(i == nexprs);
|
assert(i == nexprs);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Constant* constValue = origClass->ir.irStruct->createInitializerConstant(varInits);
|
llvm::Constant* constValue = origClass->ir.irAggr->createInitializerConstant(varInits);
|
||||||
|
|
||||||
if (constValue->getType() != value->globalVar->getType()->getContainedType(0))
|
if (constValue->getType() != value->globalVar->getType()->getContainedType(0))
|
||||||
{
|
{
|
||||||
|
|
|
@ -604,7 +604,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||||
}
|
}
|
||||||
|
|
||||||
sd->codegen(Type::sir);
|
sd->codegen(Type::sir);
|
||||||
IrAggr* irstruct = sd->ir.irStruct;
|
IrAggr* iraggr = sd->ir.irAggr;
|
||||||
|
|
||||||
RTTIBuilder b(Type::typeinfostruct);
|
RTTIBuilder b(Type::typeinfostruct);
|
||||||
|
|
||||||
|
@ -618,7 +618,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||||
if (tc->isZeroInit(Loc()))
|
if (tc->isZeroInit(Loc()))
|
||||||
initPtr = getNullValue(getVoidPtrType());
|
initPtr = getNullValue(getVoidPtrType());
|
||||||
else
|
else
|
||||||
initPtr = irstruct->getInitSymbol();
|
initPtr = iraggr->getInitSymbol();
|
||||||
b.push_void_array(getTypeStoreSize(tc->irtype->getLLType()), initPtr);
|
b.push_void_array(getTypeStoreSize(tc->irtype->getLLType()), initPtr);
|
||||||
|
|
||||||
// toX functions ground work
|
// toX functions ground work
|
||||||
|
@ -737,7 +737,7 @@ void TypeInfoClassDeclaration::codegen(Ir*i)
|
||||||
assert(tinfo->ty == Tclass);
|
assert(tinfo->ty == Tclass);
|
||||||
TypeClass *tc = static_cast<TypeClass *>(tinfo);
|
TypeClass *tc = static_cast<TypeClass *>(tinfo);
|
||||||
tc->sym->codegen(Type::sir); // make sure class is resolved
|
tc->sym->codegen(Type::sir); // make sure class is resolved
|
||||||
irg->value = tc->sym->ir.irStruct->getClassInfoSymbol();
|
irg->value = tc->sym->ir.irAggr->getClassInfoSymbol();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeInfoClassDeclaration::llvmDefine()
|
void TypeInfoClassDeclaration::llvmDefine()
|
||||||
|
|
|
@ -394,7 +394,7 @@ LLConstant * IrAggr::getClassInfoInterfaces()
|
||||||
|
|
||||||
IF_LOG Logger::println("Adding interface %s", it->base->toPrettyChars());
|
IF_LOG Logger::println("Adding interface %s", it->base->toPrettyChars());
|
||||||
|
|
||||||
IrAggr* irinter = it->base->ir.irStruct;
|
IrAggr* irinter = it->base->ir.irAggr;
|
||||||
assert(irinter && "interface has null IrStruct");
|
assert(irinter && "interface has null IrStruct");
|
||||||
IrTypeClass* itc = stripModifiers(irinter->type)->irtype->isClass();
|
IrTypeClass* itc = stripModifiers(irinter->type)->irtype->isClass();
|
||||||
assert(itc && "null interface IrTypeClass");
|
assert(itc && "null interface IrTypeClass");
|
||||||
|
|
|
@ -36,7 +36,7 @@ IrDsymbol::IrDsymbol(const IrDsymbol& s)
|
||||||
assert(incr);
|
assert(incr);
|
||||||
DModule = s.DModule;
|
DModule = s.DModule;
|
||||||
irModule = s.irModule;
|
irModule = s.irModule;
|
||||||
irStruct = s.irStruct;
|
irAggr = s.irAggr;
|
||||||
irFunc = s.irFunc;
|
irFunc = s.irFunc;
|
||||||
resolved = s.resolved;
|
resolved = s.resolved;
|
||||||
declared = s.declared;
|
declared = s.declared;
|
||||||
|
@ -56,7 +56,7 @@ void IrDsymbol::reset()
|
||||||
{
|
{
|
||||||
DModule = NULL;
|
DModule = NULL;
|
||||||
irModule = NULL;
|
irModule = NULL;
|
||||||
irStruct = NULL;
|
irAggr = NULL;
|
||||||
irFunc = NULL;
|
irFunc = NULL;
|
||||||
resolved = declared = initialized = defined = false;
|
resolved = declared = initialized = defined = false;
|
||||||
irGlobal = NULL;
|
irGlobal = NULL;
|
||||||
|
@ -66,7 +66,7 @@ void IrDsymbol::reset()
|
||||||
|
|
||||||
bool IrDsymbol::isSet()
|
bool IrDsymbol::isSet()
|
||||||
{
|
{
|
||||||
return (irStruct || irFunc || irGlobal || irLocal || irField);
|
return (irAggr || irFunc || irGlobal || irLocal || irField);
|
||||||
}
|
}
|
||||||
|
|
||||||
IrVar* IrDsymbol::getIrVar()
|
IrVar* IrDsymbol::getIrVar()
|
||||||
|
|
|
@ -52,7 +52,7 @@ struct IrDsymbol
|
||||||
|
|
||||||
IrModule* irModule;
|
IrModule* irModule;
|
||||||
|
|
||||||
IrAggr* irStruct;
|
IrAggr* irAggr;
|
||||||
|
|
||||||
IrFunction* irFunc;
|
IrFunction* irFunc;
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB)
|
||||||
// create next block
|
// create next block
|
||||||
llvm::BasicBlock *next = llvm::BasicBlock::Create(gIR->context(), "eh.next", gIR->topfunc(), gIR->scopeend());
|
llvm::BasicBlock *next = llvm::BasicBlock::Create(gIR->context(), "eh.next", gIR->topfunc(), gIR->scopeend());
|
||||||
// get class info symbol
|
// get class info symbol
|
||||||
LLValue *classInfo = rit->catchType->ir.irStruct->getClassInfoSymbol();
|
LLValue *classInfo = rit->catchType->ir.irAggr->getClassInfoSymbol();
|
||||||
// add that symbol as landing pad clause
|
// add that symbol as landing pad clause
|
||||||
landingPad->addClause(classInfo);
|
landingPad->addClause(classInfo);
|
||||||
// call llvm.eh.typeid.for to get class info index in the exception table
|
// call llvm.eh.typeid.for to get class info index in the exception table
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue