From 9543c479e2960014dad68632e6d6816786a0c63b Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Sun, 26 Jul 2020 00:17:08 -0700 Subject: [PATCH] add support for Object.RTTypeid template --- src/dmd/dsymbolsem.d | 3 +++ src/dmd/id.d | 1 + src/dmd/mtype.d | 1 + src/dmd/typinf.d | 57 ++++++++++++++++++++++++++++++++++++-------- 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/dmd/dsymbolsem.d b/src/dmd/dsymbolsem.d index 09a5003c7f0f..d5922f1408df 100644 --- a/src/dmd/dsymbolsem.d +++ b/src/dmd/dsymbolsem.d @@ -2719,6 +2719,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 2e3be17228b4..a7f1dcc5acd6 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 436fb3e517d6..c9c52e9a4b67 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..5673caf2724f 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,47 @@ 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); - else - t.vtinfo = getTypeInfoDeclaration(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(); + /* Save this for when RTTypeid is fully operational + if (!t.vtinfo) + { + .error(loc, "`object.RTTypeid!T` did not return a TypeInfo variable"); + fatal(); + } + */ + } + + 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); + else + t.vtinfo = getTypeInfoDeclaration(t); + } assert(t.vtinfo); /* If this has a custom implementation in std/typeinfo, then