diff --git a/compiler/src/dmd/attrib.d b/compiler/src/dmd/attrib.d index 1bfe7902a9..a03e7bbdc0 100644 --- a/compiler/src/dmd/attrib.d +++ b/compiler/src/dmd/attrib.d @@ -110,11 +110,6 @@ extern (C++) abstract class AttribDeclaration : Dsymbol return "attribute"; } - override final bool hasPointers() - { - return this.include(null).foreachDsymbol( (s) { return s.hasPointers(); } ) != 0; - } - /**************************************** */ override final void addObjcSymbols(ClassDeclarations* classes, ClassDeclarations* categories) diff --git a/compiler/src/dmd/attrib.h b/compiler/src/dmd/attrib.h index ef37e0adec..24d91abc62 100644 --- a/compiler/src/dmd/attrib.h +++ b/compiler/src/dmd/attrib.h @@ -29,7 +29,6 @@ class AttribDeclaration : public Dsymbol public: Dsymbols *decl; // array of Dsymbol's const char *kind() const override; - bool hasPointers() override final; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/compiler/src/dmd/cxxfrontend.d b/compiler/src/dmd/cxxfrontend.d index 67a174d66b..6bd3e32eee 100644 --- a/compiler/src/dmd/cxxfrontend.d +++ b/compiler/src/dmd/cxxfrontend.d @@ -198,6 +198,12 @@ bool isAbstract(ClassDeclaration cd) return dmd.dsymbolsem.isAbstract(cd); } +bool hasPointers(Dsymbol d) +{ + import dmd.dsymbolsem; + return dmd.dsymbolsem.hasPointers(d); +} + /*********************************************************** * dtemplate.d */ diff --git a/compiler/src/dmd/declaration.d b/compiler/src/dmd/declaration.d index 35047da4d6..4a1ec9f048 100644 --- a/compiler/src/dmd/declaration.d +++ b/compiler/src/dmd/declaration.d @@ -1035,12 +1035,6 @@ extern (C++) class VarDeclaration : Declaration vbitoffset < bitoffset + tbitsize; } - override final bool hasPointers() - { - //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type.ty); - return (!isDataseg() && type.hasPointers()); - } - /************************************* * Return true if we can take the address of this variable. */ diff --git a/compiler/src/dmd/declaration.h b/compiler/src/dmd/declaration.h index d27ed584bb..874d702123 100644 --- a/compiler/src/dmd/declaration.h +++ b/compiler/src/dmd/declaration.h @@ -298,7 +298,6 @@ public: bool isThreadlocal() override final; bool isCTFE(); bool isOverlappedWith(VarDeclaration *v); - bool hasPointers() override final; bool canTakeAddressOf(); bool needsScopeDtor(); Dsymbol *toAlias() override final; diff --git a/compiler/src/dmd/dstruct.d b/compiler/src/dmd/dstruct.d index 59c33baf77..5aef3585ca 100644 --- a/compiler/src/dmd/dstruct.d +++ b/compiler/src/dmd/dstruct.d @@ -158,13 +158,14 @@ extern (C++) class StructDeclaration : AggregateDeclaration return; foreach (vd; fields) { + import dmd.dsymbolsem : hasPointers; if (vd.storage_class & STC.ref_ || vd.hasPointers()) { hasPointerField = true; hasUnsafeBitpatterns = true; } - if (vd._init && vd._init.isVoidInitializer() && vd.type.hasPointers()) + if (vd._init && vd._init.isVoidInitializer() && vd.hasPointers()) hasVoidInitPointers = true; if (vd.storage_class & STC.system || vd.type.hasUnsafeBitpatterns()) diff --git a/compiler/src/dmd/dsymbol.d b/compiler/src/dmd/dsymbol.d index 74ca9cbda4..1b584eafaf 100644 --- a/compiler/src/dmd/dsymbol.d +++ b/compiler/src/dmd/dsymbol.d @@ -963,15 +963,6 @@ extern (C++) class Dsymbol : ASTNode return true; } - /***************************************** - * Is Dsymbol a variable that contains pointers? - */ - bool hasPointers() - { - //printf("Dsymbol::hasPointers() %s\n", toChars()); - return false; - } - void addObjcSymbols(ClassDeclarations* classes, ClassDeclarations* categories) { } diff --git a/compiler/src/dmd/dsymbol.h b/compiler/src/dmd/dsymbol.h index b942e75e97..77e7dabcb6 100644 --- a/compiler/src/dmd/dsymbol.h +++ b/compiler/src/dmd/dsymbol.h @@ -243,7 +243,6 @@ public: virtual bool needThis(); // need a 'this' pointer? virtual Visibility visible(); virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees - virtual bool hasPointers(); virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { } virtual void addComment(const utf8_t *comment); @@ -428,4 +427,5 @@ namespace dmd Dsymbols *include(Dsymbol *d, Scope *sc); void setScope(Dsymbol *d, Scope *sc); void importAll(Dsymbol *d, Scope *sc); + bool hasPointers(Dsymbol *d); } diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index bde34ac242..bf0731c185 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -953,6 +953,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (dsym.storage_class & STC.constscoperef) dsym.storage_class |= STC.scope_; + import dmd.typesem : hasPointers; + if (dsym.storage_class & STC.scope_) { STC stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.gshared); @@ -8641,3 +8643,50 @@ private extern(C++) class FinalizeSizeVisitor : Visitor sd.argTypes = target.toArgTypes(sd.type); } } + +/***************************************** +* Is Dsymbol a variable that contains pointers? +*/ +bool hasPointers(Dsymbol d) +{ + scope v = new HasPointersVisitor(); + d.accept(v); + return v.result; +} + +private extern(C++) class HasPointersVisitor : Visitor +{ + import dmd.mtype : Type; + + alias visit = Visitor.visit; + bool result; + + override void visit(AttribDeclaration ad) + { + result = ad.include(null).foreachDsymbol( (s) { return s.hasPointers(); } ) != 0; + } + + override void visit(VarDeclaration vd) + { + import dmd.typesem : hasPointers; + result = (!vd.isDataseg() && vd.type.hasPointers()); + } + + override void visit(Dsymbol d) + { + //printf("Dsymbol::hasPointers() %s\n", toChars()); + result = false; + } + + override void visit(TemplateMixin tm) + { + //printf("TemplateMixin.hasPointers() %s\n", toChars()); + result = tm.members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0; + } + + override void visit(Nspace ns) + { + //printf("Nspace::hasPointers() %s\n", toChars()); + result = ns.members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0; + } +} diff --git a/compiler/src/dmd/dtemplate.d b/compiler/src/dmd/dtemplate.d index 2158895745..8c94856053 100644 --- a/compiler/src/dmd/dtemplate.d +++ b/compiler/src/dmd/dtemplate.d @@ -5490,12 +5490,6 @@ extern (C++) final class TemplateMixin : TemplateInstance return "mixin"; } - override bool hasPointers() - { - //printf("TemplateMixin.hasPointers() %s\n", toChars()); - return members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0; - } - extern (D) bool findTempDecl(Scope* sc) { // Follow qualifications to find the TemplateDeclaration diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 1cf43835cc..ce1e3d37ff 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -618,7 +618,6 @@ public: virtual bool needThis(); virtual Visibility visible(); virtual Dsymbol* syntaxCopy(Dsymbol* s); - virtual bool hasPointers(); virtual void addObjcSymbols(Array* classes, Array* categories); virtual void addComment(const char* comment); const char* comment(); @@ -1822,7 +1821,6 @@ public: TypeQualified* tqual; TemplateInstance* syntaxCopy(Dsymbol* s) override; const char* kind() const override; - bool hasPointers() override; void accept(Visitor* v) override; }; @@ -4916,7 +4914,6 @@ class Nspace final : public ScopeDsymbol public: Expression* identExp; Nspace* syntaxCopy(Dsymbol* s) override; - bool hasPointers() override; const char* kind() const override; void accept(Visitor* v) override; }; @@ -6418,7 +6415,6 @@ class AttribDeclaration : public Dsymbol public: Array* decl; const char* kind() const override; - bool hasPointers() final override; void addObjcSymbols(Array* classes, Array* categories) final override; void accept(Visitor* v) override; }; @@ -6892,7 +6888,6 @@ public: bool isThreadlocal() final override; bool isCTFE(); bool isOverlappedWith(VarDeclaration* v); - bool hasPointers() final override; bool canTakeAddressOf(); bool needsScopeDtor(); Dsymbol* toAlias() final override; diff --git a/compiler/src/dmd/nspace.d b/compiler/src/dmd/nspace.d index 0c93f0e799..b8116343d6 100644 --- a/compiler/src/dmd/nspace.d +++ b/compiler/src/dmd/nspace.d @@ -78,12 +78,6 @@ extern (C++) final class Nspace : ScopeDsymbol return ns; } - override bool hasPointers() - { - //printf("Nspace::hasPointers() %s\n", toChars()); - return members.foreachDsymbol( (s) { return s.hasPointers(); } ) != 0; - } - override const(char)* kind() const { return "namespace"; diff --git a/compiler/src/dmd/nspace.h b/compiler/src/dmd/nspace.h index 7b4c302303..782688b9de 100644 --- a/compiler/src/dmd/nspace.h +++ b/compiler/src/dmd/nspace.h @@ -21,7 +21,6 @@ class Nspace final : public ScopeDsymbol public: Expression *identExp; Nspace *syntaxCopy(Dsymbol *s) override; - bool hasPointers() override; const char *kind() const override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/compiler/src/dmd/template.h b/compiler/src/dmd/template.h index 5576965ce4..da754e8a7d 100644 --- a/compiler/src/dmd/template.h +++ b/compiler/src/dmd/template.h @@ -284,7 +284,6 @@ public: TemplateMixin *syntaxCopy(Dsymbol *s) override; const char *kind() const override; - bool hasPointers() override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/compiler/src/dmd/toobj.d b/compiler/src/dmd/toobj.d index 8b14654391..7aa75fbf17 100644 --- a/compiler/src/dmd/toobj.d +++ b/compiler/src/dmd/toobj.d @@ -35,7 +35,7 @@ import dmd.dmodule; import dmd.dscope; import dmd.dstruct; import dmd.dsymbol; -import dmd.dsymbolsem : hasStaticCtorOrDtor, include, isFuncHidden, isAbstract; +import dmd.dsymbolsem : hasPointers, hasStaticCtorOrDtor, include, isFuncHidden, isAbstract; import dmd.dtemplate; import dmd.errors; import dmd.errorsink; diff --git a/compiler/src/dmd/typesem.d b/compiler/src/dmd/typesem.d index 71575477a1..9b706d162c 100644 --- a/compiler/src/dmd/typesem.d +++ b/compiler/src/dmd/typesem.d @@ -6686,6 +6686,7 @@ STC parameterStorageClass(TypeFunction tf, Type tthis, Parameter p, VarDeclarati // Check escaping through `this` if (tthis && tthis.isMutable()) { + import dmd.dsymbolsem : hasPointers; foreach (VarDeclaration v; isAggregate(tthis).fields) { if (v.hasPointers()) @@ -6696,6 +6697,7 @@ STC parameterStorageClass(TypeFunction tf, Type tthis, Parameter p, VarDeclarati // Check escaping through nested context if (outerVars && tf.isMutable()) { + import dmd.dsymbolsem : hasPointers; foreach (VarDeclaration v; *outerVars) { if (v.hasPointers())