Skip to content

Commit afcee2c

Browse files
committed
Fix #4779 - C++ classes need TypeInfo
1 parent b5f7bb0 commit afcee2c

File tree

5 files changed

+46
-3
lines changed

5 files changed

+46
-3
lines changed

gen/typinf.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,19 @@ class DeclareOrDefineVisitor : public Visitor {
506506
auto cd = decl->tinfo->isTypeClass()->sym;
507507
DtoResolveClass(cd);
508508

509+
auto irclass = getIrAggr(cd, true);
509510
IrGlobal *irg = getIrGlobal(decl, true);
510-
irg->value = getIrAggr(cd)->getClassInfoSymbol();
511+
512+
auto ti = irclass->getClassInfoSymbol();
513+
irg->value = ti;
514+
515+
// check if the definition can be elided
516+
if (irclass->suppressTypeInfo()) {
517+
return;
518+
}
519+
520+
irclass->getClassInfoSymbol(true);
521+
ti->setLinkage(TYPEINFO_LINKAGE_TYPE); // override
511522
}
512523

513524
// Build all other TypeInfos.

ir/irclass.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "gen/runtime.h"
3030
#include "gen/tollvm.h"
3131
#include "gen/typinf.h"
32+
#include "gen/linkage.h"
3233
#include "ir/iraggr.h"
3334
#include "ir/irdsymbol.h"
3435
#include "ir/irfunction.h"
@@ -391,7 +392,9 @@ LLConstant *IrClass::getClassInfoInit() {
391392
assert(!isInterface || !cd->baseClass);
392393
if (cd->baseClass) {
393394
DtoResolveClass(cd->baseClass);
394-
b.push(getIrAggr(cd->baseClass)->getClassInfoSymbol());
395+
auto ti = getIrAggr(cd->baseClass)->getClassInfoSymbol(true);
396+
ti->setLinkage(TYPEINFO_LINKAGE_TYPE); // override
397+
b.push(ti);
395398
} else {
396399
b.push_null(cinfoType);
397400
}
@@ -772,6 +775,7 @@ LLConstant *IrClass::getClassInfoInterfaces() {
772775
LLConstant *arr = LLConstantArray::get(array_type, constants);
773776
auto ciarr = getInterfaceArraySymbol();
774777
defineGlobal(ciarr, arr, cd);
778+
ciarr->setLinkage(TYPEINFO_LINKAGE_TYPE); // override
775779

776780
// return null, only baseclass provide interfaces
777781
if (cd->vtblInterfaces->length == 0) {

tests/codegen/static_typeid_gh1540.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct S
1515
{
1616
}
1717

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module inputs.typeinfo_on_demand2;
2+
3+
extern(C++) class MyClass : MyInterface1 {
4+
void method() {}
5+
}
6+
7+
extern(C++) interface MyInterface1 {
8+
void method();
9+
}
10+
11+
extern(C++) interface MyInterface2 {
12+
void method();
13+
}

tests/linking/typeinfo_on_demand.d

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Tests that TypeInfo is generated per CU to enable on demand usage
2+
3+
// RUN: %ldc -of%t_lib%obj -betterC -c %S/inputs/typeinfo_on_demand2.d
4+
// RUN: %ldc -I%S %t_lib%obj -run %s
5+
6+
import inputs.typeinfo_on_demand2;
7+
8+
void main() {
9+
MyChildClass mcc = new MyChildClass;
10+
mcc.method();
11+
}
12+
13+
extern(C++) class MyChildClass : MyClass, MyInterface2 {
14+
override void method() {}
15+
}

0 commit comments

Comments
 (0)