[pkg-d-commits] [ldc] 41/95: Use DMD's typinf.d directly
Matthias Klumpp
mak at moszumanska.debian.org
Thu Jul 13 20:53:58 UTC 2017
This is an automated email from the git hooks/post-receive script.
mak pushed a commit to annotated tag v1.3.0-beta1
in repository ldc.
commit fd7c075e3bfd742a1e664f937ad1f07c1623bf4e
Author: Martin <noone at nowhere.com>
Date: Sun Mar 5 14:28:56 2017 +0100
Use DMD's typinf.d directly
Instead of letting our old copy silently go more and more out-of-sync.
In this case, we missed the upstream fix wrt. skipping the declaration of
ClassInfos for speculative class types.
There are 2 noteworthy functional changes for function
`getOrCreateTypeInfoDeclaration()`:
1) The old version always overwrote `torig->vtinfo` with `t->vtinfo` when
declaring a new TypeInfo, whereas upstream's `genTypeInfo()` only sets
it if it was null before.
2) The old version called `semanticTypeInfo()` during a semantic pass,
upstream doesn't.
The LDC-specific exception for class types in `builtinTypeInfo()` is still
required.
Fixes dmd-testsuite's runnable/b16278.d.
---
ddmd/typinf.d | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++
gen/declarations.cpp | 80 ----------------
gen/typinf.cpp | 116 +---------------------
gen/typinf.h | 3 +
4 files changed, 273 insertions(+), 192 deletions(-)
diff --git a/ddmd/typinf.d b/ddmd/typinf.d
new file mode 100644
index 0000000..2889bf5
--- /dev/null
+++ b/ddmd/typinf.d
@@ -0,0 +1,266 @@
+/**
+ * Compiler implementation of the
+ * $(LINK2 http://www.dlang.org, D programming language).
+ *
+ * Copyright: Copyright (c) 1999-2016 by Digital Mars, All Rights Reserved
+ * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
+ * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Source: $(DMDSRC _typeinf.d)
+ */
+
+module ddmd.typinf;
+
+import ddmd.declaration;
+import ddmd.dmodule;
+import ddmd.dscope;
+import ddmd.dclass;
+import ddmd.dstruct;
+import ddmd.errors;
+import ddmd.globals;
+import ddmd.gluelayer;
+import ddmd.mtype;
+import ddmd.visitor;
+
+version (IN_LLVM)
+{
+ import ddmd.dsymbol;
+ extern (C++) void Declaration_codegen(Dsymbol decl);
+}
+
+/****************************************************
+ * Get the exact TypeInfo.
+ */
+extern (C++) void genTypeInfo(Type torig, Scope* sc)
+{
+ //printf("Type::genTypeInfo() %p, %s\n", this, toChars());
+ if (!Type.dtypeinfo)
+ {
+ torig.error(Loc(), "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch");
+ fatal();
+ }
+
+ 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);
+ assert(t.vtinfo);
+
+ /* If this has a custom implementation in std/typeinfo, then
+ * do not generate a COMDAT for it.
+ */
+ if (!builtinTypeInfo(t))
+ {
+ // Generate COMDAT
+ if (sc) // if in semantic() pass
+ {
+ // Find module that will go all the way to an object file
+ Module m = sc._module.importedFrom;
+ m.members.push(t.vtinfo);
+ }
+ else // if in obj generation pass
+ {
+ version (IN_LLVM)
+ Declaration_codegen(t.vtinfo);
+ else
+ toObjFile(t.vtinfo, global.params.multiobj);
+ }
+ }
+ }
+ if (!torig.vtinfo)
+ torig.vtinfo = t.vtinfo; // Types aren't merged, but we can share the vtinfo's
+ assert(torig.vtinfo);
+}
+
+extern (C++) Type getTypeInfoType(Type t, Scope* sc)
+{
+ assert(t.ty != Terror);
+ genTypeInfo(t, sc);
+ return t.vtinfo.type;
+}
+
+extern (C++) TypeInfoDeclaration getTypeInfoDeclaration(Type t)
+{
+ //printf("Type::getTypeInfoDeclaration() %s\n", t.toChars());
+ switch (t.ty)
+ {
+ case Tpointer:
+ return TypeInfoPointerDeclaration.create(t);
+ case Tarray:
+ return TypeInfoArrayDeclaration.create(t);
+ case Tsarray:
+ return TypeInfoStaticArrayDeclaration.create(t);
+ case Taarray:
+ return TypeInfoAssociativeArrayDeclaration.create(t);
+ case Tstruct:
+ return TypeInfoStructDeclaration.create(t);
+ case Tvector:
+ return TypeInfoVectorDeclaration.create(t);
+ case Tenum:
+ return TypeInfoEnumDeclaration.create(t);
+ case Tfunction:
+ return TypeInfoFunctionDeclaration.create(t);
+ case Tdelegate:
+ return TypeInfoDelegateDeclaration.create(t);
+ case Ttuple:
+ return TypeInfoTupleDeclaration.create(t);
+ case Tclass:
+ if ((cast(TypeClass)t).sym.isInterfaceDeclaration())
+ return TypeInfoInterfaceDeclaration.create(t);
+ else
+ return TypeInfoClassDeclaration.create(t);
+
+ default:
+ return TypeInfoDeclaration.create(t);
+ }
+}
+
+extern (C++) bool isSpeculativeType(Type t)
+{
+ extern (C++) final class SpeculativeTypeVisitor : Visitor
+ {
+ alias visit = super.visit;
+ public:
+ bool result;
+
+ extern (D) this()
+ {
+ }
+
+ override void visit(Type t)
+ {
+ Type tb = t.toBasetype();
+ if (tb != t)
+ tb.accept(this);
+ }
+
+ override void visit(TypeNext t)
+ {
+ if (t.next)
+ t.next.accept(this);
+ }
+
+ override void visit(TypeBasic t)
+ {
+ }
+
+ override void visit(TypeVector t)
+ {
+ t.basetype.accept(this);
+ }
+
+ override void visit(TypeAArray t)
+ {
+ t.index.accept(this);
+ visit(cast(TypeNext)t);
+ }
+
+ override void visit(TypeFunction t)
+ {
+ visit(cast(TypeNext)t);
+ // Currently TypeInfo_Function doesn't store parameter types.
+ }
+
+ override void visit(TypeStruct t)
+ {
+ StructDeclaration sd = t.sym;
+ if (auto ti = sd.isInstantiated())
+ {
+ if (!ti.needsCodegen())
+ {
+ if (ti.minst || sd.requestTypeInfo)
+ return;
+
+ /* Bugzilla 14425: TypeInfo_Struct would refer the members of
+ * struct (e.g. opEquals via xopEquals field), so if it's instantiated
+ * in speculative context, TypeInfo creation should also be
+ * stopped to avoid 'unresolved symbol' linker errors.
+ */
+ /* When -debug/-unittest is specified, all of non-root instances are
+ * automatically changed to speculative, and here is always reached
+ * from those instantiated non-root structs.
+ * Therefore, if the TypeInfo is not auctually requested,
+ * we have to elide its codegen.
+ */
+ result |= true;
+ return;
+ }
+ }
+ else
+ {
+ //assert(!sd.inNonRoot() || sd.requestTypeInfo); // valid?
+ }
+ }
+
+ override void visit(TypeClass t)
+ {
+ ClassDeclaration sd = t.sym;
+ if (auto ti = sd.isInstantiated())
+ {
+ if (!ti.needsCodegen() && !ti.minst)
+ {
+ result |= true;
+ }
+ }
+ }
+
+
+ override void visit(TypeTuple t)
+ {
+ if (t.arguments)
+ {
+ for (size_t i = 0; i < t.arguments.dim; i++)
+ {
+ Type tprm = (*t.arguments)[i].type;
+ if (tprm)
+ tprm.accept(this);
+ if (result)
+ return;
+ }
+ }
+ }
+ }
+
+ scope SpeculativeTypeVisitor v = new SpeculativeTypeVisitor();
+ t.accept(v);
+ return v.result;
+}
+
+/* ========================================================================= */
+
+/* These decide if there's an instance for them already in std.typeinfo,
+ * because then the compiler doesn't need to build one.
+ */
+extern (C++) static bool builtinTypeInfo(Type t)
+{
+ version (IN_LLVM)
+ {
+ // FIXME: if I enable for Tclass, the way LDC does typeinfo will cause
+ // a bunch of linker errors to missing ClassInfo init symbols.
+ if (t.isTypeBasic() || t.ty == Tnull)
+ return !t.mod;
+ }
+ else
+ {
+ if (t.isTypeBasic() || t.ty == Tclass || t.ty == Tnull)
+ return !t.mod;
+ }
+ if (t.ty == Tarray)
+ {
+ Type next = t.nextOf();
+ // strings are so common, make them builtin
+ return !t.mod &&
+ (next.isTypeBasic() !is null && !next.mod ||
+ next.ty == Tchar && next.mod == MODimmutable ||
+ next.ty == Tchar && next.mod == MODconst);
+ }
+ return false;
+}
diff --git a/gen/declarations.cpp b/gen/declarations.cpp
index 816e935..934a8b9 100644
--- a/gen/declarations.cpp
+++ b/gen/declarations.cpp
@@ -30,86 +30,6 @@
//////////////////////////////////////////////////////////////////////////////
-namespace {
-// from dmd/src/typinf.c
-bool isSpeculativeType(Type *t) {
- class SpeculativeTypeVisitor : public Visitor {
- public:
- bool result;
-
- SpeculativeTypeVisitor() : result(false) {}
-
- using Visitor::visit;
- void visit(Type *t) override {
- Type *tb = t->toBasetype();
- if (tb != t) {
- tb->accept(this);
- }
- }
- void visit(TypeNext *t) override {
- if (t->next) {
- t->next->accept(this);
- }
- }
- void visit(TypeBasic *t) override {}
- void visit(TypeVector *t) override { t->basetype->accept(this); }
- void visit(TypeAArray *t) override {
- t->index->accept(this);
- visit((TypeNext *)t);
- }
- void visit(TypeFunction *t) override {
- visit((TypeNext *)t);
- // Currently TypeInfo_Function doesn't store parameter types.
- }
- void visit(TypeStruct *t) override {
- StructDeclaration *sd = t->sym;
- if (TemplateInstance *ti = sd->isInstantiated()) {
- if (!ti->needsCodegen()) {
- if (ti->minst || sd->requestTypeInfo) {
- return;
- }
-
- /* Bugzilla 14425: TypeInfo_Struct would refer the members of
- * struct (e.g. opEquals via xopEquals field), so if it's instantiated
- * in speculative context, TypeInfo creation should also be
- * stopped to avoid 'unresolved symbol' linker errors.
- */
- /* When -debug/-unittest is specified, all of non-root instances are
- * automatically changed to speculative, and here is always reached
- * from those instantiated non-root structs.
- * Therefore, if the TypeInfo is not auctually requested,
- * we have to elide its codegen.
- */
- result |= true;
- return;
- }
- } else {
- // assert(!sd->inNonRoot() || sd->requestTypeInfo); // valid?
- }
- }
- void visit(TypeClass *t) override {}
- void visit(TypeTuple *t) override {
- if (t->arguments) {
- for (size_t i = 0; i < t->arguments->dim; i++) {
- Type *tprm = (*t->arguments)[i]->type;
- if (tprm) {
- tprm->accept(this);
- }
- if (result) {
- return;
- }
- }
- }
- }
- };
- SpeculativeTypeVisitor v;
- t->accept(&v);
- return v.result;
-}
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
class CodegenVisitor : public Visitor {
IRState *irs;
diff --git a/gen/typinf.cpp b/gen/typinf.cpp
index 2c56807..a63cbf0 100644
--- a/gen/typinf.cpp
+++ b/gen/typinf.cpp
@@ -53,129 +53,21 @@
#include <cstdio>
#include <ir/irtypeclass.h>
-static bool builtinTypeInfo(Type *t);
FuncDeclaration *search_toString(StructDeclaration *sd);
-namespace {
-TypeInfoDeclaration *createUnqualified(Type *t) {
- switch (t->ty) {
- case Tpointer:
- return TypeInfoPointerDeclaration::create(t);
- case Tarray:
- return TypeInfoArrayDeclaration::create(t);
- case Tsarray:
- return TypeInfoStaticArrayDeclaration::create(t);
- case Taarray:
- return TypeInfoAssociativeArrayDeclaration::create(t);
- case Tstruct:
- return TypeInfoStructDeclaration::create(t);
- case Tvector:
- return TypeInfoVectorDeclaration::create(t);
- case Tenum:
- return TypeInfoEnumDeclaration::create(t);
- case Tfunction:
- return TypeInfoFunctionDeclaration::create(t);
- case Tdelegate:
- return TypeInfoDelegateDeclaration::create(t);
- case Ttuple:
- return TypeInfoTupleDeclaration::create(t);
- case Tclass:
- if ((static_cast<TypeClass *>(t))->sym->isInterfaceDeclaration()) {
- return TypeInfoInterfaceDeclaration::create(t);
- } else {
- return TypeInfoClassDeclaration::create(t);
- }
- default:
- return TypeInfoDeclaration::create(t);
- }
-}
-}
+// defined in ddmd/typinf.d:
+void genTypeInfo(Type *torig, Scope *sc);
+bool builtinTypeInfo(Type *t);
TypeInfoDeclaration *getOrCreateTypeInfoDeclaration(Type *torig, Scope *sc) {
IF_LOG Logger::println("Type::getTypeInfo(): %s", torig->toChars());
LOG_SCOPE
- if (!Type::dtypeinfo) {
- torig->error(Loc(), "TypeInfo not found. object.d may be incorrectly "
- "installed or corrupt, compile with -v switch");
- fatal();
- }
+ genTypeInfo(torig, 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 = createUnqualified(t);
- }
- assert(t->vtinfo);
- torig->vtinfo = t->vtinfo;
-
- /* If this has a custom implementation in std/typeinfo, then
- * do not generate a COMDAT for it.
- */
- if (!builtinTypeInfo(t)) { // Generate COMDAT
- if (sc) // if in semantic() pass
- {
- // Find module that will go all the way to an object file
- Module *m = sc->module->importedFrom;
- m->members->push(t->vtinfo);
-
- semanticTypeInfo(sc, t);
- } else // if in obj generation pass
- {
- Declaration_codegen(t->vtinfo);
- }
- }
- }
- if (!torig->vtinfo) {
- torig->vtinfo =
- t->vtinfo; // Types aren't merged, but we can share the vtinfo's
- }
- assert(torig->vtinfo);
return torig->vtinfo;
}
-Type *getTypeInfoType(Type *t, Scope *sc) {
- assert(t->ty != Terror);
- getOrCreateTypeInfoDeclaration(t, sc);
- return t->vtinfo->type;
-}
-
-/* ========================================================================= */
-
-/* These decide if there's an instance for them already in std.typeinfo,
- * because then the compiler doesn't need to build one.
- */
-
-static bool builtinTypeInfo(Type *t) {
-#if 0
- // FIXME if I enable for Tclass, the way LDC does typeinfo will cause a
- // bunch of linker errors to missing class typeinfo definitions.
- if (t->isTypeBasic() || t->ty == Tclass)
- return !t->mod;
-#else
- if (t->isTypeBasic()) {
- return !t->mod;
- }
-#endif
-
- if (t->ty == Tarray) {
- Type *next = t->nextOf();
- return !t->mod && ((next->isTypeBasic() != nullptr && !next->mod) ||
- // strings are so common, make them builtin
- (next->ty == Tchar && next->mod == MODimmutable) ||
- (next->ty == Tchar && next->mod == MODconst));
- }
- return false;
-}
-
/* ========================================================================= */
//////////////////////////////////////////////////////////////////////////////
diff --git a/gen/typinf.h b/gen/typinf.h
index 6a0f0cd..2bf69fd 100644
--- a/gen/typinf.h
+++ b/gen/typinf.h
@@ -24,6 +24,9 @@ void DtoResolveTypeInfo(TypeInfoDeclaration *tid);
TypeInfoDeclaration *getOrCreateTypeInfoDeclaration(Type *t, Scope *sc);
void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p);
void TypeInfoClassDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p);
+
+// defined in ddmd/typinf.d:
Type *getTypeInfoType(Type *t, Scope *sc);
+bool isSpeculativeType(Type *t);
#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git
More information about the pkg-d-commits
mailing list