Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion gen/typinf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,19 @@ class DeclareOrDefineVisitor : public Visitor {
auto cd = decl->tinfo->isTypeClass()->sym;
DtoResolveClass(cd);

auto irclass = getIrAggr(cd, true);
IrGlobal *irg = getIrGlobal(decl, true);
irg->value = getIrAggr(cd)->getClassInfoSymbol();

auto ti = irclass->getClassInfoSymbol();
irg->value = ti;

// check if the definition can be elided
if (irclass->suppressTypeInfo()) {
return;
}

irclass->getClassInfoSymbol(true);
ti->setLinkage(TYPEINFO_LINKAGE_TYPE); // override
}

// Build all other TypeInfos.
Expand Down
5 changes: 3 additions & 2 deletions ir/iraggr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "gen/mangling.h"
#include "gen/pragma.h"
#include "gen/tollvm.h"
#include "gen/linkage.h"
#include "ir/irdsymbol.h"
#include "ir/irtypeclass.h"
#include "ir/irtypestruct.h"
Expand Down Expand Up @@ -102,9 +103,9 @@ LLGlobalVariable *IrAggr::getInitSymbol(bool define) {

if (define) {
auto initConstant = getDefaultInit();
if (!init->hasInitializer()) {
if (!init->hasInitializer())
init = gIR->setGlobalVarInitializer(init, initConstant, aggrdecl);
}
init->setLinkage(TYPEINFO_LINKAGE_TYPE); // override
}

return init;
Expand Down
20 changes: 14 additions & 6 deletions ir/irclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "gen/runtime.h"
#include "gen/tollvm.h"
#include "gen/typinf.h"
#include "gen/linkage.h"
#include "ir/iraggr.h"
#include "ir/irdsymbol.h"
#include "ir/irfunction.h"
Expand Down Expand Up @@ -89,8 +90,10 @@ LLGlobalVariable *IrClass::getVtblSymbol(bool define) {

if (define) {
auto init = getVtblInit(); // might define vtbl
if (!vtbl->hasInitializer())
if (!vtbl->hasInitializer()) {
defineGlobal(vtbl, init, aggrdecl);
vtbl->setLinkage(TYPEINFO_LINKAGE_TYPE); // override
}
}

return vtbl;
Expand Down Expand Up @@ -140,8 +143,10 @@ LLGlobalVariable *IrClass::getClassInfoSymbol(bool define) {

if (define) {
auto init = getClassInfoInit();
if (!typeInfo->hasInitializer())
if (!typeInfo->hasInitializer()) {
defineGlobal(typeInfo, init, aggrdecl);
typeInfo->setLinkage(TYPEINFO_LINKAGE_TYPE); // override
}
}

return typeInfo;
Expand Down Expand Up @@ -367,7 +372,7 @@ LLConstant *IrClass::getClassInfoInit() {
if (isInterface) {
b.push_null_void_array();
} else {
b.push_void_array(cd->size(Loc()), getInitSymbol());
b.push_void_array(cd->size(Loc()), getInitSymbol(true));
}

// string name
Expand All @@ -381,7 +386,7 @@ LLConstant *IrClass::getClassInfoInit() {
if (isInterface) {
b.push_array(0, getNullPtr());
} else {
b.push_array(cd->vtbl.length, getVtblSymbol());
b.push_array(cd->vtbl.length, getVtblSymbol(true)); // override
}

// Interface[] interfaces
Expand All @@ -391,7 +396,9 @@ LLConstant *IrClass::getClassInfoInit() {
assert(!isInterface || !cd->baseClass);
if (cd->baseClass) {
DtoResolveClass(cd->baseClass);
b.push(getIrAggr(cd->baseClass)->getClassInfoSymbol());
auto ti = getIrAggr(cd->baseClass)->getClassInfoSymbol(true);
ti->setLinkage(TYPEINFO_LINKAGE_TYPE); // override
b.push(ti);
} else {
b.push_null(cinfoType);
}
Expand Down Expand Up @@ -743,7 +750,7 @@ LLConstant *IrClass::getClassInfoInterfaces() {
assert(itc && "null interface IrTypeClass");

// classinfo
LLConstant *ci = irinter->getClassInfoSymbol();
LLConstant *ci = irinter->getClassInfoSymbol(true);

// vtbl
LLConstant *vtb;
Expand Down Expand Up @@ -772,6 +779,7 @@ LLConstant *IrClass::getClassInfoInterfaces() {
LLConstant *arr = LLConstantArray::get(array_type, constants);
auto ciarr = getInterfaceArraySymbol();
defineGlobal(ciarr, arr, cd);
ciarr->setLinkage(TYPEINFO_LINKAGE_TYPE); // override

// return null, only baseclass provide interfaces
if (cd->vtblInterfaces->length == 0) {
Expand Down
4 changes: 2 additions & 2 deletions tests/codegen/pragma_no_typeinfo.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ struct StructWithTypeInfo {}
// force emission
auto ti = typeid(StructWithTypeInfo);

// CHECK: _D18pragma_no_typeinfo17ClassWithTypeInfo7__ClassZ = global %object.TypeInfo_Class
// CHECK: _D18pragma_no_typeinfo17ClassWithTypeInfo7__ClassZ = linkonce_odr global %object.TypeInfo_Class
class ClassWithTypeInfo {}

// CHECK: _D18pragma_no_typeinfo21InterfaceWithTypeInfo11__InterfaceZ = global %object.TypeInfo_Class
// CHECK: _D18pragma_no_typeinfo21InterfaceWithTypeInfo11__InterfaceZ = linkonce_odr global %object.TypeInfo_Class
interface InterfaceWithTypeInfo {}


Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/static_typeid_gh1540.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct S
{
}

// CHECK-DAG: _D{{.*}}1C7__ClassZ{{\"?}} = global %object.TypeInfo_Class
// CHECK-DAG: _D{{.*}}1C7__ClassZ{{\"?}} = linkonce_odr global %object.TypeInfo_Class
// CHECK-DAG: _D{{.*}}classvarC14TypeInfo_Class{{\"?}} = thread_local global ptr {{.*}}1C7__ClassZ
auto classvar = typeid(C);

Expand Down
13 changes: 13 additions & 0 deletions tests/linking/inputs/typeinfo_on_demand2.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module inputs.typeinfo_on_demand2;

extern(C++) class MyClass : MyInterface1 {
void method() {}
}

extern(C++) interface MyInterface1 {
void method();
}

extern(C++) interface MyInterface2 {
void method();
}
15 changes: 15 additions & 0 deletions tests/linking/typeinfo_on_demand.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Tests that TypeInfo is generated per CU to enable on demand usage

// RUN: %ldc -of%t_lib%obj -betterC -c %S/inputs/typeinfo_on_demand2.d
// RUN: %ldc -I%S %t_lib%obj -run %s

import inputs.typeinfo_on_demand2;

void main() {
MyChildClass mcc = new MyChildClass;
mcc.method();
}

extern(C++) class MyChildClass : MyClass, MyInterface2 {
override void method() {}
}
Loading