From f8846a76aca5d970780d139845c5ab0aa2bd7306 Mon Sep 17 00:00:00 2001 From: "Dennis O." Date: Sat, 5 Oct 2024 11:19:02 +0100 Subject: [PATCH] Move `newScope` out of AST nodes to `dsymbolsem.d` (#16880) --- compiler/src/dmd/attrib.d | 115 ----------------------------- compiler/src/dmd/attrib.h | 11 --- compiler/src/dmd/dsymbol.h | 1 + compiler/src/dmd/dsymbolsem.d | 134 ++++++++++++++++++++++++++++++++++ compiler/src/dmd/frontend.h | 11 --- 5 files changed, 135 insertions(+), 137 deletions(-) diff --git a/compiler/src/dmd/attrib.d b/compiler/src/dmd/attrib.d index f960cb95629a..f3f45e0f473d 100644 --- a/compiler/src/dmd/attrib.d +++ b/compiler/src/dmd/attrib.d @@ -112,14 +112,6 @@ extern (C++) abstract class AttribDeclaration : Dsymbol return sc2; } - /**************************************** - * A hook point to supply scope for members. - * addMember, setScope, importAll, semantic, semantic2 and semantic3 will use this. - */ - Scope* newScope(Scope* sc) - { - return sc; - } override void addComment(const(char)* comment) { @@ -201,28 +193,6 @@ extern (C++) class StorageClassDeclaration : AttribDeclaration return new StorageClassDeclaration(stc, Dsymbol.arraySyntaxCopy(decl)); } - override Scope* newScope(Scope* sc) - { - StorageClass scstc = sc.stc; - /* These sets of storage classes are mutually exclusive, - * so choose the innermost or most recent one. - */ - if (stc & (STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.manifest)) - scstc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.manifest); - if (stc & (STC.auto_ | STC.scope_ | STC.static_ | STC.manifest | STC.gshared)) - scstc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.manifest | STC.gshared); - if (stc & (STC.const_ | STC.immutable_ | STC.manifest)) - scstc &= ~(STC.const_ | STC.immutable_ | STC.manifest); - if (stc & (STC.gshared | STC.shared_)) - scstc &= ~(STC.gshared | STC.shared_); - if (stc & (STC.safe | STC.trusted | STC.system)) - scstc &= ~(STC.safe | STC.trusted | STC.system); - scstc |= stc; - //printf("scstc = x%llx\n", scstc); - return createNewScope(sc, scstc, sc.linkage, sc.cppmangle, - sc.visibility, sc.explicitVisibility, sc.aligndecl, sc.inlining); - } - override final bool oneMember(out Dsymbol ps, Identifier ident) { bool t = Dsymbol.oneMembers(decl, ps, ident); @@ -285,25 +255,6 @@ extern (C++) final class DeprecatedDeclaration : StorageClassDeclaration return new DeprecatedDeclaration(msg.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl)); } - /** - * Provides a new scope with `STC.deprecated_` and `Scope.depdecl` set - * - * Calls `StorageClassDeclaration.newScope` (as it must be called or copied - * in any function overriding `newScope`), then set the `Scope`'s depdecl. - * - * Returns: - * Always a new scope, to use for this `DeprecatedDeclaration`'s members. - */ - override Scope* newScope(Scope* sc) - { - auto scx = super.newScope(sc); - // The enclosing scope is deprecated as well - if (scx == sc) - scx = sc.push(); - scx.depdecl = this; - return scx; - } - override void accept(Visitor v) { v.visit(this); @@ -338,11 +289,6 @@ extern (C++) final class LinkDeclaration : AttribDeclaration return new LinkDeclaration(loc, linkage, Dsymbol.arraySyntaxCopy(decl)); } - override Scope* newScope(Scope* sc) - { - return createNewScope(sc, sc.stc, this.linkage, sc.cppmangle, sc.visibility, sc.explicitVisibility, - sc.aligndecl, sc.inlining); - } override const(char)* toChars() const { @@ -385,12 +331,6 @@ extern (C++) final class CPPMangleDeclaration : AttribDeclaration return new CPPMangleDeclaration(loc, cppmangle, Dsymbol.arraySyntaxCopy(decl)); } - override Scope* newScope(Scope* sc) - { - return createNewScope(sc, sc.stc, LINK.cpp, cppmangle, sc.visibility, sc.explicitVisibility, - sc.aligndecl, sc.inlining); - } - override const(char)* toChars() const { return toString().ptr; @@ -461,18 +401,6 @@ extern (C++) final class CPPNamespaceDeclaration : AttribDeclaration this.loc, this.ident, this.exp, Dsymbol.arraySyntaxCopy(this.decl), this.cppnamespace); } - /** - * Returns: - * A copy of the parent scope, with `this` as `namespace` and C++ linkage - */ - override Scope* newScope(Scope* sc) - { - auto scx = sc.copy(); - scx.linkage = LINK.cpp; - scx.namespace = this; - return scx; - } - override const(char)* toChars() const { return toString().ptr; @@ -544,13 +472,6 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration return new VisibilityDeclaration(this.loc, visibility, Dsymbol.arraySyntaxCopy(decl)); } - override Scope* newScope(Scope* sc) - { - if (pkg_identifiers) - dsymbolSemantic(this, sc); - return createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, this.visibility, 1, sc.aligndecl, sc.inlining); - } - override const(char)* kind() const { return "visibility attribute"; @@ -620,11 +541,6 @@ extern (C++) final class AlignDeclaration : AttribDeclaration Dsymbol.arraySyntaxCopy(decl)); } - override Scope* newScope(Scope* sc) - { - return createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, sc.visibility, sc.explicitVisibility, this, sc.inlining); - } - override void accept(Visitor v) { v.visit(this); @@ -693,17 +609,6 @@ extern (C++) final class PragmaDeclaration : AttribDeclaration return new PragmaDeclaration(loc, ident, Expression.arraySyntaxCopy(args), Dsymbol.arraySyntaxCopy(decl)); } - override Scope* newScope(Scope* sc) - { - if (ident == Id.Pinline) - { - // We keep track of this pragma inside scopes, - // then it's evaluated on demand in function semantic - return createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, sc.visibility, sc.explicitVisibility, sc.aligndecl, this); - } - return sc; - } - override const(char)* kind() const { return "pragma"; @@ -1004,13 +909,6 @@ extern(C++) final class ForwardingAttribDeclaration : AttribDeclaration sym.symtab = new DsymbolTable(); } - /************************************** - * Use the ForwardingScopeDsymbol as the parent symbol for members. - */ - override Scope* newScope(Scope* sc) - { - return sc.push(sym); - } override inout(ForwardingAttribDeclaration) isForwardingAttribDeclaration() inout { @@ -1087,18 +985,6 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration return new UserAttributeDeclaration(Expression.arraySyntaxCopy(this.atts), Dsymbol.arraySyntaxCopy(decl)); } - override Scope* newScope(Scope* sc) - { - Scope* sc2 = sc; - if (atts && atts.length) - { - // create new one for changes - sc2 = sc.copy(); - sc2.userAttribDecl = this; - } - return sc2; - } - extern (D) static Expressions* concat(Expressions* udas1, Expressions* udas2) { Expressions* udas; @@ -1178,7 +1064,6 @@ int foreachUdaNoSemantic(Dsymbol sym, int delegate(Expression) dg) return 0; } - /** * Returns: true if the given expression is an enum from `core.attribute` named `id` */ diff --git a/compiler/src/dmd/attrib.h b/compiler/src/dmd/attrib.h index d4c41ec94f36..403c4139be25 100644 --- a/compiler/src/dmd/attrib.h +++ b/compiler/src/dmd/attrib.h @@ -30,7 +30,6 @@ class AttribDeclaration : public Dsymbol Dsymbols *decl; // array of Dsymbol's virtual Dsymbols *include(Scope *sc); - virtual Scope *newScope(Scope *sc); void addComment(const utf8_t *comment) override; const char *kind() const override; bool oneMember(Dsymbol *&ps, Identifier *ident) override; @@ -48,7 +47,6 @@ class StorageClassDeclaration : public AttribDeclaration StorageClass stc; StorageClassDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; bool oneMember(Dsymbol *&ps, Identifier *ident) override final; StorageClassDeclaration *isStorageClassDeclaration() override { return this; } @@ -62,7 +60,6 @@ class DeprecatedDeclaration final : public StorageClassDeclaration const char *msgstr; DeprecatedDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; void accept(Visitor *v) override { v->visit(this); } }; @@ -73,7 +70,6 @@ class LinkDeclaration final : public AttribDeclaration static LinkDeclaration *create(const Loc &loc, LINK p, Dsymbols *decl); LinkDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; const char *toChars() const override; void accept(Visitor *v) override { v->visit(this); } }; @@ -84,7 +80,6 @@ class CPPMangleDeclaration final : public AttribDeclaration CPPMANGLE cppmangle; CPPMangleDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; const char *toChars() const override; void accept(Visitor *v) override { v->visit(this); } }; @@ -95,7 +90,6 @@ class CPPNamespaceDeclaration final : public AttribDeclaration Expression *exp; CPPNamespaceDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; const char *toChars() const override; void accept(Visitor *v) override { v->visit(this); } }; @@ -107,7 +101,6 @@ class VisibilityDeclaration final : public AttribDeclaration DArray pkg_identifiers; VisibilityDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; const char *kind() const override; const char *toPrettyChars(bool unused) override; VisibilityDeclaration *isVisibilityDeclaration() override { return this; } @@ -121,7 +114,6 @@ class AlignDeclaration final : public AttribDeclaration structalign_t salign; AlignDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; void accept(Visitor *v) override { v->visit(this); } }; @@ -146,7 +138,6 @@ class PragmaDeclaration final : public AttribDeclaration Expressions *args; // array of Expression's PragmaDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; const char *kind() const override; void accept(Visitor *v) override { v->visit(this); } }; @@ -200,7 +191,6 @@ class ForwardingAttribDeclaration final : public AttribDeclaration public: ForwardingScopeDsymbol *sym; - Scope *newScope(Scope *sc) override; ForwardingAttribDeclaration *isForwardingAttribDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -230,7 +220,6 @@ class UserAttributeDeclaration final : public AttribDeclaration Expressions *atts; UserAttributeDeclaration *syntaxCopy(Dsymbol *s) override; - Scope *newScope(Scope *sc) override; const char *kind() const override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/compiler/src/dmd/dsymbol.h b/compiler/src/dmd/dsymbol.h index 2c5f0e579b3a..79e3c0ebff2e 100644 --- a/compiler/src/dmd/dsymbol.h +++ b/compiler/src/dmd/dsymbol.h @@ -448,4 +448,5 @@ namespace dmd Dsymbol *search(Dsymbol *d, const Loc &loc, Identifier *ident, SearchOptFlags flags = (SearchOptFlags)SearchOpt::localsOnly); void setScope(Dsymbol *d, Scope *sc); void importAll(Dsymbol *d, Scope *sc); + Scope* newScope(Dsymbol *d, Scope *sc); } diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index 8db82c057ff4..4eed91aca3ad 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -7413,6 +7413,140 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor } } +extern(D) Scope* newScope(Dsymbol d, Scope* sc) +{ + scope nsv = new NewScopeVisitor(sc); + d.accept(nsv); + return nsv.sc; +} + +private extern(C++) class NewScopeVisitor : Visitor +{ + alias visit = typeof(super).visit; + Scope* sc; + this(Scope* sc) + { + this.sc = sc; + } + + /**************************************** + * A hook point to supply scope for members. + * addMember, setScope, importAll, semantic, semantic2 and semantic3 will use this. + */ + override void visit(AttribDeclaration dc){} + + override void visit(StorageClassDeclaration swt) + { + StorageClass scstc = sc.stc; + /* These sets of storage classes are mutually exclusive, + * so choose the innermost or most recent one. + */ + if (swt.stc & (STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.manifest)) + scstc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.manifest); + if (swt.stc & (STC.auto_ | STC.scope_ | STC.static_ | STC.manifest | STC.gshared)) + scstc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.manifest | STC.gshared); + if (swt.stc & (STC.const_ | STC.immutable_ | STC.manifest)) + scstc &= ~(STC.const_ | STC.immutable_ | STC.manifest); + if (swt.stc & (STC.gshared | STC.shared_)) + scstc &= ~(STC.gshared | STC.shared_); + if (swt.stc & (STC.safe | STC.trusted | STC.system)) + scstc &= ~(STC.safe | STC.trusted | STC.system); + scstc |= swt.stc; + //printf("scstc = x%llx\n", scstc); + sc = swt.createNewScope(sc, scstc, sc.linkage, sc.cppmangle, + sc.visibility, sc.explicitVisibility, sc.aligndecl, sc.inlining); + } + + /** + * Provides a new scope with `STC.deprecated_` and `Scope.depdecl` set + * + * Calls `StorageClassDeclaration.newScope` (as it must be called or copied + * in any function overriding `newScope`), then set the `Scope`'s depdecl. + * + * Returns: + * Always a new scope, to use for this `DeprecatedDeclaration`'s members. + */ + override void visit(DeprecatedDeclaration dpd) + { + auto oldsc = sc; + visit((cast(StorageClassDeclaration)dpd)); + auto scx = sc; + sc = oldsc; + // The enclosing scope is deprecated as well + if (scx == sc) + scx = sc.push(); + scx.depdecl = dpd; + sc = scx; + } + + override void visit(LinkDeclaration lid) + { + sc= lid.createNewScope(sc, sc.stc, lid.linkage, sc.cppmangle, sc.visibility, sc.explicitVisibility, + sc.aligndecl, sc.inlining); + } + + override void visit(CPPMangleDeclaration cpmd) + { + sc = cpmd.createNewScope(sc, sc.stc, LINK.cpp, cpmd.cppmangle, sc.visibility, sc.explicitVisibility, + sc.aligndecl, sc.inlining); + } + + /** + * Returns: + * A copy of the parent scope, with `this` as `namespace` and C++ linkage + *///override Scope* visit(Scope* sc) + override void visit(CPPNamespaceDeclaration scd) + { + auto scx = sc.copy(); + scx.linkage = LINK.cpp; + scx.namespace = scd; + sc = scx; + } + + override void visit(VisibilityDeclaration atbd) + { + if (atbd.pkg_identifiers) + dsymbolSemantic(atbd, sc); + + sc = atbd.createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, atbd.visibility, 1, sc.aligndecl, sc.inlining); + } + + override void visit(AlignDeclaration visd) + { + sc = visd.createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, sc.visibility, + sc.explicitVisibility, visd, sc.inlining); + } + + override void visit(PragmaDeclaration prd) + { + if (prd.ident == Id.Pinline) + { + // We keep track of this pragma inside scopes, + // then it's evaluated on demand in function semantic + sc = prd.createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, sc.visibility, sc.explicitVisibility, sc.aligndecl, prd); // @suppress(dscanner.style.long_line) + } + } + + /************************************** + * Use the ForwardingScopeDsymbol as the parent symbol for members. + */ + override void visit(ForwardingAttribDeclaration fad) + { + sc = sc.push(fad.sym); + } + + override void visit(UserAttributeDeclaration uac) + { + Scope* sc2 = sc; + if (uac.atts && uac.atts.length) + { + // create new one for changes + sc2 = sc.copy(); + sc2.userAttribDecl = uac; + } + sc = sc2; + } +} /** * Called from a symbol's semantic to check if `gnuAbiTag` UDA * can be applied to them diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 23d404ba6bc0..d47e83a44d98 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -6214,7 +6214,6 @@ class AttribDeclaration : public Dsymbol public: Array* decl; virtual Array* include(Scope* sc); - virtual Scope* newScope(Scope* sc); void addComment(const char* comment) override; const char* kind() const override; bool oneMember(Dsymbol*& ps, Identifier* ident) override; @@ -6231,7 +6230,6 @@ class StorageClassDeclaration : public AttribDeclaration public: StorageClass stc; StorageClassDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; bool oneMember(Dsymbol*& ps, Identifier* ident) final override; StorageClassDeclaration* isStorageClassDeclaration() override; void accept(Visitor* v) override; @@ -6243,7 +6241,6 @@ class DeprecatedDeclaration final : public StorageClassDeclaration Expression* msg; const char* msgstr; DeprecatedDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; void accept(Visitor* v) override; }; @@ -6253,7 +6250,6 @@ class LinkDeclaration final : public AttribDeclaration LINK linkage; static LinkDeclaration* create(const Loc& loc, LINK p, Array* decl); LinkDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; const char* toChars() const override; void accept(Visitor* v) override; }; @@ -6263,7 +6259,6 @@ class CPPMangleDeclaration final : public AttribDeclaration public: CPPMANGLE cppmangle; CPPMangleDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; const char* toChars() const override; void accept(Visitor* v) override; }; @@ -6273,7 +6268,6 @@ class CPPNamespaceDeclaration final : public AttribDeclaration public: Expression* exp; CPPNamespaceDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; const char* toChars() const override; void accept(Visitor* v) override; CPPNamespaceDeclaration* isCPPNamespaceDeclaration() override; @@ -6285,7 +6279,6 @@ class VisibilityDeclaration final : public AttribDeclaration Visibility visibility; _d_dynamicArray< Identifier* > pkg_identifiers; VisibilityDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; const char* kind() const override; const char* toPrettyChars(bool __param_0_) override; VisibilityDeclaration* isVisibilityDeclaration() override; @@ -6298,7 +6291,6 @@ class AlignDeclaration final : public AttribDeclaration Array* exps; structalign_t salign; AlignDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; void accept(Visitor* v) override; }; @@ -6321,7 +6313,6 @@ class PragmaDeclaration final : public AttribDeclaration public: Array* args; PragmaDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; const char* kind() const override; void accept(Visitor* v) override; }; @@ -6374,7 +6365,6 @@ class ForwardingAttribDeclaration final : public AttribDeclaration public: ForwardingScopeDsymbol* sym; ForwardingAttribDeclaration(Array* decl); - Scope* newScope(Scope* sc) override; ForwardingAttribDeclaration* isForwardingAttribDeclaration() override; void accept(Visitor* v) override; }; @@ -6396,7 +6386,6 @@ class UserAttributeDeclaration final : public AttribDeclaration public: Array* atts; UserAttributeDeclaration* syntaxCopy(Dsymbol* s) override; - Scope* newScope(Scope* sc) override; const char* kind() const override; void accept(Visitor* v) override; };