diff --git a/src/dmd/dsymbolsem.d b/src/dmd/dsymbolsem.d index 69a59708bbe0..b13acfb21bf1 100644 --- a/src/dmd/dsymbolsem.d +++ b/src/dmd/dsymbolsem.d @@ -2710,6 +2710,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor { if (tempdecl.ident == Id.RTInfo) Type.rtinfo = tempdecl; + + if (tempdecl.ident == Id.RTTypeid) + Type.rttypeid = tempdecl; } /* Remember Scope for later instantiations, but make diff --git a/src/dmd/id.d b/src/dmd/id.d index 05e70ab8e82a..ec7e633da023 100644 --- a/src/dmd/id.d +++ b/src/dmd/id.d @@ -107,6 +107,7 @@ immutable Msgtable[] msgtable = { "outer" }, { "Exception" }, { "RTInfo" }, + { "RTTypeid" }, { "Throwable" }, { "Error" }, { "withSym", "__withSym" }, diff --git a/src/dmd/mtype.d b/src/dmd/mtype.d index e41c53adc271..1bc32250009a 100644 --- a/src/dmd/mtype.d +++ b/src/dmd/mtype.d @@ -473,6 +473,7 @@ extern (C++) abstract class Type : ASTNode extern (C++) __gshared ClassDeclaration typeinfowild; extern (C++) __gshared TemplateDeclaration rtinfo; + extern (C++) __gshared TemplateDeclaration rttypeid; extern (C++) __gshared Type[TMAX] basic; diff --git a/src/dmd/typinf.d b/src/dmd/typinf.d index d1a254f8b51c..b857c0c13b96 100644 --- a/src/dmd/typinf.d +++ b/src/dmd/typinf.d @@ -11,15 +11,21 @@ module dmd.typinf; +import dmd.arraytypes; import dmd.declaration; import dmd.dmodule; import dmd.dscope; import dmd.dclass; import dmd.dstruct; +import dmd.dsymbolsem; +import dmd.dtemplate; import dmd.errors; +import dmd.expressionsem; import dmd.globals; import dmd.gluelayer; import dmd.mtype; +import dmd.semantic2; +import dmd.semantic3; import dmd.visitor; import core.stdc.stdio; @@ -56,16 +62,44 @@ void genTypeInfo(Loc loc, Type torig, Scope* sc) Type t = torig.merge2(); // do this since not all Type's are merge'd if (!t.vtinfo) { - if (t.isShared()) // does both 'shared' and 'shared const' - t.vtinfo = TypeInfoSharedDeclaration.create(t); - else if (t.isConst()) - t.vtinfo = TypeInfoConstDeclaration.create(t); - else if (t.isImmutable()) - t.vtinfo = TypeInfoInvariantDeclaration.create(t); - else if (t.isWild()) - t.vtinfo = TypeInfoWildDeclaration.create(t); + if (Type.rttypeid) + { + // Evaluate: RTTypeid!t + auto tiargs = new Objects(); + tiargs.push(t); + auto ti = new TemplateInstance(loc, Type.rttypeid, tiargs); + + Scope* sc3 = ti.tempdecl._scope.startCTFE(); + sc3.tinst = sc.tinst; + sc3.minst = sc.minst; + ti.dsymbolSemantic(sc3); + ti.semantic2(sc3); + ti.semantic3(sc3); + auto e = symbolToExp(ti.toAlias(), Loc.initial, sc3, false); + + sc3.endCTFE(); + + e = e.ctfeInterpret(); + t.vtinfo = cast(TypeInfoDeclaration) e.isVarExp(); + if (!t.vtinfo) + { + .error(loc, "`object.RTTypeid!T` did not return a TypeInfo variable"); + fatal(); + } + } else - t.vtinfo = getTypeInfoDeclaration(t); + { + if (t.isShared()) // does both 'shared' and 'shared const' + t.vtinfo = TypeInfoSharedDeclaration.create(t); + else if (t.isConst()) + t.vtinfo = TypeInfoConstDeclaration.create(t); + else if (t.isImmutable()) + t.vtinfo = TypeInfoInvariantDeclaration.create(t); + else if (t.isWild()) + t.vtinfo = TypeInfoWildDeclaration.create(t); + else + t.vtinfo = getTypeInfoDeclaration(t); + } assert(t.vtinfo); /* If this has a custom implementation in std/typeinfo, then