diff --git a/src/class.c b/src/class.c index 3398a944e0b6..712446f97231 100644 --- a/src/class.c +++ b/src/class.c @@ -548,6 +548,7 @@ void ClassDeclaration::semantic(Scope *sc) } } Lancestorsdone: + //printf("\tClassDeclaration::semantic(%s) doAncestorsSemantic = %d\n", toChars(), doAncestorsSemantic); if (!members) // if opaque declaration { @@ -555,8 +556,22 @@ void ClassDeclaration::semantic(Scope *sc) return; } if (!symtab) + { symtab = new DsymbolTable(); + /* Bugzilla 12152: The semantic analysis of base classes should be finished + * before the members semantic analysis of this class, in order to determine + * vtbl in this class. However if a base class refers the member of this class, + * it can be resolved as a normal forward reference. + * Call addMember() to make this class members visible from the base classes. + */ + for (size_t i = 0; i < members->dim; i++) + { + Dsymbol *s = (*members)[i]; + s->addMember(sc, this, 1); + } + } + for (size_t i = 0; i < baseclasses->dim; i++) { BaseClass *b = (*baseclasses)[i]; @@ -597,12 +612,6 @@ void ClassDeclaration::semantic(Scope *sc) } interfaceSemantic(sc); - for (size_t i = 0; i < members->dim; i++) - { - Dsymbol *s = (*members)[i]; - s->addMember(sc, this, 1); - } - /* If this is a nested class, add the hidden 'this' * member which is a pointer to the enclosing scope. */ diff --git a/test/compilable/testfwdref.d b/test/compilable/testfwdref.d new file mode 100644 index 000000000000..d68a46bc9a73 --- /dev/null +++ b/test/compilable/testfwdref.d @@ -0,0 +1,16 @@ +// PERMUTE_ARGS: + +/***************************************************/ +// 12152 + +class A12152 +{ + alias Y = B12152.X; +} + +class B12152 : A12152 +{ + alias int X; +} + +static assert(is(A12152.Y == int));