diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2025-03-14 23:08:16 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2025-03-16 21:06:07 +0100 |
commit | 7d6e5591e6ab1f5a24dcf007b17f81cc19987c47 (patch) | |
tree | fdc4ad1abac3bd4a831b5e72ec6e3003f88f872c /gcc/d | |
parent | 26c4ea2ebcdcd0aa26350d04dc4cd38348148bd9 (diff) | |
download | gcc-7d6e5591e6ab1f5a24dcf007b17f81cc19987c47.zip gcc-7d6e5591e6ab1f5a24dcf007b17f81cc19987c47.tar.gz gcc-7d6e5591e6ab1f5a24dcf007b17f81cc19987c47.tar.bz2 |
d: Merge upstream dmd, druntime 603225372b
D front-end changes:
- Import dmd v2.111.0-beta.1.
- Added placement `new' expressions.
D runtime changes:
- Import druntime v2.111.0-beta.1.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 603225372b.
* dmd/VERSION: Bump version to v2.111.0-beta.1.
* d-builtins.cc (build_frontend_type): Update for new front-end
interface.
* decl.cc (Class DeclVisitor): Likewise.
(maybe_build_decl_tree): Likewise.
(get_vtable_decl): Likewise.
(layout_class_initializer): Likewise.
* expr.cc (class ExprVisitor): Likewise.
(ExprVisitor::visit (NewExp *)): Implement placement new for class,
struct, and pointer types.
* modules.cc (get_internal_fn): Update for new front-end interface.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 603225372b.
Diffstat (limited to 'gcc/d')
65 files changed, 1480 insertions, 1279 deletions
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc index f7e7a80..9c14645 100644 --- a/gcc/d/d-builtins.cc +++ b/gcc/d/d-builtins.cc @@ -279,7 +279,7 @@ build_frontend_type (tree type) NULL); vd->parent = sdecl; vd->offset = tree_to_uhwi (byte_position (field)); - vd->semanticRun = PASS::semanticdone; + vd->semanticRun (PASS::semanticdone); vd->csym = field; sdecl->members->push (vd); sdecl->fields.push (vd); diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index c05c303..9fcfc56 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -256,18 +256,18 @@ public: void visit (Module *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; build_module_tree (d); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Write the imported symbol to debug. */ void visit (Import *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; /* Implements import declarations by telling the debug back-end we are @@ -320,7 +320,7 @@ public: false, false); } - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Finish a top-level `asm` definition. */ @@ -472,7 +472,7 @@ public: void visit (StructDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (d->type->ty == TY::Terror) @@ -520,7 +520,7 @@ public: if (d->xhash) this->build_dsymbol (d->xhash); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Finish semantic analysis of functions in vtbl for class CD. */ @@ -542,7 +542,7 @@ public: has_errors = true; /* No name hiding to check for. */ - if (!d->isFuncHidden (fd) || fd->isFuture ()) + if (!dmd::isFuncHidden (d, fd) || fd->isFuture ()) continue; /* The function fd is hidden from the view of the class. @@ -588,7 +588,7 @@ public: void visit (ClassDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (d->type->ty == TY::Terror) @@ -617,7 +617,7 @@ public: /* Generate C symbols. */ d->csym = get_classinfo_decl (d); - Dsymbol *vtblsym = d->vtblSymbol (); + Dsymbol *vtblsym = dmd::vtblSymbol (d); vtblsym->csym = get_vtable_decl (d); tree sinit = aggregate_initializer_decl (d); @@ -654,7 +654,7 @@ public: = build_constructor (TREE_TYPE (vtblsym->csym), elms); d_finish_decl (vtblsym->csym); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Write out compiler generated TypeInfo and vtables for the given interface @@ -662,7 +662,7 @@ public: void visit (InterfaceDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (d->type->ty == TY::Terror) @@ -697,7 +697,7 @@ public: DECL_INITIAL (d->csym) = layout_classinfo (d); d_finish_decl (d->csym); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Write out compiler generated TypeInfo and initializer for the given @@ -705,10 +705,10 @@ public: void visit (EnumDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; - if (d->errors || d->type->ty == TY::Terror) + if (d->errors () || d->type->ty == TY::Terror) { error_at (make_location_t (d->loc), "had semantic errors when compiling"); @@ -736,7 +736,7 @@ public: d_finish_decl (d->sinit); } - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Finish up a variable declaration and push it into the current scope. @@ -744,7 +744,7 @@ public: void visit (VarDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (d->type->ty == TY::Terror) @@ -889,7 +889,7 @@ public: } } - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Generate and compile a static TypeInfo declaration, but only if it is @@ -897,7 +897,7 @@ public: void visit (TypeInfoDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (dmd::isSpeculativeType (d->tinfo)) @@ -906,7 +906,7 @@ public: tree t = get_typeinfo_decl (d); DECL_INITIAL (t) = layout_typeinfo (d); d_finish_decl (t); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Finish up a function declaration and compile it all the way @@ -915,7 +915,7 @@ public: void visit (FuncDeclaration *d) final override { /* Already generated the function. */ - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; /* Don't emit any symbols from gcc.attributes module. */ @@ -957,7 +957,7 @@ public: } /* Ensure all semantic passes have run. */ - if (d->semanticRun < PASS::semantic3) + if (d->semanticRun () < PASS::semantic3) { gcc_assert (!doing_semantic_analysis_p); @@ -971,8 +971,8 @@ public: return; /* Start generating code for this function. */ - gcc_assert (d->semanticRun == PASS::semantic3done); - d->semanticRun = PASS::obj; + gcc_assert (d->semanticRun () == PASS::semantic3done); + d->semanticRun (PASS::obj); /* Duplicated FuncDeclarations map to the same symbol. Check if this is the one declaration which will be emitted. */ @@ -1179,7 +1179,7 @@ maybe_build_decl_tree (Declaration *decl) /* Still running semantic analysis on declaration, or it has already had its code generated. */ - if (doing_semantic_analysis_p || decl->semanticRun >= PASS::obj) + if (doing_semantic_analysis_p || decl->semanticRun () >= PASS::obj) return decl->csym; if (error_operand_p (decl->csym)) @@ -2212,7 +2212,7 @@ get_vtable_decl (ClassDeclaration *decl) will have a different type. However the back-end seems to accept this. */ tree type = build_ctype (dmd::sarrayOf (Type::tvoidptr, decl->vtbl.length)); - Dsymbol *vtblsym = decl->vtblSymbol (); + Dsymbol *vtblsym = dmd::vtblSymbol (decl); vtblsym->csym = declare_extern_var (ident, type); DECL_LANG_SPECIFIC (vtblsym->csym) = build_lang_decl (NULL); @@ -2403,7 +2403,7 @@ aggregate_initializer_decl (AggregateDeclaration *decl) tree layout_class_initializer (ClassDeclaration *cd) { - NewExp *ne = NewExp::create (cd->loc, NULL, cd->type, NULL); + NewExp *ne = NewExp::create (cd->loc, NULL, NULL, cd->type, NULL); ne->type = cd->type; Expression *e = dmd::ctfeInterpret (ne); diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 66cfdd6..070d9fe 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -53a1cc8d13e8db2cb1642219320a8dfc1b0cc6c5 +603225372b211bb66dd0ea1a939043ace5a650cf The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 5aab7a2..2f668e5 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.110.0-rc.1 +v2.111.0-beta.1 diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d index a193876..4423653 100644 --- a/gcc/d/dmd/aggregate.d +++ b/gcc/d/dmd/aggregate.d @@ -96,7 +96,7 @@ struct MangleOverride extern (C++) abstract class AggregateDeclaration : ScopeDsymbol { Type type; /// - StorageClass storage_class; /// + STC storage_class; /// uint structsize; /// size of struct uint alignsize; /// size of struct for alignment purposes VarDeclarations fields; /// VarDeclaration fields including flattened AnonDeclaration members @@ -495,11 +495,6 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol // Back end void* sinit; /// initializer symbol - override final inout(AggregateDeclaration) isAggregateDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h index 56f597b..b742478 100644 --- a/gcc/d/dmd/aggregate.h +++ b/gcc/d/dmd/aggregate.h @@ -46,6 +46,8 @@ namespace dmd FuncDeclaration *search_toString(StructDeclaration *sd); void semanticTypeInfoMembers(StructDeclaration *sd); bool fill(StructDeclaration* sd, Loc loc, Expressions &elements, bool ctorinit); + bool isFuncHidden(ClassDeclaration* cd, FuncDeclaration* fd); + Dsymbol* vtblSymbol(ClassDeclaration *cd); } enum class ClassKind : uint8_t @@ -135,7 +137,6 @@ public: // Back end void *sinit; - AggregateDeclaration *isAggregateDeclaration() override final { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -191,7 +192,6 @@ public: bool requestTypeInfo() const; bool requestTypeInfo(bool v); - StructDeclaration *isStructDeclaration() override final { return this; } void accept(Visitor *v) override { v->visit(this); } unsigned numArgTypes() const; @@ -205,7 +205,6 @@ public: UnionDeclaration *syntaxCopy(Dsymbol *s) override; const char *kind() const override; - UnionDeclaration *isUnionDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -290,7 +289,6 @@ public: bool isBaseInfoComplete(); void finalizeSize() override; bool hasMonitor(); - bool isFuncHidden(FuncDeclaration *fd); bool isCOMclass() const; virtual bool isCOMinterface() const; bool isCPPclass() const; @@ -303,9 +301,7 @@ public: // Back end Dsymbol *vtblsym; - Dsymbol *vtblSymbol(); - ClassDeclaration *isClassDeclaration() override final { return (ClassDeclaration *)this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -320,6 +316,5 @@ public: bool isCPPinterface() const override; bool isCOMinterface() const override; - InterfaceDeclaration *isInterfaceDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/aliasthis.d b/gcc/d/dmd/aliasthis.d index 620b016..b5c0399 100644 --- a/gcc/d/dmd/aliasthis.d +++ b/gcc/d/dmd/aliasthis.d @@ -33,7 +33,7 @@ extern (C++) final class AliasThis : Dsymbol extern (D) this(Loc loc, Identifier ident) @safe { - super(loc, null); // it's anonymous (no identifier) + super(DSYM.aliasThis, loc, null); // it's anonymous (no identifier) this.ident = ident; } diff --git a/gcc/d/dmd/astenums.d b/gcc/d/dmd/astenums.d index 551b453..bbe1f9f 100644 --- a/gcc/d/dmd/astenums.d +++ b/gcc/d/dmd/astenums.d @@ -50,7 +50,7 @@ alias MOD = ubyte; enum STC : ulong // transfer changes to declaration.h { - undefined_ = 0, + none = 0, static_ = 1, /// `static` extern_ = 2, /// `extern` @@ -143,6 +143,9 @@ enum STC : ulong // transfer changes to declaration.h } +// Alias for C++ interface functions which use plain integer instead of enum class, +// since C++ enum class doesn't support | & and conversion to bool. Maybe this can +// be refactored to a struct with operator overloads or bit fields at some point. alias StorageClass = ulong; /******** diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d index df04ed1..80e8878 100644 --- a/gcc/d/dmd/attrib.d +++ b/gcc/d/dmd/attrib.d @@ -57,18 +57,19 @@ extern (C++) abstract class AttribDeclaration : Dsymbol extern (D) this(Dsymbols* decl) @safe { + super(DSYM.attribDeclaration); this.decl = decl; } extern (D) this(Loc loc, Dsymbols* decl) @safe { - super(loc, null); + super(DSYM.attribDeclaration, loc, null); this.decl = decl; } extern (D) this(Loc loc, Identifier ident, Dsymbols* decl) @safe { - super(loc, ident); + super(DSYM.attribDeclaration, loc, ident); this.decl = decl; } @@ -78,7 +79,7 @@ extern (C++) abstract class AttribDeclaration : Dsymbol * If the returned scope != sc, the caller should pop * the scope after it used. */ - extern (D) static Scope* createNewScope(Scope* sc, StorageClass stc, LINK linkage, + extern (D) static Scope* createNewScope(Scope* sc, STC stc, LINK linkage, CPPMANGLE cppmangle, Visibility visibility, int explicitVisibility, AlignDeclaration aligndecl, PragmaDeclaration inlining) { @@ -109,22 +110,11 @@ extern (C++) abstract class AttribDeclaration : Dsymbol return "attribute"; } - override bool oneMember(out Dsymbol ps, Identifier ident) - { - Dsymbols* d = this.include(null); - return Dsymbol.oneMembers(d, ps, ident); - } - override final bool hasPointers() { return this.include(null).foreachDsymbol( (s) { return s.hasPointers(); } ) != 0; } - override final bool hasStaticCtorOrDtor() - { - return this.include(null).foreachDsymbol( (s) { return s.hasStaticCtorOrDtor(); } ) != 0; - } - /**************************************** */ override final void addObjcSymbols(ClassDeclarations* classes, ClassDeclarations* categories) @@ -132,11 +122,6 @@ extern (C++) abstract class AttribDeclaration : Dsymbol objc.addSymbols(this, classes, categories); } - override inout(AttribDeclaration) isAttribDeclaration() inout pure @safe - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -150,18 +135,20 @@ extern (C++) abstract class AttribDeclaration : Dsymbol */ extern (C++) class StorageClassDeclaration : AttribDeclaration { - StorageClass stc; + STC stc; - extern (D) this(StorageClass stc, Dsymbols* decl) @safe + extern (D) this(STC stc, Dsymbols* decl) @safe { super(decl); this.stc = stc; + this.dsym = DSYM.storageClassDeclaration; } - extern (D) this(Loc loc, StorageClass stc, Dsymbols* decl) @safe + extern (D) this(Loc loc, STC stc, Dsymbols* decl) @safe { super(loc, decl); this.stc = stc; + this.dsym = DSYM.storageClassDeclaration; } override StorageClassDeclaration syntaxCopy(Dsymbol s) @@ -170,37 +157,6 @@ extern (C++) class StorageClassDeclaration : AttribDeclaration return new StorageClassDeclaration(stc, Dsymbol.arraySyntaxCopy(decl)); } - override final bool oneMember(out Dsymbol ps, Identifier ident) - { - bool t = Dsymbol.oneMembers(decl, ps, ident); - if (t && ps) - { - /* This is to deal with the following case: - * struct Tick { - * template to(T) { const T to() { ... } } - * } - * For eponymous function templates, the 'const' needs to get attached to 'to' - * before the semantic analysis of 'to', so that template overloading based on the - * 'this' pointer can be successful. - */ - if (FuncDeclaration fd = ps.isFuncDeclaration()) - { - /* Use storage_class2 instead of storage_class otherwise when we do .di generation - * we'll wind up with 'const const' rather than 'const'. - */ - /* Don't think we need to worry about mutually exclusive storage classes here - */ - fd.storage_class2 |= stc; - } - } - return t; - } - - override inout(StorageClassDeclaration) isStorageClassDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -253,6 +209,7 @@ extern (C++) final class LinkDeclaration : AttribDeclaration super(loc, null, decl); //printf("LinkDeclaration(linkage = %d, decl = %p)\n", linkage, decl); this.linkage = linkage; + this.dsym = DSYM.linkDeclaration; } static LinkDeclaration create(Loc loc, LINK p, Dsymbols* decl) @safe @@ -289,6 +246,7 @@ extern (C++) final class CPPMangleDeclaration : AttribDeclaration super(loc, null, decl); //printf("CPPMangleDeclaration(cppmangle = %d, decl = %p)\n", cppmangle, decl); this.cppmangle = cppmangle; + this.dsym = DSYM.cppMangleDeclaration; } override CPPMangleDeclaration syntaxCopy(Dsymbol s) @@ -334,11 +292,13 @@ extern (C++) final class CPPNamespaceDeclaration : AttribDeclaration extern (D) this(Loc loc, Identifier ident, Dsymbols* decl) @safe { super(loc, ident, decl); + this.dsym = DSYM.cppNamespaceDeclaration; } extern (D) this(Loc loc, Expression exp, Dsymbols* decl) @safe { super(loc, null, decl); + this.dsym = DSYM.cppNamespaceDeclaration; this.exp = exp; } @@ -346,6 +306,7 @@ extern (C++) final class CPPNamespaceDeclaration : AttribDeclaration CPPNamespaceDeclaration parent) @safe { super(loc, ident, decl); + this.dsym = DSYM.cppNamespaceDeclaration; this.exp = exp; this.cppnamespace = parent; } @@ -361,8 +322,6 @@ extern (C++) final class CPPNamespaceDeclaration : AttribDeclaration { v.visit(this); } - - override inout(CPPNamespaceDeclaration) isCPPNamespaceDeclaration() inout { return this; } } /*********************************************************** @@ -385,6 +344,7 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration extern (D) this(Loc loc, Visibility visibility, Dsymbols* decl) @safe { super(loc, null, decl); + this.dsym = DSYM.visibilityDeclaration; this.visibility = visibility; //printf("decl = %p\n", decl); } @@ -398,6 +358,7 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration extern (D) this(Loc loc, Identifier[] pkg_identifiers, Dsymbols* decl) { super(loc, null, decl); + this.dsym = DSYM.visibilityDeclaration; this.visibility.kind = Visibility.Kind.package_; this.pkg_identifiers = pkg_identifiers; if (pkg_identifiers.length > 0) @@ -431,11 +392,6 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration return buf.extractChars(); } - override inout(VisibilityDeclaration) isVisibilityDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -460,6 +416,7 @@ extern (C++) final class AlignDeclaration : AttribDeclaration extern (D) this(Loc loc, Expression exp, Dsymbols* decl) { super(loc, null, decl); + this.dsym = DSYM.alignDeclaration; if (exp) { exps = new Expressions(); @@ -470,12 +427,14 @@ extern (C++) final class AlignDeclaration : AttribDeclaration extern (D) this(Loc loc, Expressions* exps, Dsymbols* decl) @safe { super(loc, null, decl); + this.dsym = DSYM.alignDeclaration; this.exps = exps; } extern (D) this(Loc loc, structalign_t salign, Dsymbols* decl) @safe { super(loc, null, decl); + this.dsym = DSYM.alignDeclaration; this.salign = salign; } @@ -507,6 +466,7 @@ extern (C++) final class AnonDeclaration : AttribDeclaration extern (D) this(Loc loc, bool isunion, Dsymbols* decl) @safe { super(loc, null, decl); + this.dsym = DSYM.anonDeclaration; this.isunion = isunion; } @@ -521,11 +481,6 @@ extern (C++) final class AnonDeclaration : AttribDeclaration return (isunion ? "anonymous union" : "anonymous struct"); } - override inout(AnonDeclaration) isAnonDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -545,6 +500,7 @@ extern (C++) final class PragmaDeclaration : AttribDeclaration extern (D) this(Loc loc, Identifier ident, Expressions* args, Dsymbols* decl) @safe { super(loc, ident, decl); + this.dsym = DSYM.pragmaDeclaration; this.args = args; } @@ -580,6 +536,7 @@ extern (C++) class ConditionalDeclaration : AttribDeclaration extern (D) this(Loc loc, Condition condition, Dsymbols* decl, Dsymbols* elsedecl) @safe { super(loc, null, decl); + this.dsym = DSYM.conditionalDeclaration; //printf("ConditionalDeclaration::ConditionalDeclaration()\n"); this.condition = condition; this.elsedecl = elsedecl; @@ -591,22 +548,6 @@ extern (C++) class ConditionalDeclaration : AttribDeclaration return new ConditionalDeclaration(loc, condition.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl), Dsymbol.arraySyntaxCopy(elsedecl)); } - override final bool oneMember(out Dsymbol ps, Identifier ident) - { - //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition.inc); - if (condition.inc != Include.notComputed) - { - Dsymbols* d = condition.include(null) ? decl : elsedecl; - return Dsymbol.oneMembers(d, ps, ident); - } - else - { - bool res = (Dsymbol.oneMembers(decl, ps, ident) && ps is null && Dsymbol.oneMembers(elsedecl, ps, ident) && ps is null); - ps = null; - return res; - } - } - override void accept(Visitor v) { v.visit(this); @@ -627,6 +568,7 @@ extern (C++) final class StaticIfDeclaration : ConditionalDeclaration extern (D) this(Loc loc, Condition condition, Dsymbols* decl, Dsymbols* elsedecl) @safe { super(loc, condition, decl, elsedecl); + this.dsym = DSYM.staticIfDeclaration; //printf("StaticIfDeclaration::StaticIfDeclaration()\n"); } @@ -641,11 +583,6 @@ extern (C++) final class StaticIfDeclaration : ConditionalDeclaration return "static if"; } - override inout(StaticIfDeclaration) isStaticIfDeclaration() inout pure @safe - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -676,6 +613,7 @@ extern (C++) final class StaticForeachDeclaration : AttribDeclaration extern (D) this(StaticForeach sfe, Dsymbols* decl) @safe { super(sfe.loc, null, decl); + this.dsym = DSYM.staticForeachDeclaration; this.sfe = sfe; } @@ -687,21 +625,6 @@ extern (C++) final class StaticForeachDeclaration : AttribDeclaration Dsymbol.arraySyntaxCopy(decl)); } - override bool oneMember(out Dsymbol ps, Identifier ident) - { - // Required to support IFTI on a template that contains a - // `static foreach` declaration. `super.oneMember` calls - // include with a `null` scope. As `static foreach` requires - // the scope for expansion, `oneMember` can only return a - // precise result once `static foreach` has been expanded. - if (cached) - { - return super.oneMember(ps, ident); - } - ps = null; // a `static foreach` declaration may in general expand to multiple symbols - return false; - } - override const(char)* kind() const { return "static foreach"; @@ -746,16 +669,11 @@ extern(C++) final class ForwardingAttribDeclaration : AttribDeclaration this(Dsymbols* decl) @safe { super(decl); + this.dsym = DSYM.forwardingAttribDeclaration; sym = new ForwardingScopeDsymbol(); sym.symtab = new DsymbolTable(); } - - override inout(ForwardingAttribDeclaration) isForwardingAttribDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -778,6 +696,7 @@ extern (C++) final class MixinDeclaration : AttribDeclaration { super(loc, null, null); //printf("MixinDeclaration(loc = %d)\n", loc.linnum); + this.dsym = DSYM.mixinDeclaration; this.exps = exps; } @@ -792,11 +711,6 @@ extern (C++) final class MixinDeclaration : AttribDeclaration return "mixin"; } - override inout(MixinDeclaration) isMixinDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -815,6 +729,7 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration extern (D) this(Expressions* atts, Dsymbols* decl) @safe { super(decl); + this.dsym = DSYM.userAttributeDeclaration; this.atts = atts; } diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h index ab5f219..873c1bd 100644 --- a/gcc/d/dmd/attrib.h +++ b/gcc/d/dmd/attrib.h @@ -29,11 +29,7 @@ class AttribDeclaration : public Dsymbol public: Dsymbols *decl; // array of Dsymbol's const char *kind() const override; - bool oneMember(Dsymbol *&ps, Identifier *ident) override; bool hasPointers() override final; - bool hasStaticCtorOrDtor() override final; - AttribDeclaration *isAttribDeclaration() override { return this; } - void accept(Visitor *v) override { v->visit(this); } }; @@ -43,8 +39,6 @@ public: StorageClass stc; StorageClassDeclaration *syntaxCopy(Dsymbol *s) override; - bool oneMember(Dsymbol *&ps, Identifier *ident) override final; - StorageClassDeclaration *isStorageClassDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -96,7 +90,6 @@ public: VisibilityDeclaration *syntaxCopy(Dsymbol *s) override; const char *kind() const override; const char *toPrettyChars(bool unused) override; - VisibilityDeclaration *isVisibilityDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -121,7 +114,6 @@ public: AnonDeclaration *syntaxCopy(Dsymbol *s) override; const char *kind() const override; - AnonDeclaration *isAnonDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -142,7 +134,6 @@ public: Dsymbols *elsedecl; // array of Dsymbol's for else block ConditionalDeclaration *syntaxCopy(Dsymbol *s) override; - bool oneMember(Dsymbol *&ps, Identifier *ident) override final; void accept(Visitor *v) override { v->visit(this); } }; @@ -154,7 +145,6 @@ public: d_bool onStack; StaticIfDeclaration *syntaxCopy(Dsymbol *s) override; - StaticIfDeclaration *isStaticIfDeclaration() override { return this; } const char *kind() const override; void accept(Visitor *v) override { v->visit(this); } }; @@ -169,7 +159,6 @@ public: Dsymbols *cache; StaticForeachDeclaration *syntaxCopy(Dsymbol *s) override; - bool oneMember(Dsymbol *&ps, Identifier *ident) override; const char *kind() const override; void accept(Visitor *v) override { v->visit(this); } }; @@ -179,7 +168,6 @@ class ForwardingAttribDeclaration final : public AttribDeclaration public: ForwardingScopeDsymbol *sym; - ForwardingAttribDeclaration *isForwardingAttribDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index 93b6dc3..6454d73 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -51,11 +51,11 @@ import dmd.tokens; * Returns: * merged storage class */ -StorageClass mergeFuncAttrs(StorageClass s1, const FuncDeclaration f) pure @safe +STC mergeFuncAttrs(STC s1, const FuncDeclaration f) pure @safe { if (!f) return s1; - StorageClass s2 = (f.storage_class & STC.disable); + STC s2 = (f.storage_class & STC.disable); auto tf = f.type.isTypeFunction(); if (tf.trust == TRUST.safe) @@ -75,7 +75,7 @@ StorageClass mergeFuncAttrs(StorageClass s1, const FuncDeclaration f) pure @safe const sa = s1 & s2; const so = s1 | s2; - StorageClass stc = (sa & (STC.pure_ | STC.nothrow_ | STC.nogc)) | (so & STC.disable); + STC stc = (sa & (STC.pure_ | STC.nothrow_ | STC.nogc)) | (so & STC.disable); if (so & STC.system) stc |= STC.system; @@ -269,7 +269,7 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc) return null; //printf("StructDeclaration::buildOpAssign() %s\n", sd.toChars()); - StorageClass stc = STC.safe; + STC stc = STC.safe; Loc declLoc = sd.loc; Loc loc; // internal code should have no loc to prevent coverage @@ -387,7 +387,7 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc) sd.hasIdentityAssign = true; // temporary mark identity assignable const errors = global.startGagging(); // Do not report errors, even if the template opAssign fbody makes it. Scope* sc2 = sc.push(); - sc2.stc = 0; + sc2.stc = STC.none; sc2.linkage = LINK.d; fop.dsymbolSemantic(sc2); fop.semantic2(sc2); @@ -607,7 +607,7 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc) auto tf = new TypeFunction(ParameterList(parameters), Type.tbool, LINK.d, STC.const_); tf = tf.addSTC(STC.const_).toTypeFunction(); Identifier id = Id.xopEquals; - auto fop = new FuncDeclaration(declLoc, Loc.initial, id, 0, tf); + auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.none, tf); fop.isGenerated = true; fop.parent = sd; Expression e1 = new IdentifierExp(loc, Id.This); @@ -616,7 +616,7 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc) fop.fbody = new ReturnStatement(loc, e); const errors = global.startGagging(); // Do not report errors Scope* sc2 = sc.push(); - sc2.stc = 0; + sc2.stc = STC.none; sc2.linkage = LINK.d; fop.dsymbolSemantic(sc2); fop.semantic2(sc2); @@ -731,7 +731,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc) auto tf = new TypeFunction(ParameterList(parameters), Type.tint32, LINK.d, STC.const_); tf = tf.addSTC(STC.const_).toTypeFunction(); Identifier id = Id.xopCmp; - auto fop = new FuncDeclaration(declLoc, Loc.initial, id, 0, tf); + auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.none, tf); fop.isGenerated = true; fop.parent = sd; Expression e1 = new IdentifierExp(loc, Id.This); @@ -740,7 +740,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc) fop.fbody = new ReturnStatement(loc, e); const errors = global.startGagging(); // Do not report errors Scope* sc2 = sc.push(); - sc2.stc = 0; + sc2.stc = STC.none; sc2.linkage = LINK.d; fop.dsymbolSemantic(sc2); fop.semantic2(sc2); @@ -877,7 +877,7 @@ FuncDeclaration buildXtoHash(StructDeclaration sd, Scope* sc) "return h;"; fop.fbody = new MixinStatement(loc, new StringExp(loc, code)); Scope* sc2 = sc.push(); - sc2.stc = 0; + sc2.stc = STC.none; sc2.linkage = LINK.d; fop.dsymbolSemantic(sc2); fop.semantic2(sc2); @@ -905,7 +905,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc) if (ad.isUnionDeclaration()) return; // unions don't have destructors - StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc; + STC stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc; Loc declLoc = ad.userDtors.length ? ad.userDtors[0].loc : ad.loc; Loc loc; // internal code should have no loc to prevent coverage FuncDeclaration xdtor_fwd = null; @@ -1109,7 +1109,7 @@ private DtorDeclaration buildWindowsCppDtor(AggregateDeclaration ad, DtorDeclara // // TODO: if (del) delete (char*)this; // return (void*) this; // } - Parameter delparam = new Parameter(Loc.initial, STC.undefined_, Type.tuns32, Identifier.idPool("del"), new IntegerExp(dtor.loc, 0, Type.tuns32), null); + Parameter delparam = new Parameter(Loc.initial, STC.none, Type.tuns32, Identifier.idPool("del"), new IntegerExp(dtor.loc, 0, Type.tuns32), null); Parameters* params = new Parameters; params.push(delparam); const stc = dtor.storage_class & ~STC.scope_; // because we add the `return this;` later @@ -1224,8 +1224,8 @@ FuncDeclaration buildInv(AggregateDeclaration ad, Scope* sc) default: Expression e = null; - StorageClass stcx = 0; - StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc; + STC stcx = STC.none; + STC stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc; foreach (i, inv; ad.invs) { stc = mergeFuncAttrs(stc, inv); @@ -1234,7 +1234,7 @@ FuncDeclaration buildInv(AggregateDeclaration ad, Scope* sc) // What should do? } const stcy = (inv.storage_class & STC.synchronized_) | - (inv.type.mod & MODFlags.shared_ ? STC.shared_ : 0); + (inv.type.mod & MODFlags.shared_ ? STC.shared_ : STC.none); if (i == 0) stcx = stcy; else if (stcx ^ stcy) @@ -1278,7 +1278,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) const hasUserDefinedPosblit = sd.postblits.length && !sd.postblits[0].isDisabled ? true : false; // by default, the storage class of the created postblit - StorageClass stc = STC.safe; + STC stc = STC.safe; Loc declLoc = sd.postblits.length ? sd.postblits[0].loc : sd.loc; Loc loc; // internal code should have no loc to prevent coverage @@ -1559,11 +1559,11 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) * Returns: * The copy constructor declaration for struct `sd`. */ -private CtorDeclaration generateCtorDeclaration(StructDeclaration sd, const StorageClass paramStc, const StorageClass funcStc, bool move) +private CtorDeclaration generateCtorDeclaration(StructDeclaration sd, const STC paramStc, const STC funcStc, bool move) { auto fparams = new Parameters(); auto structType = sd.type; - StorageClass stc = move ? 0 : STC.ref_; // the only difference between copy or move + STC stc = move ? STC.none : STC.ref_; // the only difference between copy or move fparams.push(new Parameter(Loc.initial, paramStc | stc, structType, Id.p, null, null)); ParameterList pList = ParameterList(fparams); auto tf = new TypeFunction(pList, structType, LINK.d, STC.ref_); @@ -1773,7 +1773,7 @@ void buildCopyOrMoveCtor(StructDeclaration sd, Scope* sc, bool move) ccd.addMember(sc, sd); const errors = global.startGagging(); Scope* sc2 = sc.push(); - sc2.stc = 0; + sc2.stc = STC.none; sc2.linkage = LINK.d; ccd.dsymbolSemantic(sc2); ccd.semantic2(sc2); diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d index 48b73e4..80e4043 100644 --- a/gcc/d/dmd/cond.d +++ b/gcc/d/dmd/cond.d @@ -24,7 +24,7 @@ import dmd.dscope; import dmd.dsymbol; import dmd.errors; import dmd.expression; -import dmd.expressionsem : expressionSemantic, evalStaticCondition, resolveProperties; +import dmd.expressionsem : evalStaticCondition; import dmd.globals; import dmd.identifier; import dmd.location; @@ -145,51 +145,6 @@ extern (C++) final class StaticForeach : RootObject } /***************************************** - * Turn an aggregate which is an array into an expression tuple - * of its elements. I.e., lower - * static foreach (x; [1, 2, 3, 4]) { ... } - * to - * static foreach (x; AliasSeq!(1, 2, 3, 4)) { ... } - */ - private extern(D) void lowerArrayAggregate(Scope* sc) - { - auto aggr = aggrfe.aggr; - Expression el = new ArrayLengthExp(aggr.loc, aggr); - sc = sc.startCTFE(); - el = el.expressionSemantic(sc); - sc = sc.endCTFE(); - el = el.optimize(WANTvalue); - el = el.ctfeInterpret(); - if (el.op != EXP.int64) - { - aggrfe.aggr = ErrorExp.get(); - return; - } - - Expressions* es; - if (auto ale = aggr.isArrayLiteralExp()) - { - // Directly use the elements of the array for the TupleExp creation - es = ale.elements; - } - else - { - const length = cast(size_t)el.toInteger(); - es = new Expressions(length); - foreach (i; 0 .. length) - { - auto index = new IntegerExp(loc, i, Type.tsize_t); - auto value = new IndexExp(aggr.loc, aggr, index); - (*es)[i] = value; - } - } - aggrfe.aggr = new TupleExp(aggr.loc, es); - aggrfe.aggr = aggrfe.aggr.expressionSemantic(sc); - aggrfe.aggr = aggrfe.aggr.optimize(WANTvalue); - aggrfe.aggr = aggrfe.aggr.ctfeInterpret(); - } - - /***************************************** * Wrap a statement into a function literal and call it. * * Params: @@ -198,9 +153,9 @@ extern (C++) final class StaticForeach : RootObject * Returns: * AST of the expression `(){ s; }()` with location loc. */ - private extern(D) Expression wrapAndCall(Loc loc, Statement s) + extern(D) Expression wrapAndCall(Loc loc, Statement s) { - auto tf = new TypeFunction(ParameterList(), null, LINK.default_, 0); + auto tf = new TypeFunction(ParameterList(), null, LINK.default_, STC.none); auto fd = new FuncLiteralDeclaration(loc, loc, tf, TOK.reserved, null); fd.fbody = s; auto fe = new FuncExp(loc, fd); @@ -221,7 +176,7 @@ extern (C++) final class StaticForeach : RootObject * `foreach (parameters; lower .. upper) s;` * Where aggregate/lower, upper are as for the current StaticForeach. */ - private extern(D) Statement createForeach(Loc loc, Parameters* parameters, Statement s) + extern(D) Statement createForeach(Loc loc, Parameters* parameters, Statement s) { if (aggrfe) { @@ -254,7 +209,7 @@ extern (C++) final class StaticForeach : RootObject * } */ - private extern(D) TypeStruct createTupleType(Loc loc, Expressions* e, Scope* sc) + extern(D) TypeStruct createTupleType(Loc loc, Expressions* e, Scope* sc) { // TODO: move to druntime? auto sid = Identifier.generateId("Tuple"); auto sdecl = new StructDeclaration(loc, sid, false); @@ -262,7 +217,7 @@ extern (C++) final class StaticForeach : RootObject sdecl.members = new Dsymbols(); auto fid = Identifier.idPool(tupleFieldName); auto ty = new TypeTypeof(loc, new TupleExp(loc, e)); - sdecl.members.push(new VarDeclaration(loc, ty, fid, null, 0)); + sdecl.members.push(new VarDeclaration(loc, ty, fid, null, STC.none)); auto r = cast(TypeStruct)sdecl.type; if (global.params.useTypeInfo && Type.dtypeinfo) r.vtinfo = TypeInfoStructDeclaration.create(r); // prevent typeinfo from going to object file @@ -280,205 +235,11 @@ extern (C++) final class StaticForeach : RootObject * An AST for the expression `Tuple(e)`. */ - private extern(D) Expression createTuple(Loc loc, TypeStruct type, Expressions* e) @safe + extern(D) Expression createTuple(Loc loc, TypeStruct type, Expressions* e) @safe { // TODO: move to druntime? return new CallExp(loc, new TypeExp(loc, type), e); } - - /***************************************** - * Lower any aggregate that is not an array to an array using a - * regular foreach loop within CTFE. If there are multiple - * `static foreach` loop variables, an array of tuples is - * generated. In thise case, the field `needExpansion` is set to - * true to indicate that the static foreach loop expansion will - * need to expand the tuples into multiple variables. - * - * For example, `static foreach (x; range) { ... }` is lowered to: - * - * static foreach (x; { - * typeof({ - * foreach (x; range) return x; - * }())[] __res; - * foreach (x; range) __res ~= x; - * return __res; - * }()) { ... } - * - * Finally, call `lowerArrayAggregate` to turn the produced - * array into an expression tuple. - * - * Params: - * sc = The current scope. - */ - - private void lowerNonArrayAggregate(Scope* sc) - { - auto nvars = aggrfe ? aggrfe.parameters.length : 1; - auto aloc = aggrfe ? aggrfe.aggr.loc : rangefe.lwr.loc; - // We need three sets of foreach loop variables because the - // lowering contains three foreach loops. - Parameters*[3] pparams = [new Parameters(), new Parameters(), new Parameters()]; - foreach (i; 0 .. nvars) - { - foreach (params; pparams) - { - auto p = aggrfe ? (*aggrfe.parameters)[i] : rangefe.param; - params.push(new Parameter(aloc, p.storageClass, p.type, p.ident, null, null)); - } - } - Expression[2] res; - TypeStruct tplty = null; - if (nvars == 1) // only one `static foreach` variable, generate identifiers. - { - foreach (i; 0 .. 2) - { - res[i] = new IdentifierExp(aloc, (*pparams[i])[0].ident); - } - } - else // multiple `static foreach` variables, generate tuples. - { - foreach (i; 0 .. 2) - { - auto e = new Expressions(pparams[0].length); - foreach (j, ref elem; *e) - { - auto p = (*pparams[i])[j]; - elem = new IdentifierExp(aloc, p.ident); - } - if (!tplty) - { - tplty = createTupleType(aloc, e, sc); - } - res[i] = createTuple(aloc, tplty, e); - } - needExpansion = true; // need to expand the tuples later - } - // generate remaining code for the new aggregate which is an - // array (see documentation comment). - if (rangefe) - { - sc = sc.startCTFE(); - rangefe.lwr = rangefe.lwr.expressionSemantic(sc); - rangefe.lwr = resolveProperties(sc, rangefe.lwr); - rangefe.upr = rangefe.upr.expressionSemantic(sc); - rangefe.upr = resolveProperties(sc, rangefe.upr); - sc = sc.endCTFE(); - rangefe.lwr = rangefe.lwr.optimize(WANTvalue); - rangefe.lwr = rangefe.lwr.ctfeInterpret(); - rangefe.upr = rangefe.upr.optimize(WANTvalue); - rangefe.upr = rangefe.upr.ctfeInterpret(); - } - auto s1 = new Statements(); - auto sfe = new Statements(); - if (tplty) sfe.push(new ExpStatement(loc, tplty.sym)); - sfe.push(new ReturnStatement(aloc, res[0])); - s1.push(createForeach(aloc, pparams[0], new CompoundStatement(aloc, sfe))); - s1.push(new ExpStatement(aloc, new AssertExp(aloc, IntegerExp.literal!0))); - Type ety = new TypeTypeof(aloc, wrapAndCall(aloc, new CompoundStatement(aloc, s1))); - auto aty = ety.arrayOf(); - auto idres = Identifier.generateId("__res"); - auto vard = new VarDeclaration(aloc, aty, idres, null, STC.temp); - auto s2 = new Statements(); - - // Run 'typeof' gagged to avoid duplicate errors and if it fails just create - // an empty foreach to expose them. - const olderrors = global.startGagging(); - ety = ety.typeSemantic(aloc, sc); - if (global.endGagging(olderrors)) - s2.push(createForeach(aloc, pparams[1], null)); - else - { - s2.push(new ExpStatement(aloc, vard)); - auto catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]); - s2.push(createForeach(aloc, pparams[1], new ExpStatement(aloc, catass))); - s2.push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres))); - } - - Expression aggr = void; - Type indexty = void; - - if (rangefe && (indexty = ety).isIntegral()) - { - rangefe.lwr.type = indexty; - rangefe.upr.type = indexty; - auto lwrRange = getIntRange(rangefe.lwr); - auto uprRange = getIntRange(rangefe.upr); - - const lwr = rangefe.lwr.toInteger(); - auto upr = rangefe.upr.toInteger(); - size_t length = 0; - - if (lwrRange.imin <= uprRange.imax) - length = cast(size_t) (upr - lwr); - - auto exps = new Expressions(length); - - if (rangefe.op == TOK.foreach_) - { - foreach (i; 0 .. length) - (*exps)[i] = new IntegerExp(aloc, lwr + i, indexty); - } - else - { - --upr; - foreach (i; 0 .. length) - (*exps)[i] = new IntegerExp(aloc, upr - i, indexty); - } - aggr = new ArrayLiteralExp(aloc, indexty.arrayOf(), exps); - } - else - { - aggr = wrapAndCall(aloc, new CompoundStatement(aloc, s2)); - sc = sc.startCTFE(); - aggr = aggr.expressionSemantic(sc); - aggr = resolveProperties(sc, aggr); - sc = sc.endCTFE(); - aggr = aggr.optimize(WANTvalue); - aggr = aggr.ctfeInterpret(); - } - - assert(!!aggrfe ^ !!rangefe); - aggrfe = new ForeachStatement(loc, TOK.foreach_, pparams[2], aggr, - aggrfe ? aggrfe._body : rangefe._body, - aggrfe ? aggrfe.endloc : rangefe.endloc); - rangefe = null; - lowerArrayAggregate(sc); // finally, turn generated array into expression tuple - } - - /***************************************** - * Perform `static foreach` lowerings that are necessary in order - * to finally expand the `static foreach` using - * `dmd.statementsem.makeTupleForeach`. - */ - extern(D) void prepare(Scope* sc) - { - assert(sc); - - if (aggrfe) - { - sc = sc.startCTFE(); - aggrfe.aggr = aggrfe.aggr.expressionSemantic(sc); - sc = sc.endCTFE(); - } - - if (aggrfe && aggrfe.aggr.type.toBasetype().ty == Terror) - { - return; - } - - if (!ready()) - { - if (aggrfe && aggrfe.aggr.type.toBasetype().ty == Tarray) - { - lowerArrayAggregate(sc); - } - else - { - lowerNonArrayAggregate(sc); - } - } - } - /***************************************** * Returns: * `true` iff ready to call `dmd.statementsem.makeTupleForeach`. diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h index ec68d19..191164f 100644 --- a/gcc/d/dmd/cond.h +++ b/gcc/d/dmd/cond.h @@ -71,7 +71,6 @@ public: static void addGlobalIdent(const char *ident); int include(Scope *sc) override; - DebugCondition *isDebugCondition() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -82,7 +81,6 @@ public: static void addPredefinedGlobalIdent(const char *ident); int include(Scope *sc) override; - VersionCondition *isVersionCondition() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 9f1eab7..3efda07 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -1445,8 +1445,10 @@ final class CParser(AST) : Parser!AST auto e = cparseOrExp(); while (token.value == TOK.andAnd) { + e = new AST.CastExp(loc, e, AST.Type.tbool); nextToken(); auto e2 = cparseOrExp(); + e2 = new AST.CastExp(loc, e2, AST.Type.tbool); e = new AST.LogicalExp(loc, EXP.andAnd, e, e2); } return e; @@ -1465,8 +1467,10 @@ final class CParser(AST) : Parser!AST auto e = cparseAndAndExp(); while (token.value == TOK.orOr) { + e = new AST.CastExp(loc, e, AST.Type.tbool); nextToken(); auto e2 = cparseAndAndExp(); + e2 = new AST.CastExp(loc, e2, AST.Type.tbool); e = new AST.LogicalExp(loc, EXP.orOr, e, e2); } return e; @@ -1686,7 +1690,7 @@ final class CParser(AST) : Parser!AST private AST.Expression cparseStatementExpression() { AST.ParameterList parameterList; - StorageClass stc = 0; + STC stc = STC.none; const loc = token.loc; auto symbolsSave = symbols; symbols = new AST.Dsymbols(); @@ -1710,7 +1714,7 @@ final class CParser(AST) : Parser!AST } auto tf = new AST.TypeFunction(parameterList, null, LINK.d, stc); - auto fd = new AST.FuncLiteralDeclaration(loc, token.loc, tf, TOK.delegate_, null, null, 0); + auto fd = new AST.FuncLiteralDeclaration(loc, token.loc, tf, TOK.delegate_, null, null, STC.none); fd.fbody = fbody; auto fe = new AST.FuncExp(loc, fd); @@ -2046,7 +2050,7 @@ final class CParser(AST) : Parser!AST error("no initializer for function declaration"); if (specifier.scw & SCW.x_Thread_local) error("functions cannot be `_Thread_local`"); // C11 6.7.1-4 - StorageClass stc = specifiersToSTC(level, specifier); + STC stc = specifiersToSTC(level, specifier); stc &= ~STC.gshared; // no gshared functions auto fd = new AST.FuncDeclaration(token.loc, Loc.initial, id, stc, dt, specifier.noreturn); specifiersToFuncDeclaration(fd, specifier); @@ -2233,7 +2237,7 @@ final class CParser(AST) : Parser!AST auto body = cparseStatement(ParseStatementFlags.curly); // don't start a new scope; continue with parameter scope typedefTab.pop(); // end of function scope - StorageClass stc = specifiersToSTC(LVL.global, specifier); + STC stc = specifiersToSTC(LVL.global, specifier); stc &= ~STC.gshared; // no gshared functions auto fd = new AST.FuncDeclaration(locFunc, prevloc, id, stc, ft, specifier.noreturn); specifiersToFuncDeclaration(fd, specifier); @@ -3018,7 +3022,7 @@ final class CParser(AST) : Parser!AST auto parameterList = cparseParameterList(); const lkg = specifier.mod & MOD.x__stdcall ? LINK.windows : linkage; - StorageClass stc = specifier._nothrow ? STC.nothrow_ : 0; + STC stc = specifier._nothrow ? STC.nothrow_ : STC.none; if (specifier._pure) stc |= STC.pure_; stc |= defaultStorageClasses; @@ -3174,7 +3178,7 @@ final class CParser(AST) : Parser!AST { auto parameters = new AST.Parameters(); AST.VarArg varargs = AST.VarArg.none; - StorageClass varargsStc; + STC varargsStc; check(TOK.leftParenthesis); if (token.value == TOK.void_ && peekNext() == TOK.rightParenthesis) // func(void) @@ -3537,7 +3541,7 @@ final class CParser(AST) : Parser!AST break; } nextToken(); - auto s = new AST.CompoundAsmStatement(loc, statements, 0); + auto s = new AST.CompoundAsmStatement(loc, statements, STC.none); return s; } @@ -3922,7 +3926,7 @@ final class CParser(AST) : Parser!AST cparseGnuAttributes(specifierx); } - auto em = new AST.EnumMember(mloc, ident, value, null, 0, null, null); + auto em = new AST.EnumMember(mloc, ident, value, null, STC.none, null, null); members.push(em); if (token.value == TOK.comma) @@ -5162,9 +5166,9 @@ final class CParser(AST) : Parser!AST * Returns: * corresponding D storage class */ - StorageClass specifiersToSTC(LVL level, const ref Specifier specifier) + STC specifiersToSTC(LVL level, const ref Specifier specifier) { - StorageClass stc; + STC stc; if (specifier.scw & SCW.x_Thread_local) { if (level == LVL.global) @@ -6205,8 +6209,8 @@ final class CParser(AST) : Parser!AST if (token.value != TOK.endOfFile) break; auto ret = new AST.ReturnStatement(exp.loc, exp); - auto parameterList = AST.ParameterList(new AST.Parameters(), VarArg.none, 0); - StorageClass stc = STC.auto_; + auto parameterList = AST.ParameterList(new AST.Parameters(), VarArg.none, STC.none); + STC stc = STC.auto_; auto tf = new AST.TypeFunction(parameterList, null, LINK.d, stc); auto fd = new AST.FuncDeclaration(exp.loc, exp.loc, id, stc, tf, 0); fd.fbody = ret; @@ -6251,7 +6255,7 @@ final class CParser(AST) : Parser!AST if (token.value != TOK.identifier) break Lswitch; - auto param = new AST.Parameter(token.loc, 0, null, token.ident, null, null); + auto param = new AST.Parameter(token.loc, STC.none, null, token.ident, null, null); parameters.push(param); nextToken(); if (token.value == TOK.comma) @@ -6266,7 +6270,7 @@ final class CParser(AST) : Parser!AST //auto pstart = p; nextToken(); - auto parameterList = AST.ParameterList(parameters, varargs, 0); + auto parameterList = AST.ParameterList(parameters, varargs, STC.none); /* Create a type for each parameter. Add it to the template parameter list, * and the parameter list. */ @@ -6297,7 +6301,7 @@ final class CParser(AST) : Parser!AST // Generate function auto ret = new AST.ReturnStatement(exp.loc, exp); - StorageClass stc = STC.auto_; + STC stc = STC.auto_; auto tf = new AST.TypeFunction(parameterList, null, LINK.d, stc); auto fd = new AST.FuncDeclaration(exp.loc, exp.loc, id, stc, tf, 0); fd.fbody = ret; diff --git a/gcc/d/dmd/cxxfrontend.d b/gcc/d/dmd/cxxfrontend.d index 3cd4ced..ecf3399 100644 --- a/gcc/d/dmd/cxxfrontend.d +++ b/gcc/d/dmd/cxxfrontend.d @@ -15,6 +15,7 @@ import dmd.arraytypes; import dmd.astenums; import dmd.attrib; import dmd.common.outbuffer : OutBuffer; +import dmd.dclass : ClassDeclaration; import dmd.declaration : TypeInfoDeclaration; import dmd.denum : EnumDeclaration; import dmd.dmodule /*: Module*/; @@ -179,6 +180,18 @@ Dsymbols* include(Dsymbol d, Scope* sc) return dmd.dsymbolsem.include(d, sc); } +bool isFuncHidden(ClassDeclaration cd, FuncDeclaration fd) +{ + import dmd.dsymbolsem; + return dmd.dsymbolsem.isFuncHidden(cd, fd); +} + +Dsymbol vtblSymbol(ClassDeclaration cd) +{ + import dmd.dsymbolsem; + return dmd.dsymbolsem.vtblSymbol(cd); +} + /*********************************************************** * dtemplate.d */ @@ -265,6 +278,19 @@ bool fill(StructDeclaration sd, Loc loc, } /*********************************************************** + * func.d + */ +FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = STC.none) +{ + return FuncDeclaration.genCfunc(fparams, treturn, name, cast(STC) stc); +} + +FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, StorageClass stc = STC.none) +{ + return FuncDeclaration.genCfunc(fparams, treturn, id, cast(STC) stc); +} + +/*********************************************************** * funcsem.d */ bool functionSemantic(FuncDeclaration fd) @@ -511,7 +537,7 @@ Covariant covariant(Type src, Type t, StorageClass* pstc = null, bool cppCovariant = false) { import dmd.typesem; - return dmd.typesem.covariant(src, t, pstc, cppCovariant); + return dmd.typesem.covariant(src, t, cast(STC*) pstc, cppCovariant); } bool isZeroInit(Type t, Loc loc) @@ -643,7 +669,7 @@ Type addMod(Type type, MOD mod) Type addStorageClass(Type type, StorageClass stc) { import dmd.typesem; - return dmd.typesem.addStorageClass(type, stc); + return dmd.typesem.addStorageClass(type, cast(STC) stc); } Type pointerTo(Type type) diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 172c827..21ddd75 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -704,6 +704,12 @@ MATCH implicitConvTo(Expression e, Type t) if (!tn.isConst() && !tn.isImmutable()) return MATCH.nomatch; m = MATCH.constant; + + // After converting e.g. ubyte[] to const(ubyte)[], don't change + // to MATCH.convert, return MATCH.constant + // https://github.com/dlang/dmd/issues/20635 + if (e.type.ty == t.ty && e.type.nextOf().ty == tn.ty) + return m; } if (e.type != t && e.hexString && tn.isIntegral && (tn.size == e.sz || (!e.committed && (e.len % tn.size) == 0))) { diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d index b59c520..b21ec00 100644 --- a/gcc/d/dmd/dclass.d +++ b/gcc/d/dmd/dclass.d @@ -23,7 +23,7 @@ import dmd.gluelayer; import dmd.declaration; import dmd.dscope; import dmd.dsymbol; -import dmd.dsymbolsem : dsymbolSemantic, addMember, search, setFieldOffset; +import dmd.dsymbolsem : dsymbolSemantic, addMember, setFieldOffset; import dmd.errors; import dmd.func; import dmd.id; @@ -206,6 +206,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration id = Identifier.generateAnonymousId("class"); super(loc, id); + this.dsym = DSYM.classDeclaration; static immutable msg = "only object.d can define this reserved class name"; @@ -613,40 +614,6 @@ extern (C++) class ClassDeclaration : AggregateDeclaration return classKind == ClassKind.d; } - final bool isFuncHidden(FuncDeclaration fd) - { - import dmd.funcsem : overloadApply; - //printf("ClassDeclaration.isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toPrettyChars()); - Dsymbol s = this.search(Loc.initial, fd.ident, SearchOpt.ignoreAmbiguous | SearchOpt.ignoreErrors); - if (!s) - { - //printf("not found\n"); - /* Because, due to a hack, if there are multiple definitions - * of fd.ident, NULL is returned. - */ - return false; - } - s = s.toAlias(); - if (auto os = s.isOverloadSet()) - { - foreach (sm; os.a) - { - auto fm = sm.isFuncDeclaration(); - if (overloadApply(fm, s => fd == s.isFuncDeclaration())) - return false; - } - return true; - } - else - { - auto f = s.isFuncDeclaration(); - //printf("%s fdstart = %p\n", s.kind(), fdstart); - if (overloadApply(f, s => fd == s.isFuncDeclaration())) - return false; - return !fd.parent.isTemplateMixin(); - } - } - /**************** * Find virtual function matching identifier and type. * Used to build virtual function tables for interface implementations. @@ -921,31 +888,11 @@ extern (C++) class ClassDeclaration : AggregateDeclaration // Back end Dsymbol vtblsym; - final Dsymbol vtblSymbol() - { - if (!vtblsym) - { - auto vtype = Type.tvoidptr.immutableOf().sarrayOf(vtbl.length); - auto var = new VarDeclaration(loc, vtype, Identifier.idPool("__vtbl"), null, STC.immutable_ | STC.static_); - var.addMember(null, this); - var.isdataseg = 1; - var._linkage = LINK.d; - var.semanticRun = PASS.semanticdone; // no more semantic wanted - vtblsym = var; - } - return vtblsym; - } - extern (D) final bool isErrorException() { return errorException && (this == errorException || errorException.isBaseOf(this, null)); } - override final inout(ClassDeclaration) isClassDeclaration() inout @nogc nothrow pure @safe - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -959,6 +906,7 @@ extern (C++) final class InterfaceDeclaration : ClassDeclaration extern (D) this(Loc loc, Identifier id, BaseClasses* baseclasses) { super(loc, id, baseclasses, null, false); + this.dsym = DSYM.interfaceDeclaration; if (id == Id.IUnknown) // IUnknown is the root of all COM interfaces { com = true; @@ -1058,11 +1006,6 @@ extern (C++) final class InterfaceDeclaration : ClassDeclaration return com; } - override inout(InterfaceDeclaration) isInterfaceDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index 30f017d..870401b 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -87,7 +87,7 @@ extern (C++) abstract class Declaration : Dsymbol { Type type; Type originalType; // before semantic analysis - StorageClass storage_class = STC.undefined_; + STC storage_class = STC.none; // overridden symbol with pragma(mangle, "...") const(char)[] mangleOverride; Visibility visibility; @@ -106,15 +106,15 @@ extern (C++) abstract class Declaration : Dsymbol import dmd.common.bitfields; mixin(generateBitFields!(BitFields, ubyte)); - final extern (D) this(Identifier ident) @safe + final extern (D) this(DSYM tag, Identifier ident) @safe { - super(ident); + super(tag, ident); visibility = Visibility(Visibility.Kind.undefined); } - final extern (D) this(Loc loc, Identifier ident) @safe + final extern (D) this(DSYM tag, Loc loc, Identifier ident) @safe { - super(loc, ident); + super(tag, loc, ident); visibility = Visibility(Visibility.Kind.undefined); } @@ -274,11 +274,6 @@ extern (C++) abstract class Declaration : Dsymbol return visibility; } - override final inout(Declaration) isDeclaration() inout pure nothrow @nogc @safe - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -296,7 +291,7 @@ extern (C++) final class TupleDeclaration : Declaration extern (D) this(Loc loc, Identifier ident, Objects* objects) @safe { - super(loc, ident); + super(DSYM.tupleDeclaration, loc, ident); this.objects = objects; } @@ -350,7 +345,7 @@ extern (C++) final class TupleDeclaration : Declaration } else { - auto arg = new Parameter(Loc.initial, 0, t, null, null, null); + auto arg = new Parameter(Loc.initial, STC.none, t, null, null, null); } (*args)[i] = arg; if (!t.deco) @@ -424,11 +419,6 @@ extern (C++) final class TupleDeclaration : Declaration return 0; } - override inout(TupleDeclaration) isTupleDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -447,7 +437,7 @@ extern (C++) final class AliasDeclaration : Declaration extern (D) this(Loc loc, Identifier ident, Type type) @safe { - super(loc, ident); + super(DSYM.aliasDeclaration, loc, ident); //debug printf("AliasDeclaration(id = '%s', type = `%s`, %p)\n", ident.toChars(), dmd.hdrgen.toChars(type), type.isTypeIdentifier()); this.type = type; assert(type); @@ -455,7 +445,7 @@ extern (C++) final class AliasDeclaration : Declaration extern (D) this(Loc loc, Identifier ident, Dsymbol s) @safe { - super(loc, ident); + super(DSYM.aliasDeclaration, loc, ident); //debug printf("AliasDeclaration(id = '%s', s = `%s`)\n", ident.toChars(), s.toChars()); assert(s != this); this.aliassym = s; @@ -732,11 +722,6 @@ extern (C++) final class AliasDeclaration : Declaration aliassym && aliassym.isOverloadable(); } - override inout(AliasDeclaration) isAliasDeclaration() inout - { - return this; - } - /** Returns: `true` if this instance was created to make a template parameter visible in the scope of a template body, `false` otherwise */ extern (D) bool isAliasedTemplateParameter() const @@ -759,7 +744,7 @@ extern (C++) final class OverDeclaration : Declaration extern (D) this(Identifier ident, Dsymbol s) @safe { - super(ident); + super(DSYM.overDeclaration, ident); this.aliassym = s; } @@ -817,11 +802,6 @@ extern (C++) final class OverDeclaration : Declaration return result; } - override inout(OverDeclaration) isOverDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -887,7 +867,7 @@ extern (C++) class VarDeclaration : Declaration byte canassign; // it can be assigned to ubyte isdataseg; // private data for isDataseg 0 unset, 1 true, 2 false - final extern (D) this(Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.undefined_) + final extern (D) this(Loc loc, Type type, Identifier ident, Initializer _init, STC storage_class = STC.none) in { assert(ident); @@ -895,7 +875,7 @@ extern (C++) class VarDeclaration : Declaration do { //printf("VarDeclaration('%s')\n", ident.toChars()); - super(loc, ident); + super(DSYM.varDeclaration, loc, ident); debug { if (!type && !_init) @@ -912,9 +892,9 @@ extern (C++) class VarDeclaration : Declaration this.storage_class = storage_class; } - static VarDeclaration create(Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.undefined_) + static VarDeclaration create(Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.none) { - return new VarDeclaration(loc, type, ident, _init, storage_class); + return new VarDeclaration(loc, type, ident, _init, cast(STC) storage_class); } override VarDeclaration syntaxCopy(Dsymbol s) @@ -1217,12 +1197,6 @@ extern (C++) class VarDeclaration : Declaration return s; } - // Eliminate need for dynamic_cast - override final inout(VarDeclaration) isVarDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1242,7 +1216,7 @@ extern (C++) class BitFieldDeclaration : VarDeclaration final extern (D) this(Loc loc, Type type, Identifier ident, Expression width) { super(loc, type, ident, null); - + this.dsym = DSYM.bitFieldDeclaration; this.width = width; this.storage_class |= STC.field; } @@ -1256,11 +1230,6 @@ extern (C++) class BitFieldDeclaration : VarDeclaration return bf; } - override final inout(BitFieldDeclaration) isBitFieldDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1302,17 +1271,11 @@ extern (C++) final class SymbolDeclaration : Declaration extern (D) this(Loc loc, AggregateDeclaration dsym) @safe { - super(loc, dsym.ident); + super(DSYM.symbolDeclaration, loc, dsym.ident); this.dsym = dsym; storage_class |= STC.const_; } - // Eliminate need for dynamic_cast - override inout(SymbolDeclaration) isSymbolDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1357,6 +1320,7 @@ extern (C++) class TypeInfoDeclaration : VarDeclaration final extern (D) this(Type tinfo) { super(Loc.initial, Type.dtypeinfo.type, tinfo.getTypeInfoIdent(), null); + this.dsym = DSYM.typeInfoDeclaration; this.tinfo = tinfo; storage_class = STC.static_ | STC.gshared; visibility = Visibility(Visibility.Kind.public_); @@ -1374,11 +1338,6 @@ extern (C++) class TypeInfoDeclaration : VarDeclaration assert(0); // should never be produced by syntax } - override final inout(TypeInfoDeclaration) isTypeInfoDeclaration() inout @nogc nothrow pure @safe - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1795,6 +1754,7 @@ extern (C++) final class ThisDeclaration : VarDeclaration extern (D) this(Loc loc, Type t) { super(loc, t, Id.This, null); + this.dsym = DSYM.thisDeclaration; storage_class |= STC.nodtor; } @@ -1803,11 +1763,6 @@ extern (C++) final class ThisDeclaration : VarDeclaration assert(0); // should never be produced by syntax } - override inout(ThisDeclaration) isThisDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 6fef6a5..4d23d86 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -37,6 +37,8 @@ namespace dmd bool checkClosure(FuncDeclaration* fd); MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, Identifiers *names); PURE isPure(FuncDeclaration *f); + FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0); + FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0); } //enum STC : ulong from astenums.d: @@ -160,7 +162,6 @@ public: Visibility visible() override final; - Declaration *isDeclaration() override final { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -180,7 +181,6 @@ public: Dsymbol *toAlias2() override; bool needThis() override; - TupleDeclaration *isTupleDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -202,7 +202,6 @@ public: Dsymbol *toAlias2() override; bool isOverloadable() const override; - AliasDeclaration *isAliasDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -222,7 +221,6 @@ public: Dsymbol *isUnique(); bool isOverloadable() const override; - OverDeclaration *isOverDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -300,7 +298,6 @@ public: bool needsScopeDtor(); Dsymbol *toAlias() override final; // Eliminate need for dynamic_cast - VarDeclaration *isVarDeclaration() override final { return (VarDeclaration *)this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -315,7 +312,6 @@ public: unsigned bitOffset; BitFieldDeclaration *syntaxCopy(Dsymbol *) override; - BitFieldDeclaration *isBitFieldDeclaration() override final { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -329,7 +325,6 @@ public: AggregateDeclaration *dsym; // Eliminate need for dynamic_cast - SymbolDeclaration *isSymbolDeclaration() override { return (SymbolDeclaration *)this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -341,7 +336,6 @@ public: static TypeInfoDeclaration *create(Type *tinfo); TypeInfoDeclaration *syntaxCopy(Dsymbol *) override final; - TypeInfoDeclaration *isTypeInfoDeclaration() override final { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -481,7 +475,6 @@ class ThisDeclaration final : public VarDeclaration { public: ThisDeclaration *syntaxCopy(Dsymbol *) override; - ThisDeclaration *isThisDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -735,11 +728,6 @@ public: bool hasNestedFrameRefs(); ParameterList getParameterList(); - static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0); - static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0); - - FuncDeclaration *isFuncDeclaration() override final { return this; } - virtual FuncDeclaration *toAliasFunc() { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -750,7 +738,6 @@ public: FuncDeclaration *funcalias; d_bool hasOverloads; - FuncAliasDeclaration *isFuncAliasDeclaration() override { return this; } const char *kind() const override; FuncDeclaration *toAliasFunc() override; @@ -773,7 +760,6 @@ public: bool addPreInvariant() override; bool addPostInvariant() override; - FuncLiteralDeclaration *isFuncLiteralDeclaration() override { return this; } const char *kind() const override; const char *toPrettyChars(bool QualifyTypes = false) override; void accept(Visitor *v) override { v->visit(this); } @@ -790,7 +776,6 @@ public: bool addPreInvariant() override; bool addPostInvariant() override; - CtorDeclaration *isCtorDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -803,7 +788,6 @@ public: bool addPostInvariant() override; bool overloadInsert(Dsymbol *s) override; - PostBlitDeclaration *isPostBlitDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -817,7 +801,6 @@ public: bool addPostInvariant() override; bool overloadInsert(Dsymbol *s) override; - DtorDeclaration *isDtorDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -829,9 +812,7 @@ public: bool isVirtual() const override final; bool addPreInvariant() override final; bool addPostInvariant() override final; - bool hasStaticCtorOrDtor() override final; - StaticCtorDeclaration *isStaticCtorDeclaration() override final { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -841,7 +822,6 @@ public: bool standalone; SharedStaticCtorDeclaration *syntaxCopy(Dsymbol *) override; - SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -853,11 +833,9 @@ public: StaticDtorDeclaration *syntaxCopy(Dsymbol *) override; AggregateDeclaration *isThis() override final; bool isVirtual() const override final; - bool hasStaticCtorOrDtor() override final; bool addPreInvariant() override final; bool addPostInvariant() override final; - StaticDtorDeclaration *isStaticDtorDeclaration() override final { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -866,7 +844,6 @@ class SharedStaticDtorDeclaration final : public StaticDtorDeclaration public: SharedStaticDtorDeclaration *syntaxCopy(Dsymbol *) override; - SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -878,7 +855,6 @@ public: bool addPreInvariant() override; bool addPostInvariant() override; - InvariantDeclaration *isInvariantDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -896,7 +872,6 @@ public: bool addPreInvariant() override; bool addPostInvariant() override; - UnitTestDeclaration *isUnitTestDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -909,6 +884,5 @@ public: bool addPreInvariant() override; bool addPostInvariant() override; - NewDeclaration *isNewDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d index a650425..e85e24a 100644 --- a/gcc/d/dmd/denum.d +++ b/gcc/d/dmd/denum.d @@ -70,6 +70,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol //printf("EnumDeclaration() %p %s : %s\n", this, toChars(), memtype.toChars()); type = new TypeEnum(this); this.memtype = memtype; + this.dsym = DSYM.enumDeclaration; visibility = Visibility(Visibility.Kind.undefined); } @@ -81,13 +82,6 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol return ed; } - override bool oneMember(out Dsymbol ps, Identifier ident) - { - if (isAnonymous()) - return Dsymbol.oneMembers(members, ps, ident); - return Dsymbol.oneMember(ps, ident); - } - override Type getType() { return type; @@ -120,11 +114,6 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol return isSpecialEnumIdent(ident) && memtype; } - override inout(EnumDeclaration) isEnumDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -159,10 +148,11 @@ extern (C++) final class EnumMember : VarDeclaration super(loc, null, id ? id : Id.empty, new ExpInitializer(loc, value)); this.origValue = value; this.origType = origType; + this.dsym = DSYM.enumMember; } extern(D) this(Loc loc, Identifier id, Expression value, Type memtype, - StorageClass stc, UserAttributeDeclaration uad, DeprecatedDeclaration dd) + STC stc, UserAttributeDeclaration uad, DeprecatedDeclaration dd) { this(loc, id, value, memtype); storage_class = stc; @@ -187,11 +177,6 @@ extern (C++) final class EnumMember : VarDeclaration return "enum member"; } - override inout(EnumMember) isEnumMember() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d index 8a2c271..1f48e33 100644 --- a/gcc/d/dmd/dimport.d +++ b/gcc/d/dmd/dimport.d @@ -59,7 +59,7 @@ extern (C++) final class Import : Dsymbol return id; } - super(loc, selectIdent()); + super(DSYM.import_, loc, selectIdent()); assert(id); version (none) @@ -161,11 +161,6 @@ extern (C++) final class Import : Dsymbol return imp && !imp.aliasId; } - override inout(Import) isImport() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index 3a08c10..4beee42 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -2796,6 +2796,13 @@ public: printf("%s NewExp::interpret() %s\n", e.loc.toChars(), e.toChars()); } + if (e.placement) + { + error(e.placement.loc, "`new ( %s )` PlacementExpression cannot be evaluated at compile time", e.placement.toChars()); + result = CTFEExp.cantexp; + return; + } + Expression epre = interpret(pue, e.argprefix, istate, CTFEGoal.Nothing); if (exceptionOrCant(epre)) return; @@ -5042,7 +5049,7 @@ public: auto ce = e.e2.isCallExp(); assert(ce); - auto ne = new NewExp(e.loc, null, e.type, ce.arguments); + auto ne = new NewExp(e.loc, null, null, e.type, ce.arguments); ne.type = e.e1.type; result = interpret(ne, istate); diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 3264c34..dea8df6 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -180,6 +180,7 @@ extern (C++) class Package : ScopeDsymbol super(loc, ident); __gshared uint packageTag; this.tag = packageTag++; + this.dsym = DSYM.package_; } override const(char)* kind() const nothrow @@ -253,11 +254,6 @@ extern (C++) class Package : ScopeDsymbol return dst; } - override final inout(Package) isPackage() inout - { - return this; - } - /** * Checks if pkg is a sub-package of this * @@ -445,6 +441,7 @@ extern (C++) final class Module : Package extern (D) this(Loc loc, const(char)[] filename, Identifier ident, int doDocComment, int doHdrGen) { super(loc, ident); + this.dsym = DSYM.module_; const(char)[] srcfilename; //printf("Module::Module(filename = '%.*s', ident = '%s')\n", cast(int)filename.length, filename.ptr, ident.toChars()); this.arg = filename; @@ -1178,11 +1175,6 @@ extern (C++) final class Module : Package uint[uint] ctfe_cov; /// coverage information from ctfe execution_count[line] - override inout(Module) isModule() inout nothrow - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d index 3001bd7..2a29ef2 100644 --- a/gcc/d/dmd/dscope.d +++ b/gcc/d/dmd/dscope.d @@ -176,7 +176,7 @@ extern (C++) struct Scope Visibility visibility = Visibility(Visibility.Kind.public_); int explicitVisibility; /// set if in an explicit visibility attribute - StorageClass stc; /// storage class + STC stc; /// storage class DeprecatedDeclaration depdecl; /// customized deprecation message diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index 0a0b366..3a26002 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -119,6 +119,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration extern (D) this(Loc loc, Identifier id, bool inObject) { super(loc, id); + this.dsym = DSYM.structDeclaration; zeroInit = false; // assume false until we do semantic processing ispod = ThreeState.none; // For forward references @@ -374,11 +375,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration return postblit || hasCopyCtor; } - override final inout(StructDeclaration) isStructDeclaration() inout @nogc nothrow pure @safe - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -543,6 +539,7 @@ extern (C++) final class UnionDeclaration : StructDeclaration extern (D) this(Loc loc, Identifier id) { super(loc, id, false); + this.dsym = DSYM.unionDeclaration; } override UnionDeclaration syntaxCopy(Dsymbol s) @@ -558,11 +555,6 @@ extern (C++) final class UnionDeclaration : StructDeclaration return "union"; } - override inout(UnionDeclaration) isUnionDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index 64cf6be..e71c890 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -51,6 +51,7 @@ import dmd.statement; import dmd.staticassert; import dmd.tokens; import dmd.visitor; +import dmd.dsymbolsem; import dmd.common.outbuffer; @@ -258,6 +259,76 @@ private struct DsymbolAttributes UserAttributeDeclaration userAttribDecl; } +enum DSYM : ubyte +{ + none, + dsymbol, + linkDeclaration, + cppMangleDeclaration, + alignDeclaration, + pragmaDeclaration, + conditionalDeclaration, + staticForeachDeclaration, + userAttributeDeclaration, + labelDsymbol, + aliasThis, + package_, + module_, + enumMember, + templateDeclaration, + templateInstance, + templateMixin, + forwardingAttribDeclaration, + nspace, + declaration, + storageClassDeclaration, + expressionDsymbol, + aliasAssign, + thisDeclaration, + bitFieldDeclaration, + typeInfoDeclaration, + tupleDeclaration, + aliasDeclaration, + aggregateDeclaration, + funcDeclaration, + funcAliasDeclaration, + overDeclaration, + funcLiteralDeclaration, + ctorDeclaration, + postBlitDeclaration, + dtorDeclaration, + staticCtorDeclaration, + staticDtorDeclaration, + sharedStaticCtorDeclaration, + sharedStaticDtorDeclaration, + invariantDeclaration, + unitTestDeclaration, + newDeclaration, + varDeclaration, + versionSymbol, + debugSymbol, + classDeclaration, + structDeclaration, + unionDeclaration, + interfaceDeclaration, + scopeDsymbol, + forwardingScopeDsymbol, + withScopeSymbol, + arrayScopeSymbol, + import_, + enumDeclaration, + symbolDeclaration, + attribDeclaration, + anonDeclaration, + cppNamespaceDeclaration, + visibilityDeclaration, + overloadSet, + mixinDeclaration, + staticAssert, + staticIfDeclaration, + cAsmDeclaration +} + /*********************************************************** */ extern (C++) class Dsymbol : ASTNode @@ -268,33 +339,42 @@ extern (C++) class Dsymbol : ASTNode Scope* _scope; // !=null means context to use for semantic() private DsymbolAttributes* atts; /// attached attribute declarations const Loc loc; // where defined - bool errors; // this symbol failed to pass semantic() - PASS semanticRun = PASS.initial; ushort localNum; /// perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab + static struct BitFields + { + bool errors; // this symbol failed to pass semantic() + PASS semanticRun = PASS.initial; + } + import dmd.common.bitfields; + mixin(generateBitFields!(BitFields, ubyte)); + DSYM dsym; - final extern (D) this() nothrow @safe + final extern (D) this(DSYM tag) nothrow @safe { //printf("Dsymbol::Dsymbol(%p)\n", this); + this.dsym = tag; loc = Loc.initial; } - final extern (D) this(Identifier ident) nothrow @safe + final extern (D) this(DSYM tag, Identifier ident) nothrow @safe { //printf("Dsymbol::Dsymbol(%p, ident)\n", this); + this.dsym = tag; this.loc = Loc.initial; this.ident = ident; } - final extern (D) this(Loc loc, Identifier ident) nothrow @safe + final extern (D) this(DSYM tag, Loc loc, Identifier ident) nothrow @safe { //printf("Dsymbol::Dsymbol(%p, ident)\n", this); + this.dsym = tag; this.loc = loc; this.ident = ident; } static Dsymbol create(Identifier ident) nothrow @safe { - return new Dsymbol(ident); + return new Dsymbol(DSYM.dsymbol, ident); } final override const(char)* toChars() const @@ -820,20 +900,6 @@ extern (C++) class Dsymbol : ASTNode assert(0); } - /************************************** - * Determine if this symbol is only one. - * Returns: - * false, ps = null: There are 2 or more symbols - * true, ps = null: There are zero symbols - * true, ps = symbol: The one and only one symbol - */ - bool oneMember(out Dsymbol ps, Identifier ident) - { - //printf("Dsymbol::oneMember()\n"); - ps = this; - return true; - } - /***************************************** * Same as Dsymbol::oneMember(), but look at an array of Dsymbols. */ @@ -850,7 +916,7 @@ extern (C++) class Dsymbol : ASTNode for (size_t i = 0; i < members.length; i++) { Dsymbol sx = (*members)[i]; - bool x = sx.oneMember(ps, ident); + bool x = sx.oneMember(ps, ident); //MYTODO: this temporarily creates a new dependency to dsymbolsem, will need to extract oneMembers() later //printf("\t[%d] kind %s = %d, s = %p\n", i, sx.kind(), x, *ps); if (!x) { @@ -906,12 +972,6 @@ extern (C++) class Dsymbol : ASTNode return false; } - bool hasStaticCtorOrDtor() - { - //printf("Dsymbol::hasStaticCtorOrDtor() %s\n", toChars()); - return false; - } - void addObjcSymbols(ClassDeclarations* classes, ClassDeclarations* categories) { } @@ -1008,64 +1068,181 @@ extern (C++) class Dsymbol : ASTNode v.visit(this); } - pure nothrow @safe @nogc: - - // Eliminate need for dynamic_cast - inout(Package) isPackage() inout { return null; } - inout(Module) isModule() inout { return null; } - inout(EnumMember) isEnumMember() inout { return null; } - inout(TemplateDeclaration) isTemplateDeclaration() inout { return null; } - inout(TemplateInstance) isTemplateInstance() inout { return null; } - inout(TemplateMixin) isTemplateMixin() inout { return null; } - inout(ForwardingAttribDeclaration) isForwardingAttribDeclaration() inout { return null; } - inout(Nspace) isNspace() inout { return null; } - inout(Declaration) isDeclaration() inout { return null; } - inout(StorageClassDeclaration) isStorageClassDeclaration() inout { return null; } - inout(ExpressionDsymbol) isExpressionDsymbol() inout { return null; } - inout(AliasAssign) isAliasAssign() inout { return null; } - inout(ThisDeclaration) isThisDeclaration() inout { return null; } - inout(BitFieldDeclaration) isBitFieldDeclaration() inout { return null; } - inout(TypeInfoDeclaration) isTypeInfoDeclaration() inout { return null; } - inout(TupleDeclaration) isTupleDeclaration() inout { return null; } - inout(AliasDeclaration) isAliasDeclaration() inout { return null; } - inout(AggregateDeclaration) isAggregateDeclaration() inout { return null; } - inout(FuncDeclaration) isFuncDeclaration() inout { return null; } - inout(FuncAliasDeclaration) isFuncAliasDeclaration() inout { return null; } - inout(OverDeclaration) isOverDeclaration() inout { return null; } - inout(FuncLiteralDeclaration) isFuncLiteralDeclaration() inout { return null; } - inout(CtorDeclaration) isCtorDeclaration() inout { return null; } - inout(PostBlitDeclaration) isPostBlitDeclaration() inout { return null; } - inout(DtorDeclaration) isDtorDeclaration() inout { return null; } - inout(StaticCtorDeclaration) isStaticCtorDeclaration() inout { return null; } - inout(StaticDtorDeclaration) isStaticDtorDeclaration() inout { return null; } - inout(SharedStaticCtorDeclaration) isSharedStaticCtorDeclaration() inout { return null; } - inout(SharedStaticDtorDeclaration) isSharedStaticDtorDeclaration() inout { return null; } - inout(InvariantDeclaration) isInvariantDeclaration() inout { return null; } - inout(UnitTestDeclaration) isUnitTestDeclaration() inout { return null; } - inout(NewDeclaration) isNewDeclaration() inout { return null; } - inout(VarDeclaration) isVarDeclaration() inout { return null; } - inout(VersionSymbol) isVersionSymbol() inout { return null; } - inout(DebugSymbol) isDebugSymbol() inout { return null; } - inout(ClassDeclaration) isClassDeclaration() inout { return null; } - inout(StructDeclaration) isStructDeclaration() inout { return null; } - inout(UnionDeclaration) isUnionDeclaration() inout { return null; } - inout(InterfaceDeclaration) isInterfaceDeclaration() inout { return null; } - inout(ScopeDsymbol) isScopeDsymbol() inout { return null; } - inout(ForwardingScopeDsymbol) isForwardingScopeDsymbol() inout { return null; } - inout(WithScopeSymbol) isWithScopeSymbol() inout { return null; } - inout(ArrayScopeSymbol) isArrayScopeSymbol() inout { return null; } - inout(Import) isImport() inout { return null; } - inout(EnumDeclaration) isEnumDeclaration() inout { return null; } - inout(SymbolDeclaration) isSymbolDeclaration() inout { return null; } - inout(AttribDeclaration) isAttribDeclaration() inout { return null; } - inout(AnonDeclaration) isAnonDeclaration() inout { return null; } - inout(CPPNamespaceDeclaration) isCPPNamespaceDeclaration() inout { return null; } - inout(VisibilityDeclaration) isVisibilityDeclaration() inout { return null; } - inout(OverloadSet) isOverloadSet() inout { return null; } - inout(MixinDeclaration) isMixinDeclaration() inout { return null; } - inout(StaticAssert) isStaticAssert() inout { return null; } - inout(StaticIfDeclaration) isStaticIfDeclaration() inout { return null; } - inout(CAsmDeclaration) isCAsmDeclaration() inout { return null; } + pure nothrow @trusted @nogc final: + + inout(Package) isPackage() inout { return (dsym == DSYM.package_ || dsym == DSYM.module_) ? cast(inout(Package)) cast(void*) this : null; } + inout(Module) isModule() inout { return dsym == DSYM.module_ ? cast(inout(Module)) cast(void*) this : null; } + inout(EnumMember) isEnumMember() inout { return dsym == DSYM.enumMember ? cast(inout(EnumMember)) cast(void*) this : null; } + inout(TemplateDeclaration) isTemplateDeclaration() inout { return dsym == DSYM.templateDeclaration ? cast(inout(TemplateDeclaration)) cast(void*) this : null; } + inout(TemplateInstance) isTemplateInstance() inout { return (dsym == DSYM.templateInstance || dsym == DSYM.templateMixin) ? cast(inout(TemplateInstance)) cast(void*) this : null; } + inout(TemplateMixin) isTemplateMixin() inout { return dsym == DSYM.templateMixin ? cast(inout(TemplateMixin)) cast(void*) this : null; } + inout(ForwardingAttribDeclaration) isForwardingAttribDeclaration() inout { return dsym == DSYM.forwardingAttribDeclaration ? cast(inout(ForwardingAttribDeclaration)) cast(void*) this : null; } + inout(Nspace) isNspace() inout { return dsym == DSYM.nspace ? cast(inout(Nspace)) cast(void*) this : null; } + inout(Declaration) isDeclaration() inout { + switch (dsym) + { + case DSYM.tupleDeclaration: + case DSYM.aliasDeclaration: + case DSYM.overDeclaration: + case DSYM.varDeclaration: + case DSYM.bitFieldDeclaration: + case DSYM.typeInfoDeclaration: + case DSYM.thisDeclaration: + case DSYM.enumMember: + case DSYM.symbolDeclaration: + case DSYM.funcDeclaration: + case DSYM.funcAliasDeclaration: + case DSYM.funcLiteralDeclaration: + case DSYM.ctorDeclaration: + case DSYM.postBlitDeclaration: + case DSYM.dtorDeclaration: + case DSYM.staticCtorDeclaration: + case DSYM.sharedStaticCtorDeclaration: + case DSYM.staticDtorDeclaration: + case DSYM.sharedStaticDtorDeclaration: + case DSYM.invariantDeclaration: + case DSYM.unitTestDeclaration: + case DSYM.newDeclaration: + return cast(inout(Declaration)) cast(void*) this; + default: + return null; + } + } + inout(StorageClassDeclaration) isStorageClassDeclaration() inout { return dsym == DSYM.storageClassDeclaration ? cast(inout(StorageClassDeclaration)) cast(void*) this : null; } + inout(ExpressionDsymbol) isExpressionDsymbol() inout { return dsym == DSYM.expressionDsymbol ? cast(inout(ExpressionDsymbol)) cast(void*) this : null; } + inout(AliasAssign) isAliasAssign() inout { return dsym == DSYM.aliasAssign ? cast(inout(AliasAssign)) cast(void*) this : null; } + inout(ThisDeclaration) isThisDeclaration() inout { return dsym == DSYM.thisDeclaration ? cast(inout(ThisDeclaration)) cast(void*) this : null; } + inout(BitFieldDeclaration) isBitFieldDeclaration() inout { return dsym == DSYM.bitFieldDeclaration ? cast(inout(BitFieldDeclaration)) cast(void*) this : null; } + inout(TypeInfoDeclaration) isTypeInfoDeclaration() inout { return dsym == DSYM.typeInfoDeclaration ? cast(inout(TypeInfoDeclaration)) cast(void*) this : null; } + inout(TupleDeclaration) isTupleDeclaration() inout { return dsym == DSYM.tupleDeclaration ? cast(inout(TupleDeclaration)) cast(void*) this : null; } + inout(AliasDeclaration) isAliasDeclaration() inout { return dsym == DSYM.aliasDeclaration ? cast(inout(AliasDeclaration)) cast(void*) this : null; } + inout(AggregateDeclaration) isAggregateDeclaration() inout { + switch (dsym) + { + case DSYM.aggregateDeclaration: + case DSYM.structDeclaration: + case DSYM.unionDeclaration: + case DSYM.classDeclaration: + case DSYM.interfaceDeclaration: + return cast(inout(AggregateDeclaration)) cast(void*) this; + default: + return null; + } + } + inout(FuncDeclaration) isFuncDeclaration() inout { + switch (dsym) + { + case DSYM.funcDeclaration: + case DSYM.funcAliasDeclaration: + case DSYM.funcLiteralDeclaration: + case DSYM.ctorDeclaration: + case DSYM.postBlitDeclaration: + case DSYM.dtorDeclaration: + case DSYM.staticCtorDeclaration: + case DSYM.sharedStaticCtorDeclaration: + case DSYM.staticDtorDeclaration: + case DSYM.sharedStaticDtorDeclaration: + case DSYM.invariantDeclaration: + case DSYM.unitTestDeclaration: + case DSYM.newDeclaration: + return cast(inout(FuncDeclaration)) cast(void*) this; + default: + return null; + } + } + inout(FuncAliasDeclaration) isFuncAliasDeclaration() inout { return dsym == DSYM.funcAliasDeclaration ? cast(inout(FuncAliasDeclaration)) cast(void*) this : null; } + inout(OverDeclaration) isOverDeclaration() inout { return dsym == DSYM.overDeclaration ? cast(inout(OverDeclaration)) cast(void*) this : null; } + inout(FuncLiteralDeclaration) isFuncLiteralDeclaration() inout { return dsym == DSYM.funcLiteralDeclaration ? cast(inout(FuncLiteralDeclaration)) cast(void*) this : null; } + inout(CtorDeclaration) isCtorDeclaration() inout { return dsym == DSYM.ctorDeclaration ? cast(inout(CtorDeclaration)) cast(void*) this : null; } + inout(PostBlitDeclaration) isPostBlitDeclaration() inout { return dsym == DSYM.postBlitDeclaration ? cast(inout(PostBlitDeclaration)) cast(void*) this : null; } + inout(DtorDeclaration) isDtorDeclaration() inout { return dsym == DSYM.dtorDeclaration ? cast(inout(DtorDeclaration)) cast(void*) this : null; } + inout(StaticCtorDeclaration) isStaticCtorDeclaration() inout { return (dsym == DSYM.staticCtorDeclaration || dsym == DSYM.sharedStaticCtorDeclaration) ? cast(inout(StaticCtorDeclaration)) cast(void*) this : null; } + inout(StaticDtorDeclaration) isStaticDtorDeclaration() inout { return (dsym == DSYM.staticDtorDeclaration || dsym == DSYM.sharedStaticDtorDeclaration) ? cast(inout(StaticDtorDeclaration)) cast(void*) this : null; } + inout(SharedStaticCtorDeclaration) isSharedStaticCtorDeclaration() inout { return dsym == DSYM.sharedStaticCtorDeclaration ? cast(inout(SharedStaticCtorDeclaration)) cast(void*) this : null; } + inout(SharedStaticDtorDeclaration) isSharedStaticDtorDeclaration() inout { return dsym == DSYM.sharedStaticDtorDeclaration ? cast(inout(SharedStaticDtorDeclaration)) cast(void*) this : null; } + inout(InvariantDeclaration) isInvariantDeclaration() inout { return dsym == DSYM.invariantDeclaration ? cast(inout(InvariantDeclaration)) cast(void*) this : null; } + inout(UnitTestDeclaration) isUnitTestDeclaration() inout { return dsym == DSYM.unitTestDeclaration ? cast(inout(UnitTestDeclaration)) cast(void*) this : null; } + inout(NewDeclaration) isNewDeclaration() inout { return dsym == DSYM.newDeclaration ? cast(inout(NewDeclaration)) cast(void*) this : null; } + inout(VarDeclaration) isVarDeclaration() inout { + switch (dsym) + { + case DSYM.varDeclaration: + case DSYM.bitFieldDeclaration: + case DSYM.typeInfoDeclaration: + case DSYM.thisDeclaration: + case DSYM.enumMember: + return cast(inout(VarDeclaration)) cast(void*) this; + default: + return null; + } + } + inout(VersionSymbol) isVersionSymbol() inout { return dsym == DSYM.versionSymbol ? cast(inout(VersionSymbol)) cast(void*) this : null; } + inout(DebugSymbol) isDebugSymbol() inout { return dsym == DSYM.debugSymbol ? cast(inout(DebugSymbol)) cast(void*) this : null; } + inout(ClassDeclaration) isClassDeclaration() inout { return (dsym == DSYM.classDeclaration || dsym == DSYM.interfaceDeclaration) ? cast(inout(ClassDeclaration)) cast(void*) this : null; } + inout(StructDeclaration) isStructDeclaration() inout { return (dsym == DSYM.structDeclaration || dsym == DSYM.unionDeclaration) ? cast(inout(StructDeclaration)) cast(void*) this : null; } + inout(UnionDeclaration) isUnionDeclaration() inout { return dsym == DSYM.unionDeclaration ? cast(inout(UnionDeclaration)) cast(void*) this : null; } + inout(InterfaceDeclaration) isInterfaceDeclaration() inout { return dsym == DSYM.interfaceDeclaration ? cast(inout(InterfaceDeclaration)) cast(void*) this : null; } + inout(ScopeDsymbol) isScopeDsymbol() inout { + switch (dsym) + { + case DSYM.enumDeclaration: + case DSYM.scopeDsymbol: + case DSYM.package_: + case DSYM.module_: + case DSYM.nspace: + case DSYM.templateInstance: + case DSYM.templateMixin: + case DSYM.templateDeclaration: + case DSYM.aggregateDeclaration: + case DSYM.structDeclaration: + case DSYM.unionDeclaration: + case DSYM.classDeclaration: + case DSYM.interfaceDeclaration: + case DSYM.withScopeSymbol: + case DSYM.arrayScopeSymbol: + case DSYM.forwardingScopeDsymbol: + return cast(inout(ScopeDsymbol)) cast(void*) this; + default: + return null; + } + } + inout(ForwardingScopeDsymbol) isForwardingScopeDsymbol() inout { return dsym == DSYM.forwardingScopeDsymbol ? cast(inout(ForwardingScopeDsymbol)) cast(void*) this : null; } + inout(WithScopeSymbol) isWithScopeSymbol() inout { return dsym == DSYM.withScopeSymbol ? cast(inout(WithScopeSymbol)) cast(void*) this : null; } + inout(ArrayScopeSymbol) isArrayScopeSymbol() inout { return dsym == DSYM.arrayScopeSymbol ? cast(inout(ArrayScopeSymbol)) cast(void*) this : null; } + inout(Import) isImport() inout { return dsym == DSYM.import_ ? cast(inout(Import)) cast(void*) this : null; } + inout(EnumDeclaration) isEnumDeclaration() inout { return dsym == DSYM.enumDeclaration ? cast(inout(EnumDeclaration)) cast(void*) this : null; } + inout(SymbolDeclaration) isSymbolDeclaration() inout { return dsym == DSYM.symbolDeclaration ? cast(inout(SymbolDeclaration)) cast(void*) this : null; } + inout(AttribDeclaration) isAttribDeclaration() inout { + switch (dsym) + { + case DSYM.attribDeclaration: + case DSYM.storageClassDeclaration: + case DSYM.linkDeclaration: + case DSYM.cppMangleDeclaration: + case DSYM.cppNamespaceDeclaration: + case DSYM.visibilityDeclaration: + case DSYM.alignDeclaration: + case DSYM.anonDeclaration: + case DSYM.pragmaDeclaration: + case DSYM.conditionalDeclaration: + case DSYM.staticIfDeclaration: + case DSYM.staticForeachDeclaration: + case DSYM.forwardingAttribDeclaration: + case DSYM.mixinDeclaration: + case DSYM.userAttributeDeclaration: + return cast(inout(AttribDeclaration)) cast(void*) this; + default: + return null; + } + } + inout(AnonDeclaration) isAnonDeclaration() inout { return dsym == DSYM.anonDeclaration ? cast(inout(AnonDeclaration)) cast(void*) this : null; } + inout(CPPNamespaceDeclaration) isCPPNamespaceDeclaration() inout { return dsym == DSYM.cppNamespaceDeclaration ? cast(inout(CPPNamespaceDeclaration)) cast(void*) this : null; } + inout(VisibilityDeclaration) isVisibilityDeclaration() inout { return dsym == DSYM.visibilityDeclaration ? cast(inout(VisibilityDeclaration)) cast(void*) this : null; } + inout(OverloadSet) isOverloadSet() inout { return dsym == DSYM.overloadSet ? cast(inout(OverloadSet)) cast(void*) this : null; } + inout(MixinDeclaration) isMixinDeclaration() inout { return dsym == DSYM.mixinDeclaration ? cast(inout(MixinDeclaration)) cast(void*) this : null; } + inout(StaticAssert) isStaticAssert() inout { return dsym == DSYM.staticAssert ? cast(inout(StaticAssert)) cast(void*) this : null; } + inout(StaticIfDeclaration) isStaticIfDeclaration() inout { return dsym == DSYM.staticIfDeclaration ? cast(inout(StaticIfDeclaration)) cast(void*) this : null; } + inout(CAsmDeclaration) isCAsmDeclaration() inout { return dsym == DSYM.cAsmDeclaration ? cast(inout(CAsmDeclaration)) cast(void*) this : null; } } /*********************************************************** @@ -1088,16 +1265,17 @@ private: public: final extern (D) this() nothrow @safe { + super(DSYM.scopeDsymbol); } final extern (D) this(Identifier ident) nothrow @safe { - super(ident); + super(DSYM.scopeDsymbol, ident); } final extern (D) this(Loc loc, Identifier ident) nothrow @safe { - super(loc, ident); + super(DSYM.scopeDsymbol, loc, ident); } override ScopeDsymbol syntaxCopy(Dsymbol s) @@ -1307,29 +1485,6 @@ public: return symtab.lookup(id); } - /**************************************** - * Return true if any of the members are static ctors or static dtors, or if - * any members have members that are. - */ - override bool hasStaticCtorOrDtor() - { - if (members) - { - for (size_t i = 0; i < members.length; i++) - { - Dsymbol member = (*members)[i]; - if (member.hasStaticCtorOrDtor()) - return true; - } - } - return false; - } - - override final inout(ScopeDsymbol) isScopeDsymbol() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1346,11 +1501,7 @@ extern (C++) final class WithScopeSymbol : ScopeDsymbol extern (D) this(WithStatement withstate) nothrow @safe { this.withstate = withstate; - } - - override inout(WithScopeSymbol) isWithScopeSymbol() inout - { - return this; + this.dsym = DSYM.withScopeSymbol; } override void accept(Visitor v) @@ -1374,6 +1525,7 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol assert(exp.op == EXP.index || exp.op == EXP.slice || exp.op == EXP.array); this._scope = sc; this.arrayContent = exp; + this.dsym = DSYM.arrayScopeSymbol; } extern (D) this(Scope* sc, TypeTuple type) nothrow @safe @@ -1388,11 +1540,6 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol this.arrayContent = td; } - override inout(ArrayScopeSymbol) isArrayScopeSymbol() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1408,7 +1555,7 @@ extern (C++) final class OverloadSet : Dsymbol extern (D) this(Identifier ident, OverloadSet os = null) nothrow { - super(ident); + super(DSYM.overloadSet, ident); if (os) { a.pushSlice(os.a[]); @@ -1420,11 +1567,6 @@ extern (C++) final class OverloadSet : Dsymbol a.push(s); } - override inout(OverloadSet) isOverloadSet() inout - { - return this; - } - override const(char)* kind() const { return "overloadset"; @@ -1447,6 +1589,7 @@ extern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol extern (D) this() nothrow @safe { super(); + this.dsym = DSYM.forwardingScopeDsymbol; } override Dsymbol symtabInsert(Dsymbol s) nothrow @@ -1515,11 +1658,6 @@ extern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol override const(char)* kind()const{ return "local scope"; } - override inout(ForwardingScopeDsymbol) isForwardingScopeDsymbol() inout nothrow - { - return this; - } - } /** @@ -1532,14 +1670,9 @@ extern (C++) final class ExpressionDsymbol : Dsymbol Expression exp; this(Expression exp) nothrow @safe { - super(); + super(DSYM.expressionDsymbol); this.exp = exp; } - - override inout(ExpressionDsymbol) isExpressionDsymbol() inout nothrow - { - return this; - } } /********************************************** @@ -1557,7 +1690,7 @@ extern (C++) final class AliasAssign : Dsymbol extern (D) this(Loc loc, Identifier ident, Type type, Dsymbol aliassym) nothrow @safe { - super(loc, null); + super(DSYM.aliasAssign, loc, null); this.ident = ident; this.type = type; this.aliassym = aliassym; @@ -1572,11 +1705,6 @@ extern (C++) final class AliasAssign : Dsymbol return aa; } - override inout(AliasAssign) isAliasAssign() inout - { - return this; - } - override const(char)* kind() const { return "alias assignment"; @@ -1669,15 +1797,10 @@ extern (C++) final class CAsmDeclaration : Dsymbol Expression code; extern (D) this(Expression e) nothrow @safe { - super(); + super(DSYM.cAsmDeclaration); this.code = e; } - override inout(CAsmDeclaration) isCAsmDeclaration() inout nothrow - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h index 8209dea..e3ea876 100644 --- a/gcc/d/dmd/dsymbol.h +++ b/gcc/d/dmd/dsymbol.h @@ -183,9 +183,15 @@ private: DsymbolAttributes* atts; public: Loc loc; // where defined - d_bool errors; // this symbol failed to pass semantic() - PASS semanticRun; unsigned short localNum; // perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab + + bool errors() const; + PASS semanticRun() const; + PASS semanticRun(PASS v); +private: + unsigned char bitfields; + unsigned char dsym; +public: static Dsymbol *create(Identifier *); const char *toChars() const final override; DeprecatedDeclaration* depdecl(); @@ -237,9 +243,7 @@ public: virtual bool needThis(); // need a 'this' pointer? virtual Visibility visible(); virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees - virtual bool oneMember(Dsymbol *&ps, Identifier *ident); virtual bool hasPointers(); - virtual bool hasStaticCtorOrDtor(); virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { } virtual void addComment(const utf8_t *comment); @@ -251,61 +255,61 @@ public: bool inNonRoot(); // Eliminate need for dynamic_cast - virtual Package *isPackage() { return nullptr; } - virtual Module *isModule() { return nullptr; } - virtual EnumMember *isEnumMember() { return nullptr; } - virtual TemplateDeclaration *isTemplateDeclaration() { return nullptr; } - virtual TemplateInstance *isTemplateInstance() { return nullptr; } - virtual TemplateMixin *isTemplateMixin() { return nullptr; } - virtual ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return nullptr; } - virtual Nspace *isNspace() { return nullptr; } - virtual Declaration *isDeclaration() { return nullptr; } - virtual StorageClassDeclaration *isStorageClassDeclaration(){ return nullptr; } - virtual ExpressionDsymbol *isExpressionDsymbol() { return nullptr; } - virtual AliasAssign *isAliasAssign() { return nullptr; } - virtual ThisDeclaration *isThisDeclaration() { return nullptr; } - virtual BitFieldDeclaration *isBitFieldDeclaration() { return nullptr; } - virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return nullptr; } - virtual TupleDeclaration *isTupleDeclaration() { return nullptr; } - virtual AliasDeclaration *isAliasDeclaration() { return nullptr; } - virtual AggregateDeclaration *isAggregateDeclaration() { return nullptr; } - virtual FuncDeclaration *isFuncDeclaration() { return nullptr; } - virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return nullptr; } - virtual OverDeclaration *isOverDeclaration() { return nullptr; } - virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return nullptr; } - virtual CtorDeclaration *isCtorDeclaration() { return nullptr; } - virtual PostBlitDeclaration *isPostBlitDeclaration() { return nullptr; } - virtual DtorDeclaration *isDtorDeclaration() { return nullptr; } - virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return nullptr; } - virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return nullptr; } - virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return nullptr; } - virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return nullptr; } - virtual InvariantDeclaration *isInvariantDeclaration() { return nullptr; } - virtual UnitTestDeclaration *isUnitTestDeclaration() { return nullptr; } - virtual NewDeclaration *isNewDeclaration() { return nullptr; } - virtual VarDeclaration *isVarDeclaration() { return nullptr; } - virtual VersionSymbol *isVersionSymbol() { return nullptr; } - virtual DebugSymbol *isDebugSymbol() { return nullptr; } - virtual ClassDeclaration *isClassDeclaration() { return nullptr; } - virtual StructDeclaration *isStructDeclaration() { return nullptr; } - virtual UnionDeclaration *isUnionDeclaration() { return nullptr; } - virtual InterfaceDeclaration *isInterfaceDeclaration() { return nullptr; } - virtual ScopeDsymbol *isScopeDsymbol() { return nullptr; } - virtual ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return nullptr; } - virtual WithScopeSymbol *isWithScopeSymbol() { return nullptr; } - virtual ArrayScopeSymbol *isArrayScopeSymbol() { return nullptr; } - virtual Import *isImport() { return nullptr; } - virtual EnumDeclaration *isEnumDeclaration() { return nullptr; } - virtual SymbolDeclaration *isSymbolDeclaration() { return nullptr; } - virtual AttribDeclaration *isAttribDeclaration() { return nullptr; } - virtual AnonDeclaration *isAnonDeclaration() { return nullptr; } - virtual CPPNamespaceDeclaration *isCPPNamespaceDeclaration() { return nullptr; } - virtual VisibilityDeclaration *isVisibilityDeclaration() { return nullptr; } - virtual OverloadSet *isOverloadSet() { return nullptr; } - virtual MixinDeclaration *isMixinDeclaration() { return nullptr; } - virtual StaticAssert *isStaticAssert() { return nullptr; } - virtual StaticIfDeclaration *isStaticIfDeclaration() { return nullptr; } - virtual CAsmDeclaration *isCAsmDeclaration() { return nullptr; } + Package *isPackage(); + Module *isModule(); + EnumMember *isEnumMember(); + TemplateDeclaration *isTemplateDeclaration(); + TemplateInstance *isTemplateInstance(); + TemplateMixin *isTemplateMixin(); + ForwardingAttribDeclaration *isForwardingAttribDeclaration(); + Nspace *isNspace(); + Declaration *isDeclaration(); + StorageClassDeclaration *isStorageClassDeclaration(); + ExpressionDsymbol *isExpressionDsymbol(); + AliasAssign *isAliasAssign(); + ThisDeclaration *isThisDeclaration(); + BitFieldDeclaration *isBitFieldDeclaration(); + TypeInfoDeclaration *isTypeInfoDeclaration(); + TupleDeclaration *isTupleDeclaration(); + AliasDeclaration *isAliasDeclaration(); + AggregateDeclaration *isAggregateDeclaration(); + FuncDeclaration *isFuncDeclaration(); + FuncAliasDeclaration *isFuncAliasDeclaration(); + OverDeclaration *isOverDeclaration(); + FuncLiteralDeclaration *isFuncLiteralDeclaration(); + CtorDeclaration *isCtorDeclaration(); + PostBlitDeclaration *isPostBlitDeclaration(); + DtorDeclaration *isDtorDeclaration(); + StaticCtorDeclaration *isStaticCtorDeclaration(); + StaticDtorDeclaration *isStaticDtorDeclaration(); + SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration(); + SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration(); + InvariantDeclaration *isInvariantDeclaration(); + UnitTestDeclaration *isUnitTestDeclaration(); + NewDeclaration *isNewDeclaration(); + VarDeclaration *isVarDeclaration(); + VersionSymbol *isVersionSymbol(); + DebugSymbol *isDebugSymbol(); + ClassDeclaration *isClassDeclaration(); + StructDeclaration *isStructDeclaration(); + UnionDeclaration *isUnionDeclaration(); + InterfaceDeclaration *isInterfaceDeclaration(); + ScopeDsymbol *isScopeDsymbol(); + ForwardingScopeDsymbol *isForwardingScopeDsymbol(); + WithScopeSymbol *isWithScopeSymbol(); + ArrayScopeSymbol *isArrayScopeSymbol(); + Import *isImport(); + EnumDeclaration *isEnumDeclaration(); + SymbolDeclaration *isSymbolDeclaration(); + AttribDeclaration *isAttribDeclaration(); + AnonDeclaration *isAnonDeclaration(); + CPPNamespaceDeclaration *isCPPNamespaceDeclaration(); + VisibilityDeclaration *isVisibilityDeclaration(); + OverloadSet *isOverloadSet(); + MixinDeclaration *isMixinDeclaration(); + StaticAssert *isStaticAssert(); + StaticIfDeclaration *isStaticIfDeclaration(); + CAsmDeclaration *isCAsmDeclaration(); void accept(Visitor *v) override { v->visit(this); } }; @@ -332,9 +336,7 @@ public: const char *kind() const override; virtual Dsymbol *symtabInsert(Dsymbol *s); virtual Dsymbol *symtabLookup(Dsymbol *s, Identifier *id); - bool hasStaticCtorOrDtor() override; - ScopeDsymbol *isScopeDsymbol() override final { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -346,7 +348,6 @@ public: WithStatement *withstate; - WithScopeSymbol *isWithScopeSymbol() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -357,7 +358,6 @@ class ArrayScopeSymbol final : public ScopeDsymbol public: RootObject *arrayContent; - ArrayScopeSymbol *isArrayScopeSymbol() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -369,7 +369,6 @@ public: Dsymbols a; // array of Dsymbols void push(Dsymbol *s); - OverloadSet *isOverloadSet() override { return this; } const char *kind() const override; void accept(Visitor *v) override { v->visit(this); } }; @@ -384,7 +383,6 @@ public: void importScope(Dsymbol *s, Visibility visibility) override; const char *kind() const override; - ForwardingScopeDsymbol *isForwardingScopeDsymbol() override { return this; } }; class ExpressionDsymbol final : public Dsymbol @@ -392,7 +390,6 @@ class ExpressionDsymbol final : public Dsymbol public: Expression *exp; - ExpressionDsymbol *isExpressionDsymbol() override { return this; } }; class CAsmDeclaration final : public Dsymbol @@ -400,7 +397,6 @@ class CAsmDeclaration final : public Dsymbol public: Expression *code; // string expression - CAsmDeclaration *isCAsmDeclaration() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -433,4 +429,6 @@ namespace dmd void setScope(Dsymbol *d, Scope *sc); void importAll(Dsymbol *d, Scope *sc); void addComment(Dsymbol *d, const char *comment); + bool oneMember(Dsymbol *d, Dsymbol *&ps, Identifier *ident); + bool hasStaticCtorOrDtor(Dsymbol *d); } diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index b017366..894ac0d 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -812,7 +812,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } else if (isAliasThisTuple(e)) { - auto v = copyToTemp(0, "__tup", e); + auto v = copyToTemp(STC.none, "__tup", e); v.dsymbolSemantic(sc); auto ve = new VarExp(dsym.loc, v); ve.type = e.type; @@ -896,7 +896,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else ti = dsym._init ? dsym._init.syntaxCopy() : null; - StorageClass storage_class = STC.temp | dsym.storage_class; + STC storage_class = STC.temp | dsym.storage_class; if ((dsym.storage_class & STC.parameter) && (arg.storageClass & STC.parameter)) storage_class |= arg.storageClass; auto v = new VarDeclaration(dsym.loc, arg.type, id, ti, storage_class); @@ -935,7 +935,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else if (dsym.type.isWild()) dsym.storage_class |= STC.wild; - if (StorageClass stc = dsym.storage_class & (STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_)) + if (STC stc = dsym.storage_class & (STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_)) { if (stc == STC.final_) .error(dsym.loc, "%s `%s` cannot be `final`, perhaps you meant `const`?", dsym.kind, dsym.toPrettyChars); @@ -955,7 +955,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (dsym.storage_class & STC.scope_) { - StorageClass stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.gshared); + STC stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.gshared); if (stc) { OutBuffer buf; @@ -1024,7 +1024,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } // If it's a member template AggregateDeclaration ad2 = ti.tempdecl.isMember(); - if (ad2 && dsym.storage_class != STC.undefined_) + if (ad2 && dsym.storage_class != STC.none) { .error(dsym.loc, "%s `%s` - cannot use template to add field to aggregate `%s`", dsym.kind, dsym.toPrettyChars, ad2.toChars()); } @@ -1312,9 +1312,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor ex = (cast(AssignExp)ex).e2; if (auto ne = ex.isNewExp()) { + if (ne.placement) + { + } /* See if initializer is a NewExp that can be allocated on the stack. */ - if (dsym.type.toBasetype().ty == Tclass) + else if (dsym.type.toBasetype().ty == Tclass) { /* Unsafe to allocate on stack if constructor is not `scope` because the `this` can leak. * https://issues.dlang.org/show_bug.cgi?id=23145 @@ -1775,7 +1778,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor s.dsymbolSemantic(sc2); errors |= s.errors; } - ad.errors |= errors; + if (errors) + ad.errors = true; if (sc2 != sc) sc2.pop(); @@ -2678,7 +2682,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor */ auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null); - v.storage_class = STC.temp | STC.static_ | (isShared ? STC.shared_ : 0); + v.storage_class = STC.temp | STC.static_ | (isShared ? STC.shared_ : STC.none); auto sa = new Statements(); Statement s = new ExpStatement(Loc.initial, v); @@ -2962,7 +2966,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor */ sd.members.foreachDsymbol( s => s.setScope(sc2) ); sd.members.foreachDsymbol( s => s.importAll(sc2) ); - sd.members.foreachDsymbol( (s) { s.dsymbolSemantic(sc2); sd.errors |= s.errors; } ); + sd.members.foreachDsymbol( (s) { s.dsymbolSemantic(sc2); if (sd.errors) s.errors = true; } ); if (sd.errors) sd.type = Type.terror; @@ -3683,7 +3687,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // This is required if other lowerings add code to the generated constructor which // is less strict (e.g. `preview=dtorfields` might introduce a call to a less qualified dtor) - auto ctor = new CtorDeclaration(cldec.loc, Loc.initial, 0, tf); + auto ctor = new CtorDeclaration(cldec.loc, Loc.initial, STC.none, tf); ctor.storage_class |= STC.inference | (fd.storage_class & STC.scope_); ctor.isGenerated = true; ctor.fbody = new CompoundStatement(Loc.initial, new Statements()); @@ -4180,7 +4184,8 @@ private extern(C++) class AddMemberVisitor : Visitor } // If using C tag/prototype/forward declaration rules - if (sc.inCfile && !dsym.isImport()) + if (sc && sc.inCfile && !dsym.isImport()) + // When merging master, replace with: if (sc && sc.inCfile && !dsym.isImport()) { if (handleTagSymbols(*sc, dsym, s2, sds)) return; @@ -4834,7 +4839,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList continue; Type t = isType((*tempinst.tiargs)[i]); assert(t); - if (StorageClass stc = ModToStc(t.mod)) + if (STC stc = ModToStc(t.mod)) { //printf("t = %s, stc = x%llx\n", t.toChars(), stc); auto s = new Dsymbols(); @@ -4862,11 +4867,11 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList _scope = _scope.push(tempinst.argsym); _scope.tinst = tempinst; _scope.minst = tempinst.minst; - //scope.stc = 0; + //scope.stc = STC.none; // Declare each template parameter as an alias for the argument type Scope* paramscope = _scope.push(); - paramscope.stc = 0; + paramscope.stc = STC.none; paramscope.visibility = Visibility(Visibility.Kind.public_); // https://issues.dlang.org/show_bug.cgi?id=14169 // template parameters should be public tempinst.declareParameters(paramscope); @@ -5199,7 +5204,7 @@ void aliasSeqInstanceSemantic(TemplateInstance tempinst, Scope* sc, TemplateDecl { //printf("[%s] aliasSeqInstance.dsymbolSemantic('%s')\n", tempinst.loc.toChars(), tempinst.toChars()); Scope* paramscope = sc.push(); - paramscope.stc = 0; + paramscope.stc = STC.none; paramscope.visibility = Visibility(Visibility.Kind.public_); TemplateTupleParameter ttp = (*tempdecl.parameters)[0].isTemplateTupleParameter(); @@ -5224,7 +5229,7 @@ void aliasInstanceSemantic(TemplateInstance tempinst, Scope* sc, TemplateDeclara { //printf("[%s] aliasInstance.dsymbolSemantic('%s')\n", tempinst.loc.toChars(), tempinst.toChars()); Scope* paramscope = sc.push(); - paramscope.stc = 0; + paramscope.stc = STC.none; paramscope.visibility = Visibility(Visibility.Kind.public_); TemplateTypeParameter ttp = (*tempdecl.parameters)[0].isTemplateTypeParameter(); @@ -7414,7 +7419,7 @@ private extern(C++) class NewScopeVisitor : Visitor override void visit(StorageClassDeclaration swt) { - StorageClass scstc = sc.stc; + STC scstc = sc.stc; /* These sets of storage classes are mutually exclusive, * so choose the innermost or most recent one. */ @@ -7967,3 +7972,241 @@ private extern(C++) class CheckCtorConstInitVisitor : Visitor override void visit(Dsymbol d){} } + +/************************************** +* Determine if this symbol is only one. +* Returns: +* false, ps = null: There are 2 or more symbols +* true, ps = null: There are zero symbols +* true, ps = symbol: The one and only one symbol +*/ +bool oneMember(Dsymbol d, out Dsymbol ps, Identifier ident) +{ + scope v = new OneMemberVisitor(ps, ident); + d.accept(v); + return v.result; +} + +private extern(C++) class OneMemberVisitor : Visitor +{ + alias visit = Visitor.visit; + + Dsymbol* ps; + Identifier ident; + bool result; + + this(out Dsymbol ps, Identifier ident) + { + this.ps = &ps; + this.ident = ident; + } + + override void visit(AttribDeclaration atb) + { + Dsymbols* d = atb.include(null); + result = Dsymbol.oneMembers(d, *ps, ident); + } + + override void visit(StaticForeachDeclaration sfd) + { + // Required to support IFTI on a template that contains a + // `static foreach` declaration. `super.oneMember` calls + // include with a `null` scope. As `static foreach` requires + // the scope for expansion, `oneMember` can only return a + // precise result once `static foreach` has been expanded. + if (sfd.cached) + { + this.visit(cast(AttribDeclaration) sfd); + } + else + { + *ps = null; // a `static foreach` declaration may in general expand to multiple symbols + result = false; + } + } + + override void visit(StorageClassDeclaration scd) + { + bool t = Dsymbol.oneMembers(scd.decl, *ps, ident); + if (t && *ps) + { + /* This is to deal with the following case: + * struct Tick { + * template to(T) { const T to() { ... } } + * } + * For eponymous function templates, the 'const' needs to get attached to 'to' + * before the semantic analysis of 'to', so that template overloading based on the + * 'this' pointer can be successful. + */ + if (FuncDeclaration fd = (*ps).isFuncDeclaration()) + { + /* Use storage_class2 instead of storage_class otherwise when we do .di generation + * we'll wind up with 'const const' rather than 'const'. + */ + /* Don't think we need to worry about mutually exclusive storage classes here + */ + fd.storage_class2 |= scd.stc; + } + } + result = t; + } + + override void visit(ConditionalDeclaration cd) + { + //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition.inc); + if (cd.condition.inc != Include.notComputed) + { + Dsymbols* d = cd.condition.include(null) ? cd.decl : cd.elsedecl; + result = Dsymbol.oneMembers(d, *ps, ident); + } + else + { + bool res = (Dsymbol.oneMembers(cd.decl, *ps, ident) && *ps is null && Dsymbol.oneMembers(cd.elsedecl, *ps, ident) && *ps is null); + *ps = null; + result = res; + } + } + + override void visit(ScopeDsymbol sd) + { + if (sd.isAnonymous()) + result = Dsymbol.oneMembers(sd.members, *ps, ident); + else { + // visit(Dsymbol dsym) + *ps = sd; + result = true; + } + } + + override void visit(StaticAssert sa) + { + //printf("StaticAssert::oneMember())\n"); + *ps = null; + result = true; + } + + override void visit(TemplateInstance ti) + { + *ps = null; + result = true; + } + + override void visit(TemplateMixin tm) + { + *ps = tm; + result = true; + } + + override void visit(Dsymbol dsym) + { + *ps = dsym; + result = true; + } +} + +/**************************************** +* Return true if any of the members are static ctors or static dtors, or if +* any members have members that are. +*/ +extern(C++) bool hasStaticCtorOrDtor(Dsymbol d) +{ + scope v = new HasStaticCtorOrDtor(); + d.accept(v); + return v.result; +} + +private extern(C++) class HasStaticCtorOrDtor : Visitor +{ + import dmd.mtype : Type; + + alias visit = Visitor.visit; + bool result; + + // attrib.d + override void visit(AttribDeclaration ad){ + result = ad.include(null).foreachDsymbol( (s) { return s.hasStaticCtorOrDtor(); } ) != 0; + } + + // dsymbol.d + override void visit(Dsymbol d){ + //printf("Dsymbol::hasStaticCtorOrDtor() %s\n", toChars()); + result = false; + } + + override void visit(ScopeDsymbol sd) { + if (sd.members) + { + for (size_t i = 0; i < sd.members.length; i++) + { + Dsymbol member = (*(sd.members))[i]; + if (member.hasStaticCtorOrDtor()) + result = true; + return; + } + } + result = false; + } + + // dtemplate.d + override void visit(TemplateDeclaration td) { + result = false; // don't scan uninstantiated templates + } + + // func.d + override void visit(StaticCtorDeclaration scd) { + result = true; + } + + override void visit(StaticDtorDeclaration sdd) @nogc nothrow pure @safe { + result = true; + } +} + +extern(C++) bool isFuncHidden(ClassDeclaration cd, FuncDeclaration fd) +{ + import dmd.funcsem : overloadApply; + //printf("ClassDeclaration.isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toPrettyChars()); + Dsymbol s = cd.search(Loc.initial, fd.ident, SearchOpt.ignoreAmbiguous | SearchOpt.ignoreErrors); + if (!s) + { + //printf("not found\n"); + /* Because, due to a hack, if there are multiple definitions + * of fd.ident, NULL is returned. + */ + return false; + } + s = s.toAlias(); + if (auto os = s.isOverloadSet()) + { + foreach (sm; os.a) + { + auto fm = sm.isFuncDeclaration(); + if (overloadApply(fm, s => fd == s.isFuncDeclaration())) + return false; + } + return true; + } + else + { + auto f = s.isFuncDeclaration(); + //printf("%s fdstart = %p\n", s.kind(), fdstart); + if (overloadApply(f, s => fd == s.isFuncDeclaration())) + return false; + return !fd.parent.isTemplateMixin(); + } +} + +Dsymbol vtblSymbol(ClassDeclaration cd) +{ + if (!cd.vtblsym) + { + auto vtype = Type.tvoidptr.immutableOf().sarrayOf(cd.vtbl.length); + auto var = new VarDeclaration(cd.loc, vtype, Identifier.idPool("__vtbl"), null, STC.immutable_ | STC.static_); + var.addMember(null, cd); + var.isdataseg = 1; + var._linkage = LINK.d; + var.semanticRun = PASS.semanticdone; // no more semantic wanted + cd.vtblsym = var; + } + return cd.vtblsym; +} diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index c19d4b9..2b5b461 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -53,7 +53,7 @@ import dmd.dinterpret; import dmd.dmodule; import dmd.dscope; import dmd.dsymbol; -import dmd.dsymbolsem : dsymbolSemantic, checkDeprecated, aliasSemantic, search, search_correct, setScope, importAll, include; +import dmd.dsymbolsem : dsymbolSemantic, checkDeprecated, aliasSemantic, search, search_correct, setScope, importAll, include, hasStaticCtorOrDtor; import dmd.errors; import dmd.errorsink; import dmd.expression; @@ -605,6 +605,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol extern (D) this(Loc loc, Identifier ident, TemplateParameters* parameters, Expression constraint, Dsymbols* decldefs, bool ismixin = false, bool literal = false) { super(loc, ident); + this.dsym = DSYM.templateDeclaration; static if (LOG) { printf("TemplateDeclaration(this = %p, id = '%s')\n", this, ident.toChars()); @@ -743,11 +744,6 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol return true; } - override bool hasStaticCtorOrDtor() - { - return false; // don't scan uninstantiated templates - } - override const(char)* kind() const { return (onemember && onemember.isAggregateDeclaration()) ? onemember.kind() : "template"; @@ -890,11 +886,6 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol instances.remove(tibox); } - override inout(TemplateDeclaration) isTemplateDeclaration() inout - { - return this; - } - /** * Check if the last template parameter is a tuple one, * and returns it if so, else returns `null`. @@ -3002,6 +2993,8 @@ private bool reliesOnTemplateParameters(Expression e, TemplateParameter[] tparam override void visit(NewExp e) { //printf("NewExp.reliesOnTemplateParameters('%s')\n", e.toChars()); + if (e.placement) + e.placement.accept(this); if (e.thisexp) e.thisexp.accept(this); result = e.newtype.reliesOnTemplateParameters(tparams); @@ -3738,6 +3731,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol { printf("TemplateInstance(this = %p, ident = '%s')\n", this, ident ? ident.toChars() : "null"); } + this.dsym = DSYM.templateInstance; this.name = ident; this.tiargs = tiargs; } @@ -3753,6 +3747,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol { printf("TemplateInstance(this = %p, tempdecl = '%s')\n", this, td.toChars()); } + this.dsym = DSYM.templateInstance; this.name = td.ident; this.tiargs = tiargs; this.tempdecl = td; @@ -3823,12 +3818,6 @@ extern (C++) class TemplateInstance : ScopeDsymbol return "template instance"; } - override bool oneMember(out Dsymbol ps, Identifier ident) - { - ps = null; - return true; - } - override final const(char)* toPrettyCharsHelper() { OutBuffer buf; @@ -5342,11 +5331,6 @@ extern (C++) class TemplateInstance : ScopeDsymbol --nest; } - override final inout(TemplateInstance) isTemplateInstance() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -5490,6 +5474,7 @@ extern (C++) final class TemplateMixin : TemplateInstance tqual.idents.length ? cast(Identifier)tqual.idents[tqual.idents.length - 1] : (cast(TypeIdentifier)tqual).ident, tiargs ? tiargs : new Objects()); //printf("TemplateMixin(ident = '%s')\n", ident ? ident.toChars() : ""); + this.dsym = DSYM.templateMixin; this.ident = ident; this.tqual = tqual; } @@ -5505,11 +5490,6 @@ extern (C++) final class TemplateMixin : TemplateInstance return "mixin"; } - override bool oneMember(out Dsymbol ps, Identifier ident) - { - return Dsymbol.oneMember(ps, ident); - } - override bool hasPointers() { //printf("TemplateMixin.hasPointers() %s\n", toChars()); @@ -5590,11 +5570,6 @@ extern (C++) final class TemplateMixin : TemplateInstance return true; } - override inout(TemplateMixin) isTemplateMixin() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/dversion.d b/gcc/d/dmd/dversion.d index 5fd740f..5a24ea9 100644 --- a/gcc/d/dmd/dversion.d +++ b/gcc/d/dmd/dversion.d @@ -34,12 +34,12 @@ extern (C++) final class DebugSymbol : Dsymbol { extern (D) this(Loc loc, Identifier ident) @safe { - super(loc, ident); + super(DSYM.debugSymbol, loc, ident); } extern (D) this(Loc loc) @safe { - super(loc, null); + super(DSYM.aliasDeclaration, loc, null); } override DebugSymbol syntaxCopy(Dsymbol s) @@ -55,11 +55,6 @@ extern (C++) final class DebugSymbol : Dsymbol return "debug"; } - override inout(DebugSymbol) isDebugSymbol() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -75,12 +70,12 @@ extern (C++) final class VersionSymbol : Dsymbol extern (D) this(Loc loc, Identifier ident) @safe { - super(loc, ident); + super(DSYM.versionSymbol, loc, ident); } extern (D) this(Loc loc) @safe { - super(loc, null); + super(DSYM.versionSymbol, loc, null); } override VersionSymbol syntaxCopy(Dsymbol s) @@ -96,11 +91,6 @@ extern (C++) final class VersionSymbol : Dsymbol return "version"; } - override inout(VersionSymbol) isVersionSymbol() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h index a51c50c..7f149f4 100644 --- a/gcc/d/dmd/enum.h +++ b/gcc/d/dmd/enum.h @@ -52,14 +52,12 @@ public: bool inuse(bool v); EnumDeclaration *syntaxCopy(Dsymbol *s) override; - bool oneMember(Dsymbol *&ps, Identifier *ident) override; Type *getType() override; const char *kind() const override; bool isDeprecated() const override; // is Dsymbol deprecated? Visibility visible() override; bool isSpecial() const; - EnumDeclaration *isEnumDeclaration() override { return this; } Symbol *sinit; void accept(Visitor *v) override { v->visit(this); } @@ -87,6 +85,5 @@ public: EnumMember *syntaxCopy(Dsymbol *s) override; const char *kind() const override; - EnumMember *isEnumMember() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index b9e89e8..35897d6 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -1637,6 +1637,9 @@ void escapeExp(Expression e, ref scope EscapeByResults er, int deref) void visitNew(NewExp e) { + if (e.placement) + escapeExp(e.placement, er, deref); + Type tb = e.newtype.toBasetype(); if (tb.isTypeStruct() && !e.member && e.arguments) { @@ -1863,9 +1866,9 @@ void escapeExp(Expression e, ref scope EscapeByResults er, int deref) * Returns: * storage class for fd's `this` */ -StorageClass getThisStorageClass(FuncDeclaration fd) +STC getThisStorageClass(FuncDeclaration fd) { - StorageClass stc; + STC stc; auto tf = fd.type.toBasetype().isTypeFunction(); if (tf.isReturn) stc |= STC.return_; diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 388023f..f8dacd1 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -304,8 +304,8 @@ extern (C++) abstract class Expression : ASTNode static struct BitFields { - bool parens; // if this is a parenthesized expression - bool rvalue; // true if this is considered to be an rvalue, even if it is an lvalue + bool parens; // if this is a parenthesized expression + bool rvalue; // true if this is considered to be an rvalue, even if it is an lvalue } import dmd.common.bitfields; mixin(generateBitFields!(BitFields, ubyte)); @@ -2446,6 +2446,7 @@ extern (C++) final class NewExp : Expression Type newtype; Expressions* arguments; // Array of Expression's Identifiers* names; // Array of names corresponding to expressions + Expression placement; // if !=null, then PlacementExpression Expression argprefix; // expression to be evaluated just before arguments[] CtorDeclaration member; // constructor function @@ -2458,23 +2459,25 @@ extern (C++) final class NewExp : Expression /// The fields are still separate for backwards compatibility extern (D) ArgumentList argumentList() { return ArgumentList(arguments, names); } - extern (D) this(Loc loc, Expression thisexp, Type newtype, Expressions* arguments, Identifiers* names = null) @safe + extern (D) this(Loc loc, Expression placement, Expression thisexp, Type newtype, Expressions* arguments, Identifiers* names = null) @safe { super(loc, EXP.new_); + this.placement = placement; this.thisexp = thisexp; this.newtype = newtype; this.arguments = arguments; this.names = names; } - static NewExp create(Loc loc, Expression thisexp, Type newtype, Expressions* arguments) @safe + static NewExp create(Loc loc, Expression placement, Expression thisexp, Type newtype, Expressions* arguments) @safe { - return new NewExp(loc, thisexp, newtype, arguments); + return new NewExp(loc, placement, thisexp, newtype, arguments); } override NewExp syntaxCopy() { return new NewExp(loc, + placement ? placement.syntaxCopy() : null, thisexp ? thisexp.syntaxCopy() : null, newtype.syntaxCopy(), arraySyntaxCopy(arguments), @@ -2495,10 +2498,12 @@ extern (C++) final class NewAnonClassExp : Expression Expression thisexp; // if !=null, 'this' for class being allocated ClassDeclaration cd; // class being instantiated Expressions* arguments; // Array of Expression's to call class constructor + Expression placement; // if !=null, then PlacementExpression - extern (D) this(Loc loc, Expression thisexp, ClassDeclaration cd, Expressions* arguments) @safe + extern (D) this(Loc loc, Expression placement, Expression thisexp, ClassDeclaration cd, Expressions* arguments) @safe { super(loc, EXP.newAnonymousClass); + this.placement = placement; this.thisexp = thisexp; this.cd = cd; this.arguments = arguments; @@ -2506,7 +2511,9 @@ extern (C++) final class NewAnonClassExp : Expression override NewAnonClassExp syntaxCopy() { - return new NewAnonClassExp(loc, thisexp ? thisexp.syntaxCopy() : null, cd.syntaxCopy(null), arraySyntaxCopy(arguments)); + return new NewAnonClassExp(loc, placement ? placement.syntaxCopy : null, + thisexp ? thisexp.syntaxCopy() : null, + cd.syntaxCopy(null), arraySyntaxCopy(arguments)); } override void accept(Visitor v) diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index a4bb019..9c1e17a 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -40,6 +40,7 @@ class OverloadSet; class StringExp; class InterpExp; class LoweredAssignExp; +class StaticForeach; #ifdef IN_GCC typedef union tree_node Symbol; #else @@ -50,6 +51,7 @@ namespace dmd { // in expressionsem.d Expression *expressionSemantic(Expression *e, Scope *sc); + void lowerNonArrayAggregate(StaticForeach *sfe, Scope *sc); // in typesem.d Expression *defaultInit(Type *mt, Loc loc, const bool isCfile = false); @@ -517,6 +519,7 @@ public: Type *newtype; Expressions *arguments; // Array of Expression's Identifiers *names; // Array of names corresponding to expressions + Expression *placement; // if !NULL, placement expression Expression *argprefix; // expression to be evaluated just before arguments[] @@ -526,7 +529,7 @@ public: Expression *lowering; // lowered druntime hook: `_d_newclass` - static NewExp *create(Loc loc, Expression *thisexp, Type *newtype, Expressions *arguments); + static NewExp *create(Loc loc, Expression *placement, Expression *thisexp, Type *newtype, Expressions *arguments); NewExp *syntaxCopy() override; void accept(Visitor *v) override { v->visit(this); } @@ -540,6 +543,7 @@ public: Expression *thisexp; // if !NULL, 'this' for class being allocated ClassDeclaration *cd; // class being instantiated Expressions *arguments; // Array of Expression's to call class constructor + Expression *placement; // if !NULL, placement expression NewAnonClassExp *syntaxCopy() override; void accept(Visitor *v) override { v->visit(this); } diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 22fbfc2..22e9b8c 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -25,6 +25,7 @@ import dmd.astcodegen; import dmd.astenums; import dmd.canthrow; import dmd.chkformat; +import dmd.cond; import dmd.ctorflow; import dmd.dscope; import dmd.dsymbol; @@ -1452,11 +1453,6 @@ private Expression resolveUFCSProperties(Scope* sc, Expression e1, Expression e2 auto arguments = new Expressions(1); (*arguments)[0] = eleft; e = new CallExp(loc, e, arguments); - - // https://issues.dlang.org/show_bug.cgi?id=24017 - if (sc.debug_) - e.isCallExp().inDebugStatement = true; - e = e.expressionSemantic(sc); return e; } @@ -3161,7 +3157,7 @@ private bool functionParameters(Loc loc, Scope* sc, auto args = new Expressions(nargs - i); foreach (u; i .. nargs) (*args)[u - i] = (*arguments)[u]; - arg = new NewExp(loc, null, p.type, args); + arg = new NewExp(loc, null, null, p.type, args); break; } default: @@ -3324,7 +3320,7 @@ private bool functionParameters(Loc loc, Scope* sc, { /* allow rvalues to be passed to ref parameters by copying * them to a temp, then pass the temp as the argument */ - auto v = copyToTemp(0, "__rvalue", arg); + auto v = copyToTemp(STC.none, "__rvalue", arg); Expression ev = new DeclarationExp(arg.loc, v); ev = new CommaExp(arg.loc, ev, new VarExp(arg.loc, v)); arg = ev.expressionSemantic(sc); @@ -3406,7 +3402,7 @@ private bool functionParameters(Loc loc, Scope* sc, { // allocate the array literal as temporary static array on the stack ale.type = ale.type.nextOf().sarrayOf(ale.elements.length); - auto tmp = copyToTemp(0, "__arrayliteral_on_stack", ale); + auto tmp = copyToTemp(STC.none, "__arrayliteral_on_stack", ale); tmp.storage_class |= STC.exptemp; auto declareTmp = new DeclarationExp(ale.loc, tmp); auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp), @@ -4879,6 +4875,28 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor printf("\tnewtype: %s\n", exp.newtype.toChars()); } + if (exp.placement) + { + exp.placement = exp.placement.expressionSemantic(sc); + auto p = exp.placement; + if (p.op == EXP.error) + return setError(); + if (!p.isLvalue()) + { + error(p.loc, "PlacementExpression `%s` is an rvalue, but must be an lvalue", p.toChars()); + return setError(); + } + if (sc.setUnsafe(false, p.loc, "`@safe` function `%s` cannot use placement `new`", sc.func)) + { + return setError(); + } + if (!exp.placement.type.isNaked()) + { + error(p.loc, "PlacementExpression `%s` of type `%s` be unshared and mutable", p.toChars(), toChars(p.type)); + return setError(); + } + } + //for error messages if the argument in [] is not convertible to size_t const originalNewtype = exp.newtype; @@ -4965,6 +4983,19 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } + uinteger_t placementSize; + if (exp.placement) + { + placementSize = size(exp.placement.type, exp.placement.loc); + auto objectSize = size(tb, exp.placement.loc); + //printf("placementSize: %lld objectSize: %lld\n", placementSize, objectSize); + if (!tb.isTypeClass && placementSize < objectSize) + { + error(exp.placement.loc, "new placement size %llu must be >= object size %llu", placementSize, objectSize); + return setError(); + } + } + const size_t nargs = exp.arguments ? exp.arguments.length : 0; Expression newprefix = null; @@ -4973,9 +5004,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor auto cd = tc.sym; if (cd.errors) return setError(); - cd.size(exp.loc); + auto objectSize = cd.size(exp.loc); if (cd.sizeok != Sizeok.done) return setError(); + if (exp.placement && placementSize < objectSize) + { + error(exp.placement.loc, "new placement size %llu must be >= class object size %llu", placementSize, objectSize); + return setError(); + } if (!cd.ctor) cd.ctor = cd.searchCtor(); if (cd.noDefaultCtor && !nargs && !cd.defaultCtor) @@ -5185,6 +5221,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } else if (sc.needsCodegen() && // interpreter doesn't need this lowered + !exp.placement && !exp.onstack && !exp.type.isScopeClass()) // these won't use the GC { /* replace `new T(arguments)` with `core.lifetime._d_newclassT!T(arguments)` @@ -5290,10 +5327,16 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } exp.type = exp.type.pointerTo(); - tryLowerToNewItem(exp); + if (!exp.placement) + tryLowerToNewItem(exp); } else if (tb.ty == Tarray) { + if (exp.placement) + { + error(exp.placement.loc, "placement new cannot be used with dynamic arrays"); + return setError(); + } if (!nargs) { // https://issues.dlang.org/show_bug.cgi?id=20422 @@ -5364,7 +5407,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor goto LskipNewArrayLowering; } - if (nargs == 1) + if (exp.placement) // no need to lower + { + } + else if (nargs == 1) { auto hook = global.params.tracegc ? Id._d_newarrayTTrace : Id._d_newarrayT; if (!verifyHookExist(exp.loc, *sc, hook, "new array")) @@ -5448,10 +5494,16 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } exp.type = exp.type.pointerTo(); - tryLowerToNewItem(exp); + if (!exp.placement) + tryLowerToNewItem(exp); } else if (tb.ty == Taarray) { + if (exp.placement) + { + error(exp.placement.loc, "placement new cannot be used with associative arrays"); + return setError(); + } // e.g. `new Alias(args)` if (nargs) { @@ -5501,7 +5553,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor sds.members.push(e.cd); } - Expression n = new NewExp(e.loc, e.thisexp, e.cd.type, e.arguments); + Expression n = new NewExp(e.loc, e.placement, e.thisexp, e.cd.type, e.arguments); Expression c = new CommaExp(e.loc, d, n); result = c.expressionSemantic(sc); @@ -5841,6 +5893,19 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor printf("CallExp::semantic() %s\n", exp.toChars()); } + scope (exit) + { + if (TypeFunction tf = exp.f ? cast(TypeFunction)exp.f.type : null) + { + result.rvalue = tf.isRvalue; + if (tf.isRvalue && !tf.isRef) + { + error(exp.f.loc, "`__rvalue` only valid on functions that return by `ref`"); + setError(); + } + } + } + Objects* tiargs = null; // initial list of template arguments Expression ethis = null; Type tthis = null; @@ -6369,7 +6434,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor tthis = ue.e1.type; if (!(exp.f.type.ty == Tfunction && (cast(TypeFunction)exp.f.type).isScopeQual)) { - if (checkParamArgumentEscape(*sc, exp.f, Id.This, exp.f.vthis, STC.undefined_, ethis, false, false)) + if (checkParamArgumentEscape(*sc, exp.f, Id.This, exp.f.vthis, STC.none, ethis, false, false)) return setError(); } } @@ -6851,10 +6916,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor Loc loc = exp.loc; auto vptr = new DotIdExp(loc, new ThisExp(loc), Id.__vptr); - auto vptrTmpDecl = copyToTemp(0, "__vptrTmp", vptr); + auto vptrTmpDecl = copyToTemp(STC.none, "__vptrTmp", vptr); auto declareVptrTmp = new DeclarationExp(loc, vptrTmpDecl); - auto superTmpDecl = copyToTemp(0, "__superTmp", result); + auto superTmpDecl = copyToTemp(STC.none, "__superTmp", result); auto declareSuperTmp = new DeclarationExp(loc, superTmpDecl); auto declareTmps = new CommaExp(loc, declareVptrTmp, declareSuperTmp); @@ -7871,7 +7936,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return res.expressionSemantic(sc); } - const stc = op.isLvalue() ? STC.ref_ : 0; + const stc = op.isLvalue() ? STC.ref_ : STC.none; auto tmp = copyToTemp(stc, "__assertOp", op); tmp.dsymbolSemantic(sc); @@ -8039,7 +8104,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.msg = resolveProperties(sc, exp.msg); exp.msg = exp.msg.implicitCastTo(sc, Type.tchar.constOf().arrayOf()); exp.msg = exp.msg.optimize(WANTvalue); - checkParamArgumentEscape(*sc, null, null, null, STC.undefined_, exp.msg, true, false); + checkParamArgumentEscape(*sc, null, null, null, STC.none, exp.msg, true, false); } if (exp.msg && exp.msg.op == EXP.error) @@ -10149,7 +10214,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* Rewrite as: * auto tmp = e1; ++e1; tmp */ - auto tmp = copyToTemp(0, "__pitmp", exp.e1); + auto tmp = copyToTemp(STC.none, "__pitmp", exp.e1); Expression ea = new DeclarationExp(exp.loc, tmp); Expression eb = exp.e1.syntaxCopy(); @@ -10787,7 +10852,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } } - else if (sd.hasMoveCtor && !e2x.isCallExp() && !e2x.isStructLiteralExp()) + else if (sd.hasMoveCtor && (!e2x.isCallExp() || e2x.rvalue) && !e2x.isStructLiteralExp()) { // #move /* The !e2x.isCallExp() is because it is already an rvalue @@ -11677,7 +11742,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // `__assigntmp` will be destroyed together with the array `ae.e1`. // When `ae.e2` is a variadic arg array, it is also `scope`, so // `__assigntmp` may also be scope. - StorageClass stc = STC.nodtor; + STC stc = STC.nodtor; if (isArrayAssign) stc |= STC.rvalue | STC.scope_; @@ -13020,6 +13085,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor error(exp.loc, "compare not defined for complex operands"); return setError(); } + else if (t1.isTypeFunction() || t2.isTypeFunction()) + { + error(exp.loc, "comparison is not defined for function types"); + return setError(); + } else if (t1.ty == Taarray || t2.ty == Taarray) { error(exp.loc, "`%s` is not defined for associative arrays", EXPtoString(exp.op).ptr); @@ -13325,6 +13395,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } + if (t1.isTypeFunction() || t2.isTypeFunction()) + { + error(exp.loc, "operator `==` is not defined for function types"); + return setError(); + } + if (auto tv = t1.isTypeVector()) exp.type = tv.toBooleanVector(); @@ -13381,6 +13457,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.e2.op == EXP.call) exp.e2 = (cast(CallExp)exp.e2).addDtorHook(sc); + if (exp.e1.type.isTypeFunction() || exp.e2.type.isTypeFunction()) + { + error(exp.loc, "operator `is` is not defined for function types"); + return setError(); + } + if (exp.e1.type.toBasetype().ty == Tsarray || exp.e2.type.toBasetype().ty == Tsarray) deprecation(exp.loc, "identity comparison of static arrays " @@ -14611,7 +14693,7 @@ MATCH matchType(FuncExp funcExp, Type to, Scope* sc, FuncExp* presult, ErrorSink convertMatch = true; auto tfy = new TypeFunction(tfx.parameterList, tof.next, - tfx.linkage, STC.undefined_); + tfx.linkage, STC.none); tfy.mod = tfx.mod; tfy.trust = tfx.trust; tfy.isNothrow = tfx.isNothrow; @@ -14928,6 +15010,8 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false) bool visitNew(NewExp e) { + if (e.placement) + check(e.placement, false); if (e.thisexp) check(e.thisexp, false); return false; @@ -15111,6 +15195,8 @@ Expression resolveLoc(Expression exp, Loc loc, Scope* sc) Expression visitNew(NewExp exp) { + if (exp.placement) + exp.placement = exp.placement.resolveLoc(loc, sc); if (exp.thisexp) exp.thisexp = exp.thisexp.resolveLoc(loc, sc); if (exp.argprefix) @@ -15332,7 +15418,7 @@ Expression addDtorHook(Expression e, Scope* sc) buf[0 .. prefix.length] = prefix; buf[prefix.length .. len] = ident[0 .. len - prefix.length]; - auto tmp = copyToTemp(0, buf[0 .. len], exp); + auto tmp = copyToTemp(STC.none, buf[0 .. len], exp); Expression ae = new DeclarationExp(exp.loc, tmp); Expression e = new CommaExp(exp.loc, ae, new VarExp(exp.loc, tmp)); e = e.expressionSemantic(sc); @@ -15365,7 +15451,7 @@ Expression addDtorHook(Expression e, Scope* sc) /* Type needs destruction, so declare a tmp * which the back end will recognize and call dtor on */ - auto tmp = copyToTemp(0, Id.__tmpfordtor.toString(), exp); + auto tmp = copyToTemp(STC.none, Id.__tmpfordtor.toString(), exp); auto de = new DeclarationExp(exp.loc, tmp); auto ve = new VarExp(exp.loc, tmp); Expression e = new CommaExp(exp.loc, de, ve); @@ -17346,3 +17432,243 @@ bool fill(StructDeclaration sd, Loc loc, ref Expressions elements, bool ctorinit return !errors; } + +/***************************************** +* Lower any aggregate that is not an array to an array using a +* regular foreach loop within CTFE. If there are multiple +* `static foreach` loop variables, an array of tuples is +* generated. In thise case, the field `needExpansion` is set to +* true to indicate that the static foreach loop expansion will +* need to expand the tuples into multiple variables. +* +* For example, `static foreach (x; range) { ... }` is lowered to: +* +* static foreach (x; { +* typeof({ +* foreach (x; range) return x; +* }())[] __res; +* foreach (x; range) __res ~= x; +* return __res; +* }()) { ... } +* +* Finally, call `lowerArrayAggregate` to turn the produced +* array into an expression tuple. +* +* Params: +* sfe = The 'static foreach'. +* sc = The current scope. +*/ +extern (C++) void lowerNonArrayAggregate(StaticForeach sfe, Scope* sc) +{ + import dmd.statement; + + auto nvars = sfe.aggrfe ? sfe.aggrfe.parameters.length : 1; + auto aloc = sfe.aggrfe ? sfe.aggrfe.aggr.loc : sfe.rangefe.lwr.loc; + // We need three sets of foreach loop variables because the + // lowering contains three foreach loops. + Parameters*[3] pparams = [new Parameters(), new Parameters(), new Parameters()]; + foreach (i; 0 .. nvars) + { + foreach (params; pparams) + { + auto p = sfe.aggrfe ? (*sfe.aggrfe.parameters)[i] : sfe.rangefe.param; + params.push(new Parameter(aloc, p.storageClass, p.type, p.ident, null, null)); + } + } + Expression[2] res; + TypeStruct tplty = null; + if (nvars == 1) // only one `static foreach` variable, generate identifiers. + { + foreach (i; 0 .. 2) + { + res[i] = new IdentifierExp(aloc, (*pparams[i])[0].ident); + } + } + else // multiple `static foreach` variables, generate tuples. + { + foreach (i; 0 .. 2) + { + auto e = new Expressions(pparams[0].length); + foreach (j, ref elem; *e) + { + auto p = (*pparams[i])[j]; + elem = new IdentifierExp(aloc, p.ident); + } + if (!tplty) + { + tplty = sfe.createTupleType(aloc, e, sc); + } + res[i] = sfe.createTuple(aloc, tplty, e); + } + sfe.needExpansion = true; // need to expand the tuples later + } + // generate remaining code for the new aggregate which is an + // array (see documentation comment). + if (sfe.rangefe) + { + sc = sc.startCTFE(); + sfe.rangefe.lwr = sfe.rangefe.lwr.expressionSemantic(sc); + sfe.rangefe.lwr = resolveProperties(sc, sfe.rangefe.lwr); + sfe.rangefe.upr = sfe.rangefe.upr.expressionSemantic(sc); + sfe.rangefe.upr = resolveProperties(sc, sfe.rangefe.upr); + sc = sc.endCTFE(); + sfe.rangefe.lwr = sfe.rangefe.lwr.optimize(WANTvalue); + sfe.rangefe.lwr = sfe.rangefe.lwr.ctfeInterpret(); + sfe.rangefe.upr = sfe.rangefe.upr.optimize(WANTvalue); + sfe.rangefe.upr = sfe.rangefe.upr.ctfeInterpret(); + } + auto s1 = new Statements(); + auto stmts = new Statements(); + if (tplty) stmts.push(new ExpStatement(sfe.loc, tplty.sym)); + stmts.push(new ReturnStatement(aloc, res[0])); + s1.push(sfe.createForeach(aloc, pparams[0], new CompoundStatement(aloc, stmts))); + s1.push(new ExpStatement(aloc, new AssertExp(aloc, IntegerExp.literal!0))); + Type ety = new TypeTypeof(aloc, sfe.wrapAndCall(aloc, new CompoundStatement(aloc, s1))); + auto aty = ety.arrayOf(); + auto idres = Identifier.generateId("__res"); + auto vard = new VarDeclaration(aloc, aty, idres, null, STC.temp); + auto s2 = new Statements(); + + // Run 'typeof' gagged to avoid duplicate errors and if it fails just create + // an empty foreach to expose them. + const olderrors = global.startGagging(); + ety = ety.typeSemantic(aloc, sc); + if (global.endGagging(olderrors)) + s2.push(sfe.createForeach(aloc, pparams[1], null)); + else + { + s2.push(new ExpStatement(aloc, vard)); + auto catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]); + s2.push(sfe.createForeach(aloc, pparams[1], new ExpStatement(aloc, catass))); + s2.push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres))); + } + + Expression aggr = void; + Type indexty = void; + + if (sfe.rangefe && (indexty = ety).isIntegral()) + { + sfe.rangefe.lwr.type = indexty; + sfe.rangefe.upr.type = indexty; + auto lwrRange = getIntRange(sfe.rangefe.lwr); + auto uprRange = getIntRange(sfe.rangefe.upr); + + const lwr = sfe.rangefe.lwr.toInteger(); + auto upr = sfe.rangefe.upr.toInteger(); + size_t length = 0; + + if (lwrRange.imin <= uprRange.imax) + length = cast(size_t) (upr - lwr); + + auto exps = new Expressions(length); + + if (sfe.rangefe.op == TOK.foreach_) + { + foreach (i; 0 .. length) + (*exps)[i] = new IntegerExp(aloc, lwr + i, indexty); + } + else + { + --upr; + foreach (i; 0 .. length) + (*exps)[i] = new IntegerExp(aloc, upr - i, indexty); + } + aggr = new ArrayLiteralExp(aloc, indexty.arrayOf(), exps); + } + else + { + aggr = sfe.wrapAndCall(aloc, new CompoundStatement(aloc, s2)); + sc = sc.startCTFE(); + aggr = aggr.expressionSemantic(sc); + aggr = resolveProperties(sc, aggr); + sc = sc.endCTFE(); + aggr = aggr.optimize(WANTvalue); + aggr = aggr.ctfeInterpret(); + } + + assert(!!sfe.aggrfe ^ !!sfe.rangefe); + sfe.aggrfe = new ForeachStatement(sfe.loc, TOK.foreach_, pparams[2], aggr, + sfe.aggrfe ? sfe.aggrfe._body : sfe.rangefe._body, + sfe.aggrfe ? sfe.aggrfe.endloc : sfe.rangefe.endloc); + sfe.rangefe = null; + sfe.lowerArrayAggregate(sc); // finally, turn generated array into expression tuple +} + +/***************************************** +* Perform `static foreach` lowerings that are necessary in order +* to finally expand the `static foreach` using +* `dmd.statementsem.makeTupleForeach`. +*/ +extern(D) void prepare(StaticForeach sfe, Scope* sc) +{ + assert(sc); + + if (sfe.aggrfe) + { + sc = sc.startCTFE(); + sfe.aggrfe.aggr = sfe.aggrfe.aggr.expressionSemantic(sc); + sc = sc.endCTFE(); + } + + if (sfe.aggrfe && sfe.aggrfe.aggr.type.toBasetype().ty == Terror) + { + return; + } + + if (!sfe.ready()) + { + if (sfe.aggrfe && sfe.aggrfe.aggr.type.toBasetype().ty == Tarray) + { + sfe.lowerArrayAggregate(sc); + } + else + { + sfe.lowerNonArrayAggregate(sc); + } + } +} + +/***************************************** + * Turn an aggregate which is an array into an expression tuple + * of its elements. I.e., lower + * static foreach (x; [1, 2, 3, 4]) { ... } + * to + * static foreach (x; AliasSeq!(1, 2, 3, 4)) { ... } + */ +extern(D) void lowerArrayAggregate(StaticForeach sfe, Scope* sc) +{ + auto aggr = sfe.aggrfe.aggr; + Expression el = new ArrayLengthExp(aggr.loc, aggr); + sc = sc.startCTFE(); + el = el.expressionSemantic(sc); + sc = sc.endCTFE(); + el = el.optimize(WANTvalue); + el = el.ctfeInterpret(); + if (el.op != EXP.int64) + { + sfe.aggrfe.aggr = ErrorExp.get(); + return; + } + + Expressions* es; + if (auto ale = aggr.isArrayLiteralExp()) + { + // Directly use the elements of the array for the TupleExp creation + es = ale.elements; + } + else + { + const length = cast(size_t)el.toInteger(); + es = new Expressions(length); + foreach (i; 0 .. length) + { + auto index = new IntegerExp(sfe.loc, i, Type.tsize_t); + auto value = new IndexExp(aggr.loc, aggr, index); + (*es)[i] = value; + } + } + sfe.aggrfe.aggr = new TupleExp(aggr.loc, es); + sfe.aggrfe.aggr = sfe.aggrfe.aggr.expressionSemantic(sc); + sfe.aggrfe.aggr = sfe.aggrfe.aggr.optimize(WANTvalue); + sfe.aggrfe.aggr = sfe.aggrfe.aggr.ctfeInterpret(); +} diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index e5b72e2..7c36823 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -235,7 +235,7 @@ extern (C++) class FuncDeclaration : Declaration */ Type tintro; - StorageClass storage_class2; /// storage class for template onemember's + STC storage_class2; /// storage class for template onemember's // Things that should really go into Scope @@ -296,9 +296,9 @@ extern (C++) class FuncDeclaration : Declaration */ ObjcFuncDeclaration objc; - extern (D) this(Loc loc, Loc endloc, Identifier ident, StorageClass storage_class, Type type, bool noreturn = false) + extern (D) this(Loc loc, Loc endloc, Identifier ident, STC storage_class, Type type, bool noreturn = false) { - super(loc, ident); + super(DSYM.funcDeclaration, loc, ident); //.printf("FuncDeclaration(id = '%s', type = %s)\n", ident.toChars(), type.toChars()); //.printf("storage_class = x%llx\n", storage_class); this.storage_class = storage_class; @@ -322,7 +322,7 @@ extern (C++) class FuncDeclaration : Declaration static FuncDeclaration create(Loc loc, Loc endloc, Identifier id, StorageClass storage_class, Type type, bool noreturn = false) { - return new FuncDeclaration(loc, endloc, id, storage_class, type, noreturn); + return new FuncDeclaration(loc, endloc, id, cast(STC) storage_class, type, noreturn); } final nothrow pure @safe @@ -1006,12 +1006,12 @@ extern (C++) class FuncDeclaration : Declaration /********************************** * Generate a FuncDeclaration for a runtime library function. */ - static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = 0) + extern (D) static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, STC stc = STC.none) { return genCfunc(fparams, treturn, Identifier.idPool(name[0 .. strlen(name)]), stc); } - static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, StorageClass stc = 0) + extern (D) static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, Identifier id, STC stc = STC.none) { FuncDeclaration fd; TypeFunction tf; @@ -1043,11 +1043,6 @@ extern (C++) class FuncDeclaration : Declaration return fd; } - override final inout(FuncDeclaration) isFuncDeclaration() inout - { - return this; - } - inout(FuncDeclaration) toAliasFunc() inout @safe { return this; @@ -1243,6 +1238,7 @@ extern (C++) final class FuncAliasDeclaration : FuncDeclaration super(funcalias.loc, funcalias.endloc, ident, funcalias.storage_class, funcalias.type); assert(funcalias != this); this.funcalias = funcalias; + this.dsym = DSYM.funcAliasDeclaration; this.hasOverloads = hasOverloads; if (hasOverloads) @@ -1259,11 +1255,6 @@ extern (C++) final class FuncAliasDeclaration : FuncDeclaration userAttribDecl = funcalias.userAttribDecl; } - override inout(FuncAliasDeclaration) isFuncAliasDeclaration() inout - { - return this; - } - override const(char)* kind() const { return "function alias"; @@ -1290,9 +1281,10 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration // backend bool deferToObj; - extern (D) this(Loc loc, Loc endloc, Type type, TOK tok, ForeachStatement fes, Identifier id = null, StorageClass storage_class = STC.undefined_) + extern (D) this(Loc loc, Loc endloc, Type type, TOK tok, ForeachStatement fes, Identifier id = null, STC storage_class = STC.none) { super(loc, endloc, null, storage_class, type); + this.dsym = DSYM.funcLiteralDeclaration; this.ident = id ? id : Id.empty; this.tok = tok; this.fes = fes; @@ -1338,11 +1330,6 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration return false; } - override inout(FuncLiteralDeclaration) isFuncLiteralDeclaration() inout - { - return this; - } - override const(char)* kind() const { // GCC requires the (char*) casts @@ -1371,9 +1358,10 @@ extern (C++) final class CtorDeclaration : FuncDeclaration { bool isCpCtor; // copy constructor bool isMoveCtor; // move constructor (aka rvalue constructor) - extern (D) this(Loc loc, Loc endloc, StorageClass stc, Type type) + extern (D) this(Loc loc, Loc endloc, STC stc, Type type) { super(loc, endloc, Id.ctor, stc, type); + this.dsym = DSYM.ctorDeclaration; //printf("CtorDeclaration(loc = %s) %s %p\n", loc.toChars(), toChars(), this); } @@ -1405,11 +1393,6 @@ extern (C++) final class CtorDeclaration : FuncDeclaration return (isThis() && vthis && global.params.useInvariants == CHECKENABLE.on); } - override inout(CtorDeclaration) isCtorDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1420,9 +1403,10 @@ extern (C++) final class CtorDeclaration : FuncDeclaration */ extern (C++) final class PostBlitDeclaration : FuncDeclaration { - extern (D) this(Loc loc, Loc endloc, StorageClass stc, Identifier id) + extern (D) this(Loc loc, Loc endloc, STC stc, Identifier id) { super(loc, endloc, id, stc, null); + this.dsym = DSYM.postBlitDeclaration; } override PostBlitDeclaration syntaxCopy(Dsymbol s) @@ -1453,11 +1437,6 @@ extern (C++) final class PostBlitDeclaration : FuncDeclaration return false; // cannot overload postblits } - override inout(PostBlitDeclaration) isPostBlitDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1470,12 +1449,14 @@ extern (C++) final class DtorDeclaration : FuncDeclaration { extern (D) this(Loc loc, Loc endloc) { - super(loc, endloc, Id.dtor, STC.undefined_, null); + super(loc, endloc, Id.dtor, STC.none, null); + this.dsym = DSYM.dtorDeclaration; } - extern (D) this(Loc loc, Loc endloc, StorageClass stc, Identifier id) + extern (D) this(Loc loc, Loc endloc, STC stc, Identifier id) { super(loc, endloc, id, stc, null); + this.dsym = DSYM.dtorDeclaration; } override DtorDeclaration syntaxCopy(Dsymbol s) @@ -1513,11 +1494,6 @@ extern (C++) final class DtorDeclaration : FuncDeclaration return false; // cannot overload destructors } - override inout(DtorDeclaration) isDtorDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1528,14 +1504,16 @@ extern (C++) final class DtorDeclaration : FuncDeclaration */ extern (C++) class StaticCtorDeclaration : FuncDeclaration { - extern (D) this(Loc loc, Loc endloc, StorageClass stc) + extern (D) this(Loc loc, Loc endloc, STC stc) { super(loc, endloc, Identifier.generateIdWithLoc("_staticCtor", loc), STC.static_ | stc, null); + this.dsym = DSYM.staticCtorDeclaration; } - extern (D) this(Loc loc, Loc endloc, string name, StorageClass stc) + extern (D) this(Loc loc, Loc endloc, string name, STC stc) { super(loc, endloc, Identifier.generateIdWithLoc(name, loc), STC.static_ | stc, null); + this.dsym = DSYM.staticCtorDeclaration; } override StaticCtorDeclaration syntaxCopy(Dsymbol s) @@ -1566,16 +1544,6 @@ extern (C++) class StaticCtorDeclaration : FuncDeclaration return false; } - override final bool hasStaticCtorOrDtor() @nogc nothrow pure @safe - { - return true; - } - - override final inout(StaticCtorDeclaration) isStaticCtorDeclaration() inout @nogc nothrow pure @safe - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1589,9 +1557,10 @@ extern (C++) final class SharedStaticCtorDeclaration : StaticCtorDeclaration /// Exclude this constructor from cyclic dependency check bool standalone; - extern (D) this(Loc loc, Loc endloc, StorageClass stc) + extern (D) this(Loc loc, Loc endloc, STC stc) { super(loc, endloc, "_sharedStaticCtor", stc); + this.dsym = DSYM.sharedStaticCtorDeclaration; } override SharedStaticCtorDeclaration syntaxCopy(Dsymbol s) @@ -1602,11 +1571,6 @@ extern (C++) final class SharedStaticCtorDeclaration : StaticCtorDeclaration return scd; } - override inout(SharedStaticCtorDeclaration) isSharedStaticCtorDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1619,14 +1583,16 @@ extern (C++) class StaticDtorDeclaration : FuncDeclaration { VarDeclaration vgate; // 'gate' variable - extern (D) this(Loc loc, Loc endloc, StorageClass stc) + extern (D) this(Loc loc, Loc endloc, STC stc) { super(loc, endloc, Identifier.generateIdWithLoc("_staticDtor", loc), STC.static_ | stc, null); + this.dsym = DSYM.staticDtorDeclaration; } - extern (D) this(Loc loc, Loc endloc, string name, StorageClass stc) + extern (D) this(Loc loc, Loc endloc, string name, STC stc) { super(loc, endloc, Identifier.generateIdWithLoc(name, loc), STC.static_ | stc, null); + this.dsym = DSYM.staticDtorDeclaration; } override StaticDtorDeclaration syntaxCopy(Dsymbol s) @@ -1647,11 +1613,6 @@ extern (C++) class StaticDtorDeclaration : FuncDeclaration return false; } - override final bool hasStaticCtorOrDtor() - { - return true; - } - override final bool addPreInvariant() { return false; @@ -1662,11 +1623,6 @@ extern (C++) class StaticDtorDeclaration : FuncDeclaration return false; } - override final inout(StaticDtorDeclaration) isStaticDtorDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1677,9 +1633,10 @@ extern (C++) class StaticDtorDeclaration : FuncDeclaration */ extern (C++) final class SharedStaticDtorDeclaration : StaticDtorDeclaration { - extern (D) this(Loc loc, Loc endloc, StorageClass stc) + extern (D) this(Loc loc, Loc endloc, STC stc) { super(loc, endloc, "_sharedStaticDtor", stc); + this.dsym = DSYM.sharedStaticDtorDeclaration; } override SharedStaticDtorDeclaration syntaxCopy(Dsymbol s) @@ -1690,11 +1647,6 @@ extern (C++) final class SharedStaticDtorDeclaration : StaticDtorDeclaration return sdd; } - override inout(SharedStaticDtorDeclaration) isSharedStaticDtorDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1705,11 +1657,12 @@ extern (C++) final class SharedStaticDtorDeclaration : StaticDtorDeclaration */ extern (C++) final class InvariantDeclaration : FuncDeclaration { - extern (D) this(Loc loc, Loc endloc, StorageClass stc, Identifier id, Statement fbody) + extern (D) this(Loc loc, Loc endloc, STC stc, Identifier id, Statement fbody) { // Make a unique invariant for now; we'll fix it up as we add it to the aggregate invariant list. super(loc, endloc, id ? id : Identifier.generateId("__invariant"), stc, null); this.fbody = fbody; + this.dsym = DSYM.invariantDeclaration; } override InvariantDeclaration syntaxCopy(Dsymbol s) @@ -1735,11 +1688,6 @@ extern (C++) final class InvariantDeclaration : FuncDeclaration return false; } - override inout(InvariantDeclaration) isInvariantDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1765,10 +1713,11 @@ extern (C++) final class UnitTestDeclaration : FuncDeclaration // toObjFile() these nested functions after this one FuncDeclarations deferredNested; - extern (D) this(Loc loc, Loc endloc, StorageClass stc, char* codedoc) + extern (D) this(Loc loc, Loc endloc, STC stc, char* codedoc) { super(loc, endloc, Identifier.generateIdWithLoc("__unittest", loc), stc, null); this.codedoc = codedoc; + this.dsym = DSYM.unitTestDeclaration; } override UnitTestDeclaration syntaxCopy(Dsymbol s) @@ -1799,11 +1748,6 @@ extern (C++) final class UnitTestDeclaration : FuncDeclaration return false; } - override inout(UnitTestDeclaration) isUnitTestDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); @@ -1814,9 +1758,10 @@ extern (C++) final class UnitTestDeclaration : FuncDeclaration */ extern (C++) final class NewDeclaration : FuncDeclaration { - extern (D) this(Loc loc, StorageClass stc) + extern (D) this(Loc loc, STC stc) { super(loc, Loc.initial, Id.classNew, STC.static_ | stc, null); + this.dsym = DSYM.newDeclaration; } override NewDeclaration syntaxCopy(Dsymbol s) @@ -1847,11 +1792,6 @@ extern (C++) final class NewDeclaration : FuncDeclaration return false; } - override inout(NewDeclaration) isNewDeclaration() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/funcsem.d b/gcc/d/dmd/funcsem.d index 4658a5a..113d28f 100644 --- a/gcc/d/dmd/funcsem.d +++ b/gcc/d/dmd/funcsem.d @@ -1275,6 +1275,7 @@ extern (D) void declareThis(FuncDeclaration fd, Scope* sc) const bool dualCtx = (fd.toParent2() != fd.toParentLocal()); if (dualCtx) fd.hasDualContext = true; + auto ad = fd.isThis(); if (!dualCtx && !ad && !fd.isNested()) { @@ -1369,7 +1370,7 @@ int findVtblIndex(FuncDeclaration fd, Dsymbol[] vtbl) import dmd.typesem : covariant; FuncDeclaration mismatch = null; - StorageClass mismatchstc = 0; + STC mismatchstc = STC.none; int mismatchvi = -1; int exactvi = -1; int bestvi = -1; @@ -1401,7 +1402,7 @@ int findVtblIndex(FuncDeclaration fd, Dsymbol[] vtbl) continue; } - StorageClass stc = 0; + STC stc = STC.none; const cov = fd.type.covariant(fdv.type, &stc); //printf("\tbaseclass cov = %d\n", cov); final switch (cov) @@ -1428,7 +1429,7 @@ int findVtblIndex(FuncDeclaration fd, Dsymbol[] vtbl) } if (fd._linkage == LINK.cpp && bestvi != -1) { - StorageClass stc = 0; + STC stc = STC.none; FuncDeclaration fdv = vtbl[bestvi].isFuncDeclaration(); assert(fdv && fdv.ident == fd.ident); if (fd.type.covariant(fdv.type, &stc, /*cppCovariant=*/true) == Covariant.no) @@ -2648,7 +2649,7 @@ void buildEnsureRequire(FuncDeclaration thisfd) tf.isNogc = f.isNogc; tf.purity = f.purity; tf.trust = f.trust; - auto fd = new FuncDeclaration(loc, loc, Id.require, STC.undefined_, tf); + auto fd = new FuncDeclaration(loc, loc, Id.require, STC.none, tf); fd.fbody = thisfd.frequire; Statement s1 = new ExpStatement(loc, fd); Expression e = new CallExp(loc, new VarExp(loc, fd, false), thisfd.fdrequireParams); @@ -2689,7 +2690,7 @@ void buildEnsureRequire(FuncDeclaration thisfd) tf.isNogc = f.isNogc; tf.purity = f.purity; tf.trust = f.trust; - auto fd = new FuncDeclaration(loc, loc, Id.ensure, STC.undefined_, tf); + auto fd = new FuncDeclaration(loc, loc, Id.ensure, STC.none, tf); fd.fbody = thisfd.fensure; Statement s1 = new ExpStatement(loc, fd); Expression e = new CallExp(loc, new VarExp(loc, fd, false), thisfd.fdensureParams); diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index 0ef955a..62f49a0 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -429,7 +429,7 @@ private void statementToBuffer(Statement s, ref OutBuffer buf, ref HdrGenState h if (p) { // Print condition assignment - StorageClass stc = p.storageClass; + STC stc = p.storageClass; if (!p.type && !stc) stc = STC.auto_; if (stcToBuffer(buf, stc)) @@ -2531,6 +2531,13 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt buf.writeByte('.'); } buf.writestring("new "); + if (e.placement) + { + buf.writeByte('('); + expToBuffer(e.placement, PREC.assign, buf, hgs); + buf.writeByte(')'); + buf.writeByte(' '); + } typeToBuffer(e.newtype, null, buf, hgs); if (e.arguments && e.arguments.length) { @@ -2548,6 +2555,13 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt buf.writeByte('.'); } buf.writestring("new"); + if (e.placement) + { + buf.writeByte(' '); + buf.writeByte('('); + expToBuffer(e.placement, PREC.assign, buf, hgs); + buf.writeByte(')'); + } buf.writestring(" class "); if (e.arguments && e.arguments.length) { @@ -3283,7 +3297,7 @@ void toCBuffer(const Initializer iz, ref OutBuffer buf, ref HdrGenState hgs) initializerToBuffer(cast() iz, buf, hgs); } -bool stcToBuffer(ref OutBuffer buf, StorageClass stc) @safe +bool stcToBuffer(ref OutBuffer buf, STC stc) @safe { //printf("stc: %llx\n", stc); bool result = false; @@ -3349,11 +3363,11 @@ bool stcToBuffer(ref OutBuffer buf, StorageClass stc) @safe * and return a string representation of it. * stc is reduced by the one picked. */ -string stcToString(ref StorageClass stc) @safe +string stcToString(ref STC stc) @safe { static struct SCstring { - StorageClass stc; + STC stc; string id; } @@ -3396,7 +3410,7 @@ string stcToString(ref StorageClass stc) @safe ]; foreach (ref entry; table) { - const StorageClass tbl = entry.stc; + const STC tbl = entry.stc; assert(tbl & STC.visibleStorageClasses); if (stc & tbl) { @@ -3629,7 +3643,7 @@ private void parameterToBuffer(Parameter p, ref OutBuffer buf, ref HdrGenState h if (p.storageClass & STC.auto_) buf.writestring("auto "); - StorageClass stc = p.storageClass; + STC stc = p.storageClass; if (p.storageClass & STC.in_) { buf.writestring("in "); diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h index bfbb551..dc41a00 100644 --- a/gcc/d/dmd/import.h +++ b/gcc/d/dmd/import.h @@ -44,6 +44,5 @@ public: Dsymbol *toAlias() override; bool overloadInsert(Dsymbol *s) override; - Import *isImport() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d index 4900320..753c70a 100644 --- a/gcc/d/dmd/json.d +++ b/gcc/d/dmd/json.d @@ -333,7 +333,7 @@ public: } } - extern(D) void propertyStorageClass(const char[] name, StorageClass stc) + extern(D) void propertyStorageClass(const char[] name, STC stc) { stc &= STC.visibleStorageClasses; if (stc) diff --git a/gcc/d/dmd/mangle/package.d b/gcc/d/dmd/mangle/package.d index d184fe9..de4d45f 100644 --- a/gcc/d/dmd/mangle/package.d +++ b/gcc/d/dmd/mangle/package.d @@ -451,7 +451,7 @@ void mangleParameter(Parameter p, ref OutBuffer buf, ref Backref backref) switch (stc & ((STC.IOR | STC.lazy_) & ~STC.constscoperef)) { - case 0: + case STC.none: break; case STC.in_: buf.writeByte('I'); diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h index 82e1b4a..ec1a11b 100644 --- a/gcc/d/dmd/module.h +++ b/gcc/d/dmd/module.h @@ -47,8 +47,6 @@ public: bool equals(const RootObject * const o) const override; - Package *isPackage() override final { return this; } - bool isAncestorPackageOf(const Package * const pkg) const; void accept(Visitor *v) override { v->visit(this); } @@ -158,7 +156,6 @@ public: void *ctfe_cov; // stores coverage information from ctfe - Module *isModule() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 84899d0..b527631 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -232,9 +232,9 @@ unittest /************************************ * Convert MODxxxx to STCxxx */ -StorageClass ModToStc(uint mod) pure nothrow @nogc @safe +STC ModToStc(uint mod) pure nothrow @nogc @safe { - StorageClass stc = 0; + STC stc = STC.none; if (mod & MODFlags.immutable_) stc |= STC.immutable_; if (mod & MODFlags.const_) @@ -1108,7 +1108,7 @@ extern (C++) abstract class Type : ASTNode * Apply STCxxxx bits to existing type. * Use *before* semantic analysis is run. */ - extern (D) final Type addSTC(StorageClass stc) + extern (D) final Type addSTC(STC stc) { Type t = this; if (t.isImmutable()) @@ -2488,6 +2488,7 @@ extern (C++) final class TypeFunction : TypeNext bool isInOutQual; /// inout on the qualifier bool isCtor; /// the function is a constructor bool isReturnScope; /// `this` is returned by value + bool isRvalue; /// returned reference should be treated as rvalue } import dmd.common.bitfields : generateBitFields; @@ -2499,7 +2500,7 @@ extern (C++) final class TypeFunction : TypeNext byte inuse; ArgumentList inferenceArguments; // function arguments to determine `auto ref` in type semantic - extern (D) this(ParameterList pl, Type treturn, LINK linkage, StorageClass stc = 0) @safe + extern (D) this(ParameterList pl, Type treturn, LINK linkage, STC stc = STC.none) @safe { super(Tfunction, treturn); //if (!treturn) *(char*)0=0; @@ -2531,6 +2532,8 @@ extern (C++) final class TypeFunction : TypeNext this.isScopeQual = true; if (stc & STC.scopeinferred) this.isScopeInferred = true; + if (stc & STC.rvalue) + this.isRvalue = true; this.trust = TRUST.default_; if (stc & STC.safe) @@ -2541,9 +2544,9 @@ extern (C++) final class TypeFunction : TypeNext this.trust = TRUST.trusted; } - static TypeFunction create(Parameters* parameters, Type treturn, ubyte varargs, LINK linkage, StorageClass stc = 0) @safe + static TypeFunction create(Parameters* parameters, Type treturn, ubyte varargs, LINK linkage, StorageClass stc = STC.none) @safe { - return new TypeFunction(ParameterList(parameters, cast(VarArg)varargs), treturn, linkage, stc); + return new TypeFunction(ParameterList(parameters, cast(VarArg)varargs), treturn, linkage, cast(STC) stc); } override const(char)* kind() const @@ -2567,6 +2570,7 @@ extern (C++) final class TypeFunction : TypeNext t.isScopeQual = isScopeQual; t.isReturnInferred = isReturnInferred; t.isScopeInferred = isScopeInferred; + t.isRvalue = isRvalue; t.isInOutParam = isInOutParam; t.isInOutQual = isInOutQual; t.trust = trust; @@ -3548,7 +3552,7 @@ extern (C++) final class TypeTuple : Type { Expression e = (*exps)[i]; assert(e.type.ty != Ttuple); - auto arg = new Parameter(e.loc, STC.undefined_, e.type, null, null, null); + auto arg = new Parameter(e.loc, STC.none, e.type, null, null, null); (*arguments)[i] = arg; } this.arguments = arguments; @@ -3573,15 +3577,15 @@ extern (C++) final class TypeTuple : Type { super(Ttuple); arguments = new Parameters(); - arguments.push(new Parameter(Loc.initial, 0, t1, null, null, null)); + arguments.push(new Parameter(Loc.initial, STC.none, t1, null, null, null)); } extern (D) this(Type t1, Type t2) { super(Ttuple); arguments = new Parameters(); - arguments.push(new Parameter(Loc.initial, 0, t1, null, null, null)); - arguments.push(new Parameter(Loc.initial, 0, t2, null, null, null)); + arguments.push(new Parameter(Loc.initial, STC.none, t1, null, null, null)); + arguments.push(new Parameter(Loc.initial, STC.none, t2, null, null, null)); } static TypeTuple create() @safe @@ -3806,11 +3810,11 @@ extern (C++) struct ParameterList { /// The raw (unexpanded) formal parameters, possibly containing tuples. Parameters* parameters; - StorageClass stc; // storage class of ... + STC stc; // storage class of ... VarArg varargs = VarArg.none; bool hasIdentifierList; // true if C identifier-list style - this(Parameters* parameters, VarArg varargs = VarArg.none, StorageClass stc = 0) @safe + this(Parameters* parameters, VarArg varargs = VarArg.none, STC stc = STC.none) @safe { this.parameters = parameters; this.varargs = varargs; @@ -3909,13 +3913,13 @@ extern (C++) final class Parameter : ASTNode import dmd.attrib : UserAttributeDeclaration; Loc loc; - StorageClass storageClass; + STC storageClass; Type type; Identifier ident; Expression defaultArg; UserAttributeDeclaration userAttribDecl; // user defined attributes - extern (D) this(Loc loc, StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe + extern (D) this(Loc loc, STC storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe { this.loc = loc; this.type = type; @@ -3927,7 +3931,7 @@ extern (C++) final class Parameter : ASTNode static Parameter create(Loc loc, StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe { - return new Parameter(loc, storageClass, type, ident, defaultArg, userAttribDecl); + return new Parameter(loc, cast(STC) storageClass, type, ident, defaultArg, userAttribDecl); } Parameter syntaxCopy() @@ -4139,21 +4143,21 @@ extern (C++) final class Parameter : ASTNode bool isCovariant(bool returnByRef, const Parameter p) const pure nothrow @nogc @safe { - ulong thisSTC = this.storageClass; - ulong otherSTC = p.storageClass; + STC thisSTC = this.storageClass; + STC otherSTC = p.storageClass; if (thisSTC & STC.constscoperef) thisSTC |= STC.scope_; if (otherSTC & STC.constscoperef) otherSTC |= STC.scope_; - const mask = STC.ref_ | STC.out_ | STC.lazy_ | (((thisSTC | otherSTC) & STC.constscoperef) ? STC.in_ : 0); + const mask = STC.ref_ | STC.out_ | STC.lazy_ | (((thisSTC | otherSTC) & STC.constscoperef) ? STC.in_ : STC.none); if ((thisSTC & mask) != (otherSTC & mask)) return false; return isCovariantScope(returnByRef, thisSTC, otherSTC); } - extern (D) static bool isCovariantScope(bool returnByRef, StorageClass from, StorageClass to) pure nothrow @nogc @safe + extern (D) static bool isCovariantScope(bool returnByRef, STC from, STC to) pure nothrow @nogc @safe { // Workaround for failing covariance when finding a common type of delegates, // some of which have parameters with inferred scope @@ -4340,21 +4344,21 @@ bool isIndexableNonAggregate(Type t) /*************************************** * Computes how a parameter may be returned. - * Shrinking the representation is necessary because StorageClass is so wide + * Shrinking the representation is necessary because STC is so wide * Params: * stc = storage class of parameter * Returns: * value from enum ScopeRef */ -ScopeRef buildScopeRef(StorageClass stc) pure nothrow @nogc @safe +ScopeRef buildScopeRef(STC stc) pure nothrow @nogc @safe { if (stc & STC.out_) stc |= STC.ref_; // treat `out` and `ref` the same ScopeRef result; - final switch (stc & (STC.ref_ | STC.scope_ | STC.return_)) + switch (stc & (STC.ref_ | STC.scope_ | STC.return_)) { - case 0: result = ScopeRef.None; break; + case STC.none: result = ScopeRef.None; break; /* can occur in case test/compilable/testsctreturn.d * related to https://issues.dlang.org/show_bug.cgi?id=20149 @@ -4372,6 +4376,8 @@ ScopeRef buildScopeRef(StorageClass stc) pure nothrow @nogc @safe result = stc & STC.returnScope ? ScopeRef.Ref_ReturnScope : ScopeRef.ReturnRef_Scope; break; + default: + assert(0); } return result; } diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index 1dd6a27..6515e96 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -137,6 +137,8 @@ public: override void visit(NewExp e) { + if (e.placement) + return; // placement new doesn't use the GC if (e.member && !e.member.isNogc() && f.setGC(e.loc, null)) { // @nogc-ness is already checked in NewExp::semantic diff --git a/gcc/d/dmd/nspace.d b/gcc/d/dmd/nspace.d index 0014ec6..35d7835 100644 --- a/gcc/d/dmd/nspace.d +++ b/gcc/d/dmd/nspace.d @@ -66,6 +66,7 @@ extern (C++) final class Nspace : ScopeDsymbol { super(loc, ident); //printf("Nspace::Nspace(ident = %s)\n", ident.toChars()); + this.dsym = DSYM.nspace; this.members = members; this.identExp = identExp; } @@ -88,11 +89,6 @@ extern (C++) final class Nspace : ScopeDsymbol return "namespace"; } - override inout(Nspace) isNspace() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h index cbee2fb..db5c47f 100644 --- a/gcc/d/dmd/nspace.h +++ b/gcc/d/dmd/nspace.h @@ -23,6 +23,5 @@ class Nspace final : public ScopeDsymbol Nspace *syntaxCopy(Dsymbol *s) override; bool hasPointers() override; const char *kind() const override; - Nspace *isNspace() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/ob.d b/gcc/d/dmd/ob.d index 5acc69f..39cb74c 100644 --- a/gcc/d/dmd/ob.d +++ b/gcc/d/dmd/ob.d @@ -1723,6 +1723,8 @@ void genKill(ref ObState obstate, ObNode* ob) override void visit(NewExp e) { + if (e.placement) + e.placement.accept(this); if (e.arguments) { foreach (ex; *e.arguments) @@ -2464,6 +2466,9 @@ void checkObErrors(ref ObState obstate) override void visit(NewExp e) { + if (e.placement) + e.placement.accept(this); + if (e.arguments) { foreach (ex; *e.arguments) diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index b66ddcb..3510d3a 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -751,6 +751,7 @@ Expression optimize(Expression e, int result, bool keepLvalue = false) void visitNew(NewExp e) { + expOptimize(e.placement, WANTvalue); expOptimize(e.thisexp, WANTvalue); // Optimize parameters if (e.arguments) diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index 33e0e5a..2a92704 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -327,7 +327,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer pAttrs.comment = token.blockComment.ptr; } AST.Visibility.Kind prot; - StorageClass stc; + STC stc; AST.Condition condition; linkage = linksave; @@ -536,7 +536,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } // Workaround 14894. Add an empty unittest declaration to keep // the number of symbols in this scope independent of -unittest. - s = new AST.UnitTestDeclaration(loc, token.loc, STC.undefined_, null); + s = new AST.UnitTestDeclaration(loc, token.loc, STC.none, null); } break; @@ -744,7 +744,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer a = parseBlock(pLastDecl, pAttrs); auto stc2 = getStorageClass!AST(pAttrs); - if (stc2 != STC.undefined_) + if (stc2 != STC.none) { s = new AST.StorageClassDeclaration(scdLoc, stc2, a); } @@ -1101,7 +1101,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer * Starts with token on the first ident. * Ends with scanner past closing ';' */ - private AST.Dsymbols* parseAutoDeclarations(StorageClass storageClass, const(char)* comment) + private AST.Dsymbols* parseAutoDeclarations(STC storageClass, const(char)* comment) { //printf("parseAutoDeclarations\n"); auto a = new AST.Dsymbols(); @@ -1216,9 +1216,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer * Returns: * The combination of both storage classes (`orig | added`). */ - private StorageClass appendStorageClass(StorageClass orig, StorageClass added) + private STC appendStorageClass(STC orig, STC added) { - void checkConflictSTCGroup(bool at = false)(StorageClass group) + void checkConflictSTCGroup(bool at = false)(STC group) { if (added & group && orig & group & ((orig & group) - 1)) error( @@ -1308,13 +1308,13 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer * If the attribute is builtin, the return value will be non-zero. * Otherwise, 0 is returned, and `pudas` will be appended to. */ - private StorageClass parseAttribute(ref AST.Expressions* udas) + private STC parseAttribute(ref AST.Expressions* udas) { nextToken(); if (token.value == TOK.identifier) { // If we find a builtin attribute, we're done, return immediately. - if (StorageClass stc = isBuiltinAtAttribute(token.ident)) + if (STC stc = isBuiltinAtAttribute(token.ident)) return stc; // Allow identifier, template instantiation, or function call @@ -1332,7 +1332,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (udas is null) udas = new AST.Expressions(); udas.push(exp); - return 0; + return STC.none; } AST.Expression templateArgToExp(RootObject o, Loc loc) @@ -1359,7 +1359,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer auto args = parseTemplateArgumentList(); foreach (arg; *args) udas.push(templateArgToExp(arg, token.loc)); - return 0; + return STC.none; } if (auto o = parseTemplateSingleArgument()) @@ -1367,7 +1367,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (udas is null) udas = new AST.Expressions(); udas.push(templateArgToExp(o, token.loc)); - return 0; + return STC.none; } if (token.isKeyword()) @@ -1375,17 +1375,17 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer else error("`@identifier` or `@(ArgumentList)` expected, not `@%s`", token.toChars()); - return 0; + return STC.none; } /*********************************************** * Parse const/immutable/shared/inout/nothrow/pure postfix */ - private StorageClass parsePostfix(StorageClass storageClass, AST.Expressions** pudas) + private STC parsePostfix(STC storageClass, AST.Expressions** pudas) { while (1) { - StorageClass stc; + STC stc; switch (token.value) { case TOK.const_: @@ -1422,6 +1422,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer stc = STC.scope_; break; + case TOK.rvalue: + stc = STC.rvalue; + break; + case TOK.at: { AST.Expressions* udas = null; @@ -1458,16 +1462,16 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } } - private StorageClass parseTypeCtor() + private STC parseTypeCtor() { - StorageClass storageClass = STC.undefined_; + STC storageClass = STC.none; while (1) { if (peekNext() == TOK.leftParenthesis) return storageClass; - StorageClass stc; + STC stc; switch (token.value) { case TOK.const_: @@ -2411,7 +2415,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { AST.Expressions* udas = null; const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); nextToken(); if (token.value == TOK.leftParenthesis && peekNext() == TOK.this_ && peekNext2() == TOK.rightParenthesis) @@ -2462,7 +2466,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (stc & STC.static_) error(loc, "constructor cannot be static"); } - else if (StorageClass ss = stc & (STC.shared_ | STC.static_)) // this() + else if (STC ss = stc & (STC.shared_ | STC.static_)) // this() { if (ss == STC.static_) error(loc, "use `static this()` to declare a static constructor"); @@ -2504,7 +2508,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { AST.Expressions* udas = null; const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); nextToken(); check(TOK.this_); @@ -2512,7 +2516,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer check(TOK.rightParenthesis); stc = parsePostfix(stc, &udas); - if (StorageClass ss = stc & (STC.shared_ | STC.static_)) + if (STC ss = stc & (STC.shared_ | STC.static_)) { if (ss == STC.static_) error(loc, "use `static ~this()` to declare a static destructor"); @@ -2540,7 +2544,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { //Expressions *udas = NULL; const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); nextToken(); nextToken(); @@ -2552,7 +2556,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer error(loc, "use `shared static this()` to declare a shared static constructor"); else if (stc & STC.static_) appendStorageClass(stc, STC.static_); // complaint for the redundancy - else if (StorageClass modStc = stc & STC.TYPECTOR) + else if (STC modStc = stc & STC.TYPECTOR) { OutBuffer buf; AST.stcToBuffer(buf, modStc); @@ -2574,7 +2578,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { AST.Expressions* udas = null; const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); nextToken(); nextToken(); @@ -2587,7 +2591,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer error(loc, "use `shared static ~this()` to declare a shared static destructor"); else if (stc & STC.static_) appendStorageClass(stc, STC.static_); // complaint for the redundancy - else if (StorageClass modStc = stc & STC.TYPECTOR) + else if (STC modStc = stc & STC.TYPECTOR) { OutBuffer buf; AST.stcToBuffer(buf, modStc); @@ -2615,7 +2619,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { //Expressions *udas = NULL; const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); nextToken(); nextToken(); @@ -2624,9 +2628,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer check(TOK.rightParenthesis); stc = parsePostfix(stc & ~STC.TYPECTOR, null) | stc; - if (StorageClass ss = stc & (STC.shared_ | STC.static_)) + if (STC ss = stc & (STC.shared_ | STC.static_)) appendStorageClass(stc, ss); // complaint for the redundancy - else if (StorageClass modStc = stc & STC.TYPECTOR) + else if (STC modStc = stc & STC.TYPECTOR) { OutBuffer buf; AST.stcToBuffer(buf, modStc); @@ -2648,7 +2652,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { AST.Expressions* udas = null; const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); nextToken(); nextToken(); @@ -2658,9 +2662,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer check(TOK.rightParenthesis); stc = parsePostfix(stc & ~STC.TYPECTOR, &udas) | stc; - if (StorageClass ss = stc & (STC.shared_ | STC.static_)) + if (STC ss = stc & (STC.shared_ | STC.static_)) appendStorageClass(stc, ss); // complaint for the redundancy - else if (StorageClass modStc = stc & STC.TYPECTOR) + else if (STC modStc = stc & STC.TYPECTOR) { OutBuffer buf; AST.stcToBuffer(buf, modStc); @@ -2689,7 +2693,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Dsymbol parseInvariant(PrefixAttributes!AST* pAttrs) { const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); nextToken(); if (token.value == TOK.leftParenthesis) // optional () or invariant (expression); @@ -2731,7 +2735,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Dsymbol parseUnitTest(PrefixAttributes!AST* pAttrs) { const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); nextToken(); @@ -2773,7 +2777,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer private AST.Dsymbol parseNewDeclaration(PrefixAttributes!AST* pAttrs) { const loc = token.loc; - StorageClass stc = getStorageClass!AST(pAttrs); + STC stc = getStorageClass!AST(pAttrs); if (!(stc & STC.disable)) { error("`new` allocator must be annotated with `@disabled`"); @@ -2792,7 +2796,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { auto parameters = new AST.Parameters(); VarArg varargs = VarArg.none; - StorageClass varargsStc; + STC varargsStc; // Attributes allowed for ... enum VarArgsStc = STC.const_ | STC.immutable_ | STC.shared_ | STC.scope_ | STC.return_ | STC.returnScope; @@ -2802,8 +2806,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { Identifier ai = null; AST.Type at; - StorageClass storageClass = 0; - StorageClass stc; + STC storageClass = STC.none; + STC stc; AST.Expression ae; AST.Expressions* udas = null; for (; 1; nextToken()) @@ -2855,7 +2859,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.at: { AST.Expressions* exps = null; - StorageClass stc2 = parseAttribute(exps); + STC stc2 = parseAttribute(exps); if (stc2 & atAttrGroup) { error("`@%s` attribute for function parameter is not supported", token.toChars()); @@ -2961,7 +2965,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (token.value == TOK.at) { AST.Expressions* exps = null; - StorageClass stc2 = parseAttribute(exps); + STC stc2 = parseAttribute(exps); if (stc2 & atAttrGroup) { error("`@%s` attribute for function parameter is not supported", token.toChars()); @@ -3059,7 +3063,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer Identifier ident = null; AST.Expressions* udas; - StorageClass stc; + STC stc; AST.Expression deprecationMessage; enum attributeErrorMessage = "`%s` is not a valid attribute for enum members"; Lattrs: @@ -3068,7 +3072,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer switch (token.value) { case TOK.at: - if (StorageClass _stc = parseAttribute(udas)) + if (STC _stc = parseAttribute(udas)) { if (_stc == STC.disable) stc |= _stc; @@ -3499,7 +3503,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer * shared inout type * shared inout const type */ - StorageClass stc = 0; + STC stc = STC.none; while (1) { switch (token.value) @@ -3983,7 +3987,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer auto parameterList = parseParameterList(null); - StorageClass stc = parsePostfix(STC.undefined_, null); + STC stc = parsePostfix(STC.none, null); auto tf = new AST.TypeFunction(parameterList, t, linkage, stc); if (stc & (STC.const_ | STC.immutable_ | STC.shared_ | STC.wild | STC.return_)) { @@ -4019,7 +4023,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer * Reference: https://dlang.org/spec/declaration.html#Declarator */ private AST.Type parseDeclarator(AST.Type t, ref int palt, Identifier* pident, - AST.TemplateParameters** tpl = null, StorageClass storageClass = 0, + AST.TemplateParameters** tpl = null, STC storageClass = STC.none, bool* pdisable = null, AST.Expressions** pudas = null) { //printf("parseDeclarator(tpl = %p)\n", tpl); @@ -4160,7 +4164,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer /* Parse const/immutable/shared/inout/nothrow/pure/return postfix */ // merge prefix storage classes - StorageClass stc = parsePostfix(storageClass, pudas); + STC stc = parsePostfix(storageClass, pudas); AST.Type tf = new AST.TypeFunction(parameterList, t, linkage, stc); tf = tf.addSTC(stc); @@ -4187,11 +4191,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer return ts; } - private void parseStorageClasses(ref StorageClass storage_class, ref LINK link, + private void parseStorageClasses(ref STC storage_class, ref LINK link, ref bool setAlignment, ref AST.Expression ealign, ref AST.Expressions* udas, out Loc linkloc) { - StorageClass stc; + STC stc; bool sawLinkage = false; // seen a linkage declaration linkloc = Loc.initial; @@ -4369,7 +4373,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer */ private AST.Dsymbols* parseDeclarations(bool autodecl, PrefixAttributes!AST* pAttrs, const(char)* comment) { - StorageClass storage_class = STC.undefined_; + STC storage_class = STC.none; LINK link = linkage; Loc linkloc = this.linkLoc; bool setAlignment = false; @@ -4500,7 +4504,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (pAttrs) { storage_class |= pAttrs.storageClass; - //pAttrs.storageClass = STC.undefined_; + //pAttrs.storageClass = STC.none; } AST.Type tfirst = null; @@ -4606,9 +4610,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer AST.Expression constraint = null; //printf("%s funcdecl t = %s, storage_class = x%lx\n", loc.toChars(), t.toChars(), storage_class); - auto f = new AST.FuncDeclaration(loc, Loc.initial, ident, storage_class | (disable ? STC.disable : 0), t); + auto f = new AST.FuncDeclaration(loc, Loc.initial, ident, storage_class | (disable ? STC.disable : STC.none), t); if (pAttrs) - pAttrs.storageClass = STC.undefined_; + pAttrs.storageClass = STC.none; if (tpl) constraint = parseConstraint(); AST.Dsymbol s = parseContracts(f, !!tpl); @@ -4644,7 +4648,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer auto tempdecl = new AST.TemplateDeclaration(loc, tplIdent, tpl, constraint, decldefs); s = tempdecl; - StorageClass stc2 = STC.undefined_; + STC stc2 = STC.none; if (storage_class & STC.static_) { assert(f.storage_class & STC.static_); @@ -4657,7 +4661,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer f.storage_class &= ~STC.deprecated_; stc2 |= STC.deprecated_; } - if (stc2 != STC.undefined_) + if (stc2 != STC.none) { auto ax = new AST.Dsymbols(); ax.push(s); @@ -4697,7 +4701,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer auto v = new AST.VarDeclaration(loc, t, ident, _init); v.storage_class = storage_class; if (pAttrs) - pAttrs.storageClass = STC.undefined_; + pAttrs.storageClass = STC.none; s = v; } @@ -4812,7 +4816,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer Loc linkloc = this.linkLoc; AST.Expressions* udas; LINK link = linkage; - StorageClass storage_class = STC.undefined_; + STC storage_class = STC.none; AST.Expression ealign; bool setAlignment = false; @@ -4870,7 +4874,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer return; hasParsedAttributes = true; udas = null; - storage_class = STC.undefined_; + storage_class = STC.none; link = linkage; linkloc = this.linkLoc; setAlignment = false; @@ -4885,7 +4889,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer AST.Dsymbol s; bool attributesAppended; - const StorageClass funcStc = parseTypeCtor(); + const STC funcStc = parseTypeCtor(); Token* tk; // function literal? if (token.value == TOK.function_ || @@ -5058,7 +5062,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer AST.TemplateParameters* tpl = null; AST.ParameterList parameterList; AST.Type tret = null; - StorageClass stc = 0; + STC stc = STC.none; TOK save = TOK.reserved; switch (token.value) @@ -5137,7 +5141,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer // (parameters) { statements... } parameterList = parseParameterList(&tpl); stc = parsePostfix(stc, null); - if (StorageClass modStc = stc & STC.TYPECTOR) + if (STC modStc = stc & STC.TYPECTOR) { if (save == TOK.function_) { @@ -5485,8 +5489,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer AST.Type at; Loc aloc; - StorageClass storageClass = 0; - StorageClass stc = 0; + STC storageClass = STC.none; + STC stc = STC.none; Lagain: if (stc) { @@ -5663,8 +5667,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer AST.Parameter parseAssignCondition() { AST.Parameter param = null; - StorageClass storageClass = 0; - StorageClass stc = 0; + STC storageClass = STC.none; + STC stc = STC.none; Lwhile: while (1) { @@ -7005,7 +7009,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer Loc labelloc; nextToken(); - StorageClass stc = parsePostfix(STC.undefined_, null); // optional FunctionAttributes + STC stc = parsePostfix(STC.none, null); // optional FunctionAttributes if (stc & (STC.const_ | STC.immutable_ | STC.shared_ | STC.wild)) error("`const`/`immutable`/`shared`/`inout` attributes are not allowed on `asm` blocks"); @@ -8773,7 +8777,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.const_: case TOK.immutable_: // immutable(type)(arguments) / immutable(type).init { - StorageClass stc = parseTypeCtor(); + STC stc = parseTypeCtor(); AST.Type t = parseBasicType(); t = t.addSTC(stc); @@ -9502,7 +9506,17 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { const loc = token.loc; - nextToken(); + nextToken(); // skip past `new` + + // parse PlacementExpression if any + AST.Expression placement; + if (token.value == TOK.leftParenthesis) + { + nextToken(); + placement = parseAssignExp(); + check(TOK.rightParenthesis); + } + AST.Expressions* arguments = null; AST.Identifiers* names = null; @@ -9538,7 +9552,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } auto cd = new AST.ClassDeclaration(loc, id, baseclasses, members, false); - auto e = new AST.NewAnonClassExp(loc, thisexp, cd, arguments); + auto e = new AST.NewAnonClassExp(loc, placement, thisexp, cd, arguments); return e; } @@ -9562,7 +9576,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer parseNamedArguments(arguments, names); } - auto e = new AST.NewExp(loc, thisexp, t, arguments, names); + auto e = new AST.NewExp(loc, placement, thisexp, t, arguments, names); return e; } @@ -9590,7 +9604,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer * Returns: * storage class for attribute, 0 if not */ - static StorageClass isBuiltinAtAttribute(Identifier ident) + static STC isBuiltinAtAttribute(Identifier ident) { return (ident == Id.property) ? STC.property : (ident == Id.nogc) ? STC.nogc : @@ -9600,10 +9614,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer (ident == Id.live) ? STC.live : (ident == Id.future) ? STC.future : (ident == Id.disable) ? STC.disable : - 0; + STC.none; } - enum StorageClass atAttrGroup = + enum STC atAttrGroup = STC.property | STC.nogc | STC.safe | @@ -9800,7 +9814,7 @@ enum ParseStatementFlags : int struct PrefixAttributes(AST) { - StorageClass storageClass; + STC storageClass; AST.Expression depmsg; LINK link; AST.Visibility visibility; @@ -9852,13 +9866,13 @@ private enum CARRAYDECL = 1; /***************************** * Destructively extract storage class from pAttrs. */ -private StorageClass getStorageClass(AST)(PrefixAttributes!(AST)* pAttrs) +private STC getStorageClass(AST)(PrefixAttributes!(AST)* pAttrs) { - StorageClass stc = STC.undefined_; + STC stc = STC.none; if (pAttrs) { stc = pAttrs.storageClass; - pAttrs.storageClass = STC.undefined_; + pAttrs.storageClass = STC.none; } return stc; } diff --git a/gcc/d/dmd/pragmasem.d b/gcc/d/dmd/pragmasem.d index c5d18ef..a7299a0 100644 --- a/gcc/d/dmd/pragmasem.d +++ b/gcc/d/dmd/pragmasem.d @@ -567,7 +567,7 @@ private bool pragmaMsgSemantic(Loc loc, Scope* sc, Expressions* args) return false; buf.writestring("\n"); - fprintf(stderr, buf.extractChars); + fprintf(stderr, "%s", buf.extractChars); return true; } diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index f7a7ce1..b9ac0c6 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -478,7 +478,7 @@ private extern(C++) final class Semantic3Visitor : Visitor foreach (i, fparam; f.parameterList) { Identifier id = fparam.ident; - StorageClass stc = 0; + STC stc = STC.none; if (!id) { /* Generate identifier for un-named parameter, @@ -1349,7 +1349,7 @@ private extern(C++) final class Semantic3Visitor : Visitor sc = sc.push(); if (funcdecl.isCtorDeclaration()) // https://issues.dlang.org/show_bug.cgi?id=#15665 f.isCtor = true; - sc.stc = 0; + sc.stc = STC.none; sc.linkage = funcdecl._linkage; // https://issues.dlang.org/show_bug.cgi?id=8496 funcdecl.type = f.typeSemantic(funcdecl.loc, sc); sc = sc.pop(); @@ -1489,9 +1489,9 @@ private extern(C++) final class Semantic3Visitor : Visitor // storage_class is apparently not set for dtor & ctor OutBuffer ob; stcToBuffer(ob, - (ngErr ? STC.nogc : 0) | - (puErr ? STC.pure_ : 0) | - (saErr ? STC.system : 0) + (ngErr ? STC.nogc : STC.none) | + (puErr ? STC.pure_ : STC.none) | + (saErr ? STC.system : STC.none) ); ctor.loc.error("`%s` has stricter attributes than its destructor (`%s`)", ctor.toPrettyChars(), ob.peekChars()); ctor.loc.errorSupplemental("The destructor will be called if an exception is thrown"); diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d index 659b0f4..c8c0c78 100644 --- a/gcc/d/dmd/sideeffect.d +++ b/gcc/d/dmd/sideeffect.d @@ -374,7 +374,7 @@ bool discardValue(Expression e) * Returns: * Newly created temporary variable. */ -VarDeclaration copyToTemp(StorageClass stc, const char[] name, Expression e) +VarDeclaration copyToTemp(STC stc, const char[] name, Expression e) { assert(name[0] == '_' && name[1] == '_'); auto vd = new VarDeclaration(e.loc, e.type, @@ -413,7 +413,7 @@ Expression extractSideEffect(Scope* sc, const char[] name, (sc.ctfe ? !hasSideEffect(e) : isTrivialExp(e))) return e; - auto vd = copyToTemp(0, name, e); + auto vd = copyToTemp(STC.none, name, e); vd.storage_class |= e.isLvalue() ? STC.ref_ : STC.rvalue; e0 = Expression.combine(e0, new DeclarationExp(vd.loc, vd) diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d index 3b5f5f8..1d63946 100644 --- a/gcc/d/dmd/statement.d +++ b/gcc/d/dmd/statement.d @@ -1715,7 +1715,7 @@ extern (C++) final class LabelDsymbol : Dsymbol extern (D) this(Identifier ident, Loc loc = Loc.initial) @safe { - super(loc, ident); + super(DSYM.labelDsymbol, loc, ident); } static LabelDsymbol create(Identifier ident) @safe @@ -1799,7 +1799,7 @@ extern (C++) final class InlineAsmStatement : AsmStatement */ extern (C++) final class GccAsmStatement : AsmStatement { - StorageClass stc; // attributes of the asm {} block + STC stc; // attributes of the asm {} block Expression insn; // string expression that is the template for assembler code Expressions* args; // input and output operands of the statement uint outputargs; // of the operands in 'args', the number of output operands @@ -1830,9 +1830,9 @@ extern (C++) final class GccAsmStatement : AsmStatement */ extern (C++) final class CompoundAsmStatement : CompoundStatement { - StorageClass stc; // postfix attributes like nothrow/pure/@trusted + STC stc; // postfix attributes like nothrow/pure/@trusted - extern (D) this(Loc loc, Statements* statements, StorageClass stc) @safe + extern (D) this(Loc loc, Statements* statements, STC stc) @safe { super(loc, statements, STMT.CompoundAsm); this.stc = stc; diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index 4029fda..d19052b 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -135,7 +135,16 @@ private Expression checkAssignmentAsCondition(Expression e, Scope* sc) return e; } -// Performs semantic analysis in Statement AST nodes +/** + * Performs semantic analysis in Statement AST nodes + * + * Params: + * s = statement to perform semantic analysis on + * sc = scope in which statement resides + * + * Returns: statement `s` after semantic analysis. + * Can be `null`, for example with `pragma(msg, "")` + */ Statement statementSemantic(Statement s, Scope* sc) { import dmd.compiler; @@ -1291,7 +1300,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) } else { - r = copyToTemp(0, "__r", fs.aggr); + r = copyToTemp(STC.none, "__r", fs.aggr); r.dsymbolSemantic(sc); _init = new ExpStatement(loc, r); if (vinit) @@ -3074,14 +3083,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc) * _d_monitorenter(tmp); * try { body } finally { _d_monitorexit(tmp); } */ - auto tmp = copyToTemp(0, "__sync", ss.exp); + auto tmp = copyToTemp(STC.none, "__sync", ss.exp); tmp.dsymbolSemantic(sc); auto cs = new Statements(); cs.push(new ExpStatement(ss.loc, tmp)); auto args = new Parameters(); - args.push(new Parameter(Loc.initial, 0, ClassDeclaration.object.type, null, null, null)); + args.push(new Parameter(Loc.initial, STC.none, ClassDeclaration.object.type, null, null, null)); FuncDeclaration fdenter = FuncDeclaration.genCfunc(args, Type.tvoid, Id.monitorenter); Expression e = new CallExp(ss.loc, fdenter, new VarExp(ss.loc, tmp)); @@ -3123,7 +3132,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) cs.push(new ExpStatement(ss.loc, v)); auto enterArgs = new Parameters(); - enterArgs.push(new Parameter(Loc.initial, 0, t.pointerTo(), null, null, null)); + enterArgs.push(new Parameter(Loc.initial, STC.none, t.pointerTo(), null, null, null)); FuncDeclaration fdenter = FuncDeclaration.genCfunc(enterArgs, Type.tvoid, Id.criticalenter, STC.nothrow_); Expression e = new AddrExp(ss.loc, tmpExp); @@ -3133,7 +3142,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) cs.push(new ExpStatement(ss.loc, e)); auto exitArgs = new Parameters(); - exitArgs.push(new Parameter(Loc.initial, 0, t, null, null, null)); + exitArgs.push(new Parameter(Loc.initial, STC.none, t, null, null, null)); FuncDeclaration fdexit = FuncDeclaration.genCfunc(exitArgs, Type.tvoid, Id.criticalexit, STC.nothrow_); e = new CallExp(ss.loc, fdexit, tmpExp); @@ -3220,7 +3229,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) * } * } */ - auto tmp = copyToTemp(0, "__withtmp", ws.exp); + auto tmp = copyToTemp(STC.none, "__withtmp", ws.exp); tmp.dsymbolSemantic(sc); auto es = new ExpStatement(ws.loc, tmp); ws.exp = new VarExp(ws.loc, tmp); @@ -3488,6 +3497,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) sc = sc.push(); sc.debug_ = true; ds.statement = ds.statement.statementSemantic(sc); + debugThrowWalker(ds.statement); sc.pop(); } result = ds.statement; @@ -3847,11 +3857,11 @@ private extern(D) Expression applyArray(ForeachStatement fs, Expression flde, auto params = new Parameters(); params.push(new Parameter(Loc.initial, STC.in_, tn.arrayOf(), null, null, null)); auto dgparams = new Parameters(); - dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null)); + dgparams.push(new Parameter(Loc.initial, STC.none, Type.tvoidptr, null, null, null)); if (dim == 2) - dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null)); + dgparams.push(new Parameter(Loc.initial, STC.none, Type.tvoidptr, null, null, null)); dgty = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d)); - params.push(new Parameter(Loc.initial, 0, dgty, null, null, null)); + params.push(new Parameter(Loc.initial, STC.none, dgty, null, null, null)); fdapply = FuncDeclaration.genCfunc(params, Type.tint32, fdname.ptr); if (tab.isTypeSArray()) @@ -3912,14 +3922,14 @@ private extern(D) Expression applyAssocArray(ForeachStatement fs, Expression fld if (!fdapply[i]) { auto params = new Parameters(); - params.push(new Parameter(Loc.initial, 0, Type.tvoid.pointerTo(), null, null, null)); + params.push(new Parameter(Loc.initial, STC.none, Type.tvoid.pointerTo(), null, null, null)); params.push(new Parameter(Loc.initial, STC.const_, Type.tsize_t, null, null, null)); auto dgparams = new Parameters(); - dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null)); + dgparams.push(new Parameter(Loc.initial, STC.none, Type.tvoidptr, null, null, null)); if (dim == 2) - dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null)); + dgparams.push(new Parameter(Loc.initial, STC.none, Type.tvoidptr, null, null, null)); fldeTy[i] = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d)); - params.push(new Parameter(Loc.initial, 0, fldeTy[i], null, null, null)); + params.push(new Parameter(Loc.initial, STC.none, fldeTy[i], null, null, null)); fdapply[i] = FuncDeclaration.genCfunc(params, Type.tint32, i ? Id._aaApply2 : Id._aaApply); } @@ -3990,7 +4000,7 @@ private FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFuncti auto params = new Parameters(); foreach (i, p; *fs.parameters) { - StorageClass stc = STC.ref_ | (p.storageClass & STC.scope_); + STC stc = STC.ref_ | (p.storageClass & STC.scope_); Identifier id; p.type = p.type.typeSemantic(fs.loc, sc); @@ -4034,7 +4044,7 @@ private FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFuncti } // https://issues.dlang.org/show_bug.cgi?id=13840 // Throwable nested function inside nothrow function is acceptable. - StorageClass stc = mergeFuncAttrs(STC.safe | STC.pure_ | STC.nogc, fs.func); + STC stc = mergeFuncAttrs(STC.safe | STC.pure_ | STC.nogc, fs.func); auto tf = new TypeFunction(ParameterList(params), Type.tint32, LINK.d, stc); fs.cases = new Statements(); fs.gotos = new ScopeStatements(); @@ -4099,7 +4109,7 @@ void catchSemantic(Catch c, Scope* sc) return; } - StorageClass stc; + STC stc; auto cd = c.type.toBasetype().isClassHandle(); if (!cd) { @@ -4256,7 +4266,7 @@ Statement scopeCode(Statement statement, Scope* sc, out Statement sentry, out St * sexception: x = true; * sfinally: if (!x) statement; */ - auto v = copyToTemp(0, "__os", IntegerExp.createBool(false)); + auto v = copyToTemp(STC.none, "__os", IntegerExp.createBool(false)); v.dsymbolSemantic(sc); sentry = new ExpStatement(statement.loc, v); @@ -4449,7 +4459,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState * Returns: * `true` iff the declaration was successful. */ - bool declareVariable(StorageClass storageClass, Type type, Identifier ident, Expression e, Type t) + bool declareVariable(STC storageClass, Type type, Identifier ident, Expression e, Type t) { if (storageClass & (STC.out_ | STC.lazy_) || storageClass & STC.ref_ && !te) @@ -4590,7 +4600,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState { // expand tuples into multiple `static foreach` variables. assert(e && !t); auto ident = Identifier.generateId("__value"); - declareVariable(0, e.type, ident, e, null); + declareVariable(STC.none, e.type, ident, e, null); import dmd.cond: StaticForeach; auto field = Identifier.idPool(StaticForeach.tupleFieldName.ptr,StaticForeach.tupleFieldName.length); Expression access = new DotIdExp(loc, e, field); @@ -4760,7 +4770,6 @@ private Statements* flatten(Statement statement, Scope* sc) if (dc) { s = new DebugStatement(cs.loc, cs.ifbody); - debugThrowWalker(cs.ifbody); } else s = cs.ifbody; @@ -4932,7 +4941,8 @@ Params: */ private void debugThrowWalker(Statement s) { - + if (!s) + return; extern(C++) final class DebugWalker : SemanticTimeTransitiveVisitor { alias visit = SemanticTimeTransitiveVisitor.visit; diff --git a/gcc/d/dmd/staticassert.d b/gcc/d/dmd/staticassert.d index 3d73ae8..0e959bc 100644 --- a/gcc/d/dmd/staticassert.d +++ b/gcc/d/dmd/staticassert.d @@ -30,7 +30,7 @@ extern (C++) final class StaticAssert : Dsymbol extern (D) this(Loc loc, Expression exp, Expression msg) { - super(loc, Id.empty); + super(DSYM.staticAssert, loc, Id.empty); this.exp = exp; this.msgs = new Expressions(1); (*this.msgs)[0] = msg; @@ -38,7 +38,7 @@ extern (C++) final class StaticAssert : Dsymbol extern (D) this(Loc loc, Expression exp, Expressions* msgs) { - super(loc, Id.empty); + super(DSYM.staticAssert, loc, Id.empty); this.exp = exp; this.msgs = msgs; } @@ -49,23 +49,11 @@ extern (C++) final class StaticAssert : Dsymbol return new StaticAssert(loc, exp.syntaxCopy(), msgs ? Expression.arraySyntaxCopy(msgs) : null); } - override bool oneMember(out Dsymbol ps, Identifier ident) - { - //printf("StaticAssert::oneMember())\n"); - ps = null; - return true; - } - override const(char)* kind() const { return "static assert"; } - override inout(StaticAssert) isStaticAssert() inout - { - return this; - } - override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/staticassert.h b/gcc/d/dmd/staticassert.h index ed76de0..9a10dee 100644 --- a/gcc/d/dmd/staticassert.h +++ b/gcc/d/dmd/staticassert.h @@ -21,8 +21,6 @@ public: Expressions *msg; StaticAssert *syntaxCopy(Dsymbol *s) override; - bool oneMember(Dsymbol *&ps, Identifier *ident) override; const char *kind() const override; - StaticAssert *isStaticAssert() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h index 5bb0de5..e98a1d6 100644 --- a/gcc/d/dmd/template.h +++ b/gcc/d/dmd/template.h @@ -77,12 +77,10 @@ public: TemplateDeclaration *syntaxCopy(Dsymbol *) override; bool overloadInsert(Dsymbol *s) override; - bool hasStaticCtorOrDtor() override; const char *kind() const override; Visibility visible() override; - TemplateDeclaration *isTemplateDeclaration() override { return this; } bool isDeprecated() const override; bool isOverloadable() const override; @@ -270,14 +268,12 @@ public: TemplateInstance *syntaxCopy(Dsymbol *) override; Dsymbol *toAlias() override final; // resolve real symbol const char *kind() const override; - bool oneMember(Dsymbol *&ps, Identifier *ident) override; const char* toPrettyCharsHelper() override final; Identifier *getIdent() override final; bool isDiscardable(); bool needsCodegen(); - TemplateInstance *isTemplateInstance() override final { return this; } void accept(Visitor *v) override { v->visit(this); } }; @@ -288,10 +284,8 @@ public: TemplateMixin *syntaxCopy(Dsymbol *s) override; const char *kind() const override; - bool oneMember(Dsymbol *&ps, Identifier *ident) override; bool hasPointers() override; - TemplateMixin *isTemplateMixin() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/templatesem.d b/gcc/d/dmd/templatesem.d index 48c4297..e514456 100644 --- a/gcc/d/dmd/templatesem.d +++ b/gcc/d/dmd/templatesem.d @@ -120,7 +120,7 @@ void templateDeclarationSemantic(Scope* sc, TemplateDeclaration tempdecl) auto paramsym = new ScopeDsymbol(); paramsym.parent = tempdecl.parent; Scope* paramscope = sc.push(paramsym); - paramscope.stc = 0; + paramscope.stc = STC.none; if (global.params.ddoc.doOutput) { @@ -603,7 +603,7 @@ Scope* createScopeForTemplateParameters(TemplateDeclaration td, TemplateInstance paramscope.tinst = ti; paramscope.minst = sc.minst; paramscope.callsc = sc; - paramscope.stc = 0; + paramscope.stc = STC.none; return paramscope; } @@ -905,7 +905,7 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat // Match attributes of tthis against attributes of fd if (fd.type && !fd.isCtorDeclaration() && !(td._scope.stc & STC.static_)) { - StorageClass stc = td._scope.stc | fd.storage_class2; + STC stc = td._scope.stc | fd.storage_class2; // Propagate parent storage class, https://issues.dlang.org/show_bug.cgi?id=5504 Dsymbol p = td.parent; while (p.isTemplateDeclaration() || p.isTemplateInstance()) @@ -2491,7 +2491,7 @@ private extern(C++) class DummyArgVisitor : Visitor return; } if (!tap.sdummy) - tap.sdummy = new Dsymbol(); + tap.sdummy = new Dsymbol(DSYM.dsymbol); result = tap.sdummy; } diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index 42344c6..dedfeb7 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -1523,7 +1523,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) if (!fparams.parameters) return ErrorExp.get(); - StorageClass stc; + STC stc; // Set stc to storage class of the ith parameter auto ex = isExpression((*e.args)[1]); diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index 7f87ac4..d382101 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -2348,7 +2348,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc) /* Create a scope for evaluating the default arguments for the parameters */ Scope* argsc = sc.push(); - argsc.stc = 0; // don't inherit storage class + argsc.stc = STC.none; // don't inherit storage class argsc.visibility = Visibility(Visibility.Kind.public_); argsc.func = null; @@ -2404,12 +2404,12 @@ Type typeSemantic(Type type, Loc loc, Scope* sc) // https://issues.dlang.org/show_bug.cgi?id=12744 // If the storage classes of narg // conflict with the ones in fparam, it's ignored. - StorageClass stc = fparam.storageClass | narg.storageClass; - StorageClass stc1 = fparam.storageClass & (STC.ref_ | STC.out_ | STC.lazy_); - StorageClass stc2 = narg.storageClass & (STC.ref_ | STC.out_ | STC.lazy_); + STC stc = fparam.storageClass | narg.storageClass; + STC stc1 = fparam.storageClass & (STC.ref_ | STC.out_ | STC.lazy_); + STC stc2 = narg.storageClass & (STC.ref_ | STC.out_ | STC.lazy_); if (stc1 && stc2 && stc1 != stc2) { - OutBuffer buf1; stcToBuffer(buf1, stc1 | ((stc1 & STC.ref_) ? (fparam.storageClass & STC.auto_) : 0)); + OutBuffer buf1; stcToBuffer(buf1, stc1 | ((stc1 & STC.ref_) ? (fparam.storageClass & STC.auto_) : STC.none)); OutBuffer buf2; stcToBuffer(buf2, stc2); .error(loc, "incompatible parameter storage classes `%s` and `%s`", @@ -2985,8 +2985,14 @@ Type typeSemantic(Type type, Loc loc, Scope* sc) Type visitTag(TypeTag mtype) { //printf("TypeTag.semantic() %s\n", mtype.toChars()); - Type returnType(Type t) - { + Type returnType(TypeTag tt) + { + Type t = tt.resolved; + // To make const checking work, the const STC needs to be added: + // t = t.resolved.addSTC(mtype.mod.ModToStc); + // However, this currently fails compilable/test22875.i + // Apparently there's some aliasing going on, where mutable + // versions of the type also get const applied to them. return t.deco ? t : t.merge(); } @@ -2994,7 +3000,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc) { /* struct S s, *p; */ - return returnType(mtype.resolved.addSTC(mtype.mod)); + return returnType(mtype); } /* Find the current scope by skipping tag scopes. @@ -3067,7 +3073,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc) { mtype.id = Identifier.generateId("__tag"[]); declareTag(); - return returnType(mtype.resolved.addSTC(mtype.mod)); + return returnType(mtype); } /* look for pre-existing declaration @@ -3080,7 +3086,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc) if (mtype.tok == TOK.enum_ && !mtype.members) .error(mtype.loc, "`enum %s` is incomplete without members", mtype.id.toChars()); // C11 6.7.2.3-3 declareTag(); - return returnType(mtype.resolved.addSTC(mtype.mod)); + return returnType(mtype); } /* A redeclaration only happens if both declarations are in @@ -3180,7 +3186,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc) declareTag(); } } - return returnType(mtype.resolved.addSTC(mtype.mod)); + return returnType(mtype); } switch (type.ty) @@ -6182,7 +6188,7 @@ Dsymbol toDsymbol(Type type, Scope* sc) /************************************ * Add storage class modifiers to type. */ -Type addStorageClass(Type type, StorageClass stc) +Type addStorageClass(Type type, STC stc) { Type visitType(Type t) { @@ -6214,7 +6220,7 @@ Type addStorageClass(Type type, StorageClass stc) (stc & STC.safe && t.trust < TRUST.trusted)) { // Klunky to change these - auto tf = new TypeFunction(t.parameterList, t.next, t.linkage, 0); + auto tf = new TypeFunction(t.parameterList, t.next, t.linkage, STC.none); tf.mod = t.mod; tf.inferenceArguments = tf_src.inferenceArguments; tf.purity = t.purity; @@ -6345,7 +6351,7 @@ Type getComplexLibraryType(Loc loc, Scope* sc, TY ty) * Returns: * An enum value of either `Covariant.yes` or a reason it's not covariant. */ -Covariant covariant(Type src, Type t, StorageClass* pstc = null, bool cppCovariant = false) +Covariant covariant(Type src, Type t, STC* pstc = null, bool cppCovariant = false) { version (none) { @@ -6355,8 +6361,8 @@ Covariant covariant(Type src, Type t, StorageClass* pstc = null, bool cppCovaria printf("mod = %x, %x\n", src.mod, t.mod); } if (pstc) - *pstc = 0; - StorageClass stc = 0; + *pstc = STC.none; + STC stc = STC.none; bool notcovariant = false; @@ -6506,8 +6512,8 @@ Lcovariant: if (!t1.isRef && (t1.isScopeQual || t2.isScopeQual)) { - StorageClass stc1 = t1.isScopeQual ? STC.scope_ : 0; - StorageClass stc2 = t2.isScopeQual ? STC.scope_ : 0; + STC stc1 = t1.isScopeQual ? STC.scope_ : STC.none; + STC stc2 = t2.isScopeQual ? STC.scope_ : STC.none; if (t1.isReturn) { stc1 |= STC.return_; @@ -6605,7 +6611,7 @@ Lnotcovariant: * Returns: * storage class with STC.scope_ or STC.return_ OR'd in */ -StorageClass parameterStorageClass(TypeFunction tf, Type tthis, Parameter p, VarDeclarations* outerVars = null, +STC parameterStorageClass(TypeFunction tf, Type tthis, Parameter p, VarDeclarations* outerVars = null, bool indirect = false) { //printf("parameterStorageClass(p: %s)\n", p.toChars()); diff --git a/gcc/d/dmd/version.h b/gcc/d/dmd/version.h index 7913c96..8840b59 100644 --- a/gcc/d/dmd/version.h +++ b/gcc/d/dmd/version.h @@ -18,7 +18,6 @@ public: DebugSymbol *syntaxCopy(Dsymbol *) override; const char *kind() const override; - DebugSymbol *isDebugSymbol() override; void accept(Visitor *v) override { v->visit(this); } }; @@ -28,6 +27,5 @@ public: VersionSymbol *syntaxCopy(Dsymbol *) override; const char *kind() const override; - VersionSymbol *isVersionSymbol() override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/visitor/postorder.d b/gcc/d/dmd/visitor/postorder.d index af12f1e..39c38a2 100644 --- a/gcc/d/dmd/visitor/postorder.d +++ b/gcc/d/dmd/visitor/postorder.d @@ -82,13 +82,13 @@ public: override void visit(NewExp e) { //printf("NewExp::apply(): %s\n", toChars()); - doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e); + doCond(e.placement) || doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e); } override void visit(NewAnonClassExp e) { //printf("NewAnonClassExp::apply(): %s\n", toChars()); - doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e); + doCond(e.placement) || doCond(e.thisexp) || doCond(e.arguments.peekSlice()) || applyTo(e); } override void visit(TypeidExp e) diff --git a/gcc/d/dmd/visitor/transitive.d b/gcc/d/dmd/visitor/transitive.d index c3ce13e..89c2332 100644 --- a/gcc/d/dmd/visitor/transitive.d +++ b/gcc/d/dmd/visitor/transitive.d @@ -994,6 +994,8 @@ package(dmd.visitor) mixin template ParseVisitMethods(AST) override void visit(AST.NewExp e) { //printf("Visiting NewExp\n"); + if (e.placement) + e.placement.accept(this); if (e.thisexp) e.thisexp.accept(this); visitType(e.newtype); @@ -1003,6 +1005,8 @@ package(dmd.visitor) mixin template ParseVisitMethods(AST) override void visit(AST.NewAnonClassExp e) { //printf("Visiting NewAnonClassExp\n"); + if (e.placement) + e.placement.accept(this); if (e.thisexp) e.thisexp.accept(this); visitArgs(e.arguments.peekSlice()); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index da794ea..0415763 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -1783,7 +1783,7 @@ public: void visit (DelegateExp *e) final override { - if (e->func->semanticRun == PASS::semantic3done) + if (e->func->semanticRun () == PASS::semantic3done) { /* Add the function as nested function if it belongs to this module. ie: it is a member of this module, or it is a template instance. */ @@ -2246,6 +2246,15 @@ public: new_call = build_nop (type, build_address (var)); setup_exp = modify_expr (var, aggregate_initializer_decl (cd)); } + else if (e->placement != NULL) + { + /* Generate: placement_expr = typeid(class).init */ + tree placement_expr = build_expr (e->placement); + new_call = build_nop (type, build_address (placement_expr)); + tree class_init = build_vconvert (TREE_TYPE (placement_expr), + aggregate_initializer_decl (cd)); + setup_exp = modify_expr (placement_expr, class_init); + } else { /* Generate: _d_newclass() @@ -2318,12 +2327,22 @@ public: return; } - /* This case should have been rewritten to `_d_newitemT' during the - semantic phase. */ - gcc_assert (e->lowering); + if (e->placement != NULL) + { + /* Generate: &placement_expr */ + tree placement_expr = build_expr (e->placement); + new_call = build_nop (build_ctype (tb), + build_address (placement_expr)); + } + else + { + /* This case should have been rewritten to `_d_newitemT' during the + semantic phase. */ + gcc_assert (e->lowering); - /* Generate: _d_newitemT() */ - new_call = build_expr (e->lowering); + /* Generate: _d_newitemT() */ + new_call = build_expr (e->lowering); + } if (e->member || !e->arguments) { @@ -2396,12 +2415,22 @@ public: return; } - /* This case should have been rewritten to `_d_newitemT' during the - semantic phase. */ - gcc_assert (e->lowering); + if (e->placement != NULL) + { + /* Generate: &placement_expr */ + tree placement_expr = build_expr (e->placement); + result = build_nop (build_ctype (tb), + build_address (placement_expr)); + } + else + { + /* This case should have been rewritten to `_d_newitemT' during the + semantic phase. */ + gcc_assert (e->lowering); - /* Generate: _d_newitemT() */ - result = build_expr (e->lowering); + /* Generate: _d_newitemT() */ + result = build_expr (e->lowering); + } if (e->arguments && e->arguments->length == 1) { diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc index 85b6e42..471ac43 100644 --- a/gcc/d/modules.cc +++ b/gcc/d/modules.cc @@ -143,13 +143,13 @@ get_internal_fn (tree ident, const Visibility &visibility) name = IDENTIFIER_POINTER (s); } - FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid, - Identifier::idPool (name)); + FuncDeclaration *fd = dmd::genCfunc (NULL, Type::tvoid, + Identifier::idPool (name)); fd->isGenerated (true); fd->loc = Loc::singleFilename (mod->srcfile.toChars ()); fd->parent = mod; fd->visibility = visibility; - fd->semanticRun = PASS::semantic3done; + fd->semanticRun (PASS::semantic3done); return fd; } |