From patchwork Sun Oct 29 15:47:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 159376 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:d641:0:b0:403:3b70:6f57 with SMTP id cy1csp1746526vqb; Sun, 29 Oct 2023 08:48:23 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFHLCmSfRObYQjmTM4fEnbXNdJVBhoRB7lEA8AnBu82u/b4dr9l0fjK7UyvekJn7AmMZ+cE X-Received: by 2002:a05:6808:1385:b0:3b2:f54b:8b3a with SMTP id c5-20020a056808138500b003b2f54b8b3amr10564923oiw.27.1698594503370; Sun, 29 Oct 2023 08:48:23 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1698594503; cv=pass; d=google.com; s=arc-20160816; b=ml3DUsjK6Tbxj7DIpIpMkYFIrn07VVjTUW3qiNBb79C01eS620Z20kRiCswFxxzyqv 1ByA0TJyIMzAtlijYZkEPKVZbNv4sVbuZ+tviOixlkn+yI4Grtpg4VmSVV0gSowcxU5J 3wEtSh6AIbbKJpYdNzaMovH4MwYbFC4B0/v4uHrnkZE4RwY4MXnBSKSMm6RYu12MBuS1 eKf+rKa+A97ZXVf67waA5R9RODEP/0RSVRACifk036hyvu6sjrOA9x8w4eGDxt+5uKcs pkr7ymjtwN87GdmU2b2i06xE7kjHpB9keQh6uqO/E9npIiknjFjBEtM04xvuruU22/D/ G8eg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature :arc-filter:dmarc-filter:delivered-to; bh=BGZYEe2Ez9mWFO8QZJJbjAK0UcZgtMj2oDdNK++mZtg=; fh=D2tRalIjW6KCgVuqwFHStdMb9uqe8HSQc2WEvRJ6uLE=; b=qdjOOlWZ+IVod7Oh8riG2W90+m8HQmToobIkColKZsEvbdtU5jMS2nWdMQA+GDvNm+ 5IVH02bnMbmIH5reR92JXvwJzFoM5g1eZF7X8S1FOU4GBWR00yKXfVOPhMQuyf4ksyQJ XuVtRaKapayCpdMVi1+fHQDxURjLGzxYWSyzDYULJ6EBS58rwlDscPFl5KHMcRJ2HJPv ujlwdUgYZGK1cN8H0iMbd/rpfpPFhmxIlCiHEQuPgMoRzmEJH7Vhe0d/CgLwzfm4nrZz NmkPuQHR1pvzXbiYYvYz+hW36k9NtYk3ScSKBjL68yGAbgF569hgIAmVmjgvcvhICTnz 80EA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@gdcproject.org header.s=MBO0001 header.b=cIJPq4qN; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=gdcproject.org Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id t1-20020a0cde01000000b0066d16ed048asi4217061qvk.29.2023.10.29.08.48.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Oct 2023 08:48:23 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gdcproject.org header.s=MBO0001 header.b=cIJPq4qN; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=gdcproject.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0B848386186E for ; Sun, 29 Oct 2023 15:48:23 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [80.241.56.151]) by sourceware.org (Postfix) with ESMTPS id 419833858C39 for ; Sun, 29 Oct 2023 15:47:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 419833858C39 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=gdcproject.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gdcproject.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 419833858C39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=80.241.56.151 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698594464; cv=none; b=aSgEnugMW6s1xCCNfVztwljJL9m2mLP9jYx1OQ3ioUV8WDWaAYQlEQEyT7QeNeFMD4ZvPP6PYfgKrjVrHgffHXZyaUgapVce3mXqJqGqsw19QxhlGc6V7HDMthzMNe4jjBXnn2qEO3nujbeLeTan6y2Rwdv5/pk9/aoo6Vi5zOs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698594464; c=relaxed/simple; bh=d3zscuzP1/NqYsxbEEQrSZClKIDggA83Ms9CLQaUGzs=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=n+U6cZ8fqaaQMRhBX5njyIH323mrPAkAdxLs4k7YMvxERm6SQ3NIPNN7A58QUF73z4wqmfFfpaclDn6eLyvf/9vrPkZYMHaXYuUvvstKCFOL8kiQTf6ZXlX2maHTUtEcUO18ruTbxBSZlNm7QG2c+uhPCm5CDiYNNiWMF9qtufs= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp2.mailbox.org (smtp2.mailbox.org [10.196.197.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4SJLPz49qxz9skk; Sun, 29 Oct 2023 16:47:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gdcproject.org; s=MBO0001; t=1698594455; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=BGZYEe2Ez9mWFO8QZJJbjAK0UcZgtMj2oDdNK++mZtg=; b=cIJPq4qND+4mt9gBQwDSHOGCaIfplFeppisDh7vy5iy8bnfwkvrWgZ3Ho0EzJHLGrnC7sS P5Dt5GqsuEF53fkAzzcjXwoUlmiA/kv/+T8fRwrrEDd3S1IRMISvasSoNMOr5l0sT5BhjV nTl/GEWk0ZsJOiU1n6kaZGVnsmFZS+dsqXcFo3gqdYcN8vHmjoqFsqb6C+RxCui/suPYqR jbofk5whwA3bTyYrKekIWfqKeT/suDU+wEj3EKUjKNG927heaZHjTaOeaCgWOzz3KlswGE p1ltAm3HrQjnBfAdeK0llBzYsl5kpkQ1jL+gXkm6sQF8J7gXvh2Z9k6ur/0AUg== From: Iain Buclaw To: gcc-patches@gcc.gnu.org Cc: Iain Buclaw Subject: [committed] d: Merge upstream dmd, druntime e48bc0987d, phobos 2458e8f82. Date: Sun, 29 Oct 2023 16:47:32 +0100 Message-Id: <20231029154732.191984-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781105429898336465 X-GMAIL-MSGID: 1781105429898336465 Hi, This patch merges the D front-end and runtime library with upstream dmd e48bc0987d, and standard library with phobos 2458e8f82. Synchronizing with the v2.106.0-beta.1 release. D front-end changes: - Import dmd v2.106.0-beta.1. D runtime changes: - Import druntime v2.106.0-beta.1. Phobos changes: - Import phobos v2.106.0-beta.1. Bootstrapped and regression tested on x86_64-linux-gnu/-m32, and committed to mainline. Regards, Iain. --- gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd e48bc0987d. * expr.cc (ExprVisitor::visit (NewExp *)): Update for new front-end interface. * runtime.def (NEWARRAYT): Remove. (NEWARRAYIT): Remove. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime e48bc0987d. * src/MERGE: Merge upstream phobos 2458e8f82. --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/aggregate.d | 8 +- gcc/d/dmd/aggregate.h | 8 - gcc/d/dmd/aliasthis.h | 2 +- gcc/d/dmd/attrib.h | 1 - gcc/d/dmd/canthrow.d | 2 +- gcc/d/dmd/cond.d | 2 +- gcc/d/dmd/cond.h | 2 - gcc/d/dmd/cparse.d | 17 +- gcc/d/dmd/dcast.d | 2 +- gcc/d/dmd/dclass.d | 8 +- gcc/d/dmd/declaration.d | 1 + gcc/d/dmd/declaration.h | 12 - gcc/d/dmd/denum.d | 2 +- gcc/d/dmd/dimport.d | 2 +- gcc/d/dmd/dinterpret.d | 3 + gcc/d/dmd/dmodule.d | 2 +- gcc/d/dmd/dscope.d | 2 +- gcc/d/dmd/dstruct.d | 2 +- gcc/d/dmd/dsymbol.d | 7 +- gcc/d/dmd/dsymbolsem.d | 15 +- gcc/d/dmd/dtemplate.d | 8 +- gcc/d/dmd/expression.d | 90 ++----- gcc/d/dmd/expression.h | 88 +------ gcc/d/dmd/expressionsem.d | 53 ++++ gcc/d/dmd/func.d | 20 +- gcc/d/dmd/globals.h | 6 +- gcc/d/dmd/hdrgen.d | 38 ++- gcc/d/dmd/id.d | 2 + gcc/d/dmd/import.h | 1 - gcc/d/dmd/init.h | 1 - gcc/d/dmd/location.d | 2 +- gcc/d/dmd/module.h | 1 - gcc/d/dmd/mtype.d | 16 +- gcc/d/dmd/mtype.h | 12 - gcc/d/dmd/objc.h | 2 - gcc/d/dmd/scope.h | 2 - gcc/d/dmd/sideeffect.d | 4 +- gcc/d/dmd/statement.d | 6 +- gcc/d/dmd/statement.h | 4 +- gcc/d/dmd/template.h | 5 - gcc/d/dmd/tokens.d | 2 +- gcc/d/dmd/tokens.h | 3 - gcc/d/expr.cc | 20 +- gcc/d/runtime.def | 9 +- .../gdc.test/fail_compilation/ice10727a.d | 2 + .../gdc.test/fail_compilation/ice10727b.d | 2 + libphobos/libdruntime/MERGE | 2 +- .../core/internal/array/construction.d | 167 +++++++++++++ .../libdruntime/core/internal/array/utils.d | 236 ++++++++++++++++++ libphobos/libdruntime/core/lifetime.d | 13 +- .../libdruntime/core/sys/freebsd/ifaddrs.d | 41 +++ .../libdruntime/core/sys/freebsd/net/if_dl.d | 42 ++++ .../libdruntime/core/sys/freebsd/sys/socket.d | 131 ++++++++++ .../libdruntime/core/sys/freebsd/sys/types.d | 58 +++++ .../libdruntime/core/sys/posix/sys/types.d | 4 +- libphobos/libdruntime/object.d | 2 + libphobos/libdruntime/rt/lifetime.d | 26 +- libphobos/src/MERGE | 2 +- libphobos/src/std/parallelism.d | 2 +- libphobos/src/std/range/primitives.d | 10 +- libphobos/src/std/traits.d | 57 +++++ 63 files changed, 962 insertions(+), 334 deletions(-) create mode 100644 libphobos/libdruntime/core/sys/freebsd/ifaddrs.d create mode 100644 libphobos/libdruntime/core/sys/freebsd/net/if_dl.d create mode 100644 libphobos/libdruntime/core/sys/freebsd/sys/socket.d create mode 100644 libphobos/libdruntime/core/sys/freebsd/sys/types.d diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index bfadeaa0c68..2a0baf09a4b 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -f4be7f6f7bae75f1613b862940cdd533b5ae99b2 +e48bc0987dfec35bc76a3015ee3e85906ce86dfd 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 fd05dcf2136..b272d4bbe5c 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.105.2 +v2.106.0-beta.1 diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d index 68b5f1b48f1..d9b48b531d7 100644 --- a/gcc/d/dmd/aggregate.d +++ b/gcc/d/dmd/aggregate.d @@ -192,7 +192,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol * Returns: * The total number of fields minus the number of hidden fields. */ - final size_t nonHiddenFields() + extern (D) final size_t nonHiddenFields() { return fields.length - isNested() - (vthis2 !is null); } @@ -202,7 +202,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol * Returns: * false if failed to determine the size. */ - final bool determineSize(const ref Loc loc) + extern (D) final bool determineSize(const ref Loc loc) { //printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok); @@ -609,7 +609,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol } /// Flag this aggregate as deprecated - final void setDeprecated() + extern (D) final void setDeprecated() { this.storage_class |= STC.deprecated_; } @@ -745,7 +745,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol /******************************************* * Look for constructor declaration. */ - final Dsymbol searchCtor() + extern (D) final Dsymbol searchCtor() { auto s = search(Loc.initial, Id.ctor); if (s) diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h index 4b107e0f2a9..58a0126de1a 100644 --- a/gcc/d/dmd/aggregate.h +++ b/gcc/d/dmd/aggregate.h @@ -114,17 +114,13 @@ public: virtual Scope *newScope(Scope *sc); void setScope(Scope *sc) override final; - size_t nonHiddenFields(); - bool determineSize(const Loc &loc); virtual void finalizeSize() = 0; uinteger_t size(const Loc &loc) override final; bool fill(const Loc &loc, Expressions &elements, bool ctorinit); Type *getType() override final; bool isDeprecated() const override final; // is aggregate deprecated? - void setDeprecated(); bool isNested() const; bool isExport() const override final; - Dsymbol *searchCtor(); Visibility visible() override final; @@ -279,12 +275,10 @@ public: ObjcClassDeclaration objc; // Data for a class declaration that is needed for the Objective-C integration Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr - void classError(const char* fmt, const char* arg); static ClassDeclaration *create(const Loc &loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject); const char *toPrettyChars(bool QualifyTypes = false) override; ClassDeclaration *syntaxCopy(Dsymbol *s) override; Scope *newScope(Scope *sc) override; - bool isBaseOf2(ClassDeclaration *cd); #define OFFSET_RUNTIME 0x76543210 #define OFFSET_FWDREF 0x76543211 @@ -292,11 +286,9 @@ public: bool isBaseInfoComplete(); Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final; - ClassDeclaration *searchBase(Identifier *ident); void finalizeSize() override; bool hasMonitor(); bool isFuncHidden(FuncDeclaration *fd); - FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); bool isCOMclass() const; virtual bool isCOMinterface() const; bool isCPPclass() const; diff --git a/gcc/d/dmd/aliasthis.h b/gcc/d/dmd/aliasthis.h index 389cff40054..092490fd5de 100644 --- a/gcc/d/dmd/aliasthis.h +++ b/gcc/d/dmd/aliasthis.h @@ -21,7 +21,7 @@ public: // alias Identifier this; Identifier *ident; Dsymbol *sym; - bool isDeprecated_; + d_bool isDeprecated_; AliasThis *syntaxCopy(Dsymbol *) override; const char *kind() const override; diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h index 1e75598c72a..f47a1f6f836 100644 --- a/gcc/d/dmd/attrib.h +++ b/gcc/d/dmd/attrib.h @@ -123,7 +123,6 @@ public: Expressions *alignExps; structalign_t salign; - AlignDeclaration(const Loc &loc, Expression *ealign, Dsymbols *decl); AlignDeclaration *syntaxCopy(Dsymbol *s) override; Scope *newScope(Scope *sc) override; void accept(Visitor *v) override { v->visit(this); } diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d index bb1fd6fc974..8aece3bdd71 100644 --- a/gcc/d/dmd/canthrow.d +++ b/gcc/d/dmd/canthrow.d @@ -55,7 +55,7 @@ enum CT : BE * eSink = if !null, then send error messages to eSink * Returns: `CT.exception` or `CT.error` if the expression may throw exceptions. */ -extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, ErrorSink eSink) +CT canThrow(Expression e, FuncDeclaration func, ErrorSink eSink) { //printf("Expression::canThrow(%d) %s\n", mustNotThrow, e.toChars()); // stop walking if we determine this expression can throw diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d index e4d1096db48..9fa8a25462f 100644 --- a/gcc/d/dmd/cond.d +++ b/gcc/d/dmd/cond.d @@ -133,7 +133,7 @@ extern (C++) final class StaticForeach : RootObject this.rangefe = rangefe; } - StaticForeach syntaxCopy() + extern (D) StaticForeach syntaxCopy() { return new StaticForeach( loc, diff --git a/gcc/d/dmd/cond.h b/gcc/d/dmd/cond.h index 45094d14991..d02ae1321c5 100644 --- a/gcc/d/dmd/cond.h +++ b/gcc/d/dmd/cond.h @@ -53,8 +53,6 @@ public: ForeachRangeStatement *rangefe; d_bool needExpansion; - - StaticForeach *syntaxCopy(); }; class DVCondition : public Condition diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index d183b8227c8..0b738cdc3d5 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -1923,7 +1923,12 @@ final class CParser(AST) : Parser!AST } } if (isalias) - s = new AST.AliasDeclaration(token.loc, id, dt); + { + auto ad = new AST.AliasDeclaration(token.loc, id, dt); + ad.adFlags |= ad.hidden; // do not print when generating .di files + s = ad; + } + insertTypedefToTypedefTab(id, dt); // remember typedefs } else if (id) @@ -1960,7 +1965,9 @@ 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 - auto fd = new AST.FuncDeclaration(token.loc, Loc.initial, id, specifiersToSTC(level, specifier), dt, specifier.noreturn); + StorageClass 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); s = fd; } @@ -2136,7 +2143,9 @@ 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 - auto fd = new AST.FuncDeclaration(locFunc, prevloc, id, specifiersToSTC(LVL.global, specifier), ft, specifier.noreturn); + StorageClass 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); if (addFuncName) @@ -5289,7 +5298,7 @@ final class CParser(AST) : Parser!AST (*decls)[0] = s; s = new AST.AlignDeclaration(s.loc, specifier.alignExps, decls); } - else if (!specifier.packalign.isDefault()) + else if (!specifier.packalign.isDefault() && !specifier.packalign.isUnknown()) { //printf(" applying packalign %d\n", cast(int)specifier.packalign); // Wrap #pragma pack in an AlignDeclaration diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 9f661ea410b..e4d580513fe 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -3684,7 +3684,7 @@ void fix16997(Scope* sc, UnaExp ue) * This is to enable comparing things like an immutable * array with a mutable one. */ -extern (C++) bool arrayTypeCompatibleWithoutCasting(Type t1, Type t2) +extern (D) bool arrayTypeCompatibleWithoutCasting(Type t1, Type t2) { t1 = t1.toBasetype(); t2 = t2.toBasetype(); diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d index 0fbbb1128e7..09a4f4ef3f2 100644 --- a/gcc/d/dmd/dclass.d +++ b/gcc/d/dmd/dclass.d @@ -367,7 +367,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration baseok = Baseok.none; } - final void classError(const(char)* fmt, const(char)* arg) + extern (D) private void classError(const(char)* fmt, const(char)* arg) { .error(loc, fmt, kind, toPrettyChars, arg); } @@ -423,7 +423,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration * Determine if 'this' is a base class of cd. * This is used to detect circular inheritance only. */ - final bool isBaseOf2(ClassDeclaration cd) pure nothrow @nogc + extern (D) final bool isBaseOf2(ClassDeclaration cd) pure nothrow @nogc { if (!cd) return false; @@ -538,7 +538,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration * Returns: * ClassDeclaration if found, null if not */ - final ClassDeclaration searchBase(Identifier ident) + extern (D) final ClassDeclaration searchBase(Identifier ident) { foreach (b; *baseclasses) { @@ -716,7 +716,7 @@ extern (C++) class ClassDeclaration : AggregateDeclaration * Errors: * prints error message if more than one match */ - final FuncDeclaration findFunc(Identifier ident, TypeFunction tf) + extern (D) final FuncDeclaration findFunc(Identifier ident, TypeFunction tf) { //printf("ClassDeclaration.findFunc(%s, %s) %s\n", ident.toChars(), tf.toChars(), toChars()); FuncDeclaration fdmatch = null; diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index 40463b4d970..d634e7fe545 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -244,6 +244,7 @@ extern (C++) abstract class Declaration : Dsymbol enum wasRead = 1; // set if AliasDeclaration was read enum ignoreRead = 2; // ignore any reads of AliasDeclaration enum nounderscore = 4; // don't prepend _ to mangled name + enum hidden = 8; // don't print this in .di files Symbol* isym; // import version of csym diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 71f2baa525f..8cd295f1e06 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -705,15 +705,11 @@ public: bool functionSemantic3(); bool equals(const RootObject * const o) const override final; - int overrides(FuncDeclaration *fd); int findVtblIndex(Dsymbols *vtbl, int dim); - BaseClass *overrideInterface(); bool overloadInsert(Dsymbol *s) override; bool inUnittest(); MATCH leastAsSpecialized(FuncDeclaration *g, Identifiers *names); LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc); - int getLevel(FuncDeclaration *fd, int intypeof); // lexical nesting level difference - int getLevelAndCheck(const Loc &loc, Scope *sc, FuncDeclaration *fd); const char *toPrettyChars(bool QualifyTypes = false) override; const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure' bool isMain() const; @@ -726,13 +722,9 @@ public: bool isOverloadable() const override final; bool isAbstract() override final; PURE isPure(); - PURE isPureBypassingInference(); bool isSafe(); - bool isSafeBypassingInference(); bool isTrusted(); - bool isNogc(); - bool isNogcBypassingInference(); virtual bool isNested() const; AggregateDeclaration *isThis() override; @@ -752,8 +744,6 @@ public: 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); - bool checkNRVO(); - FuncDeclaration *isFuncDeclaration() override final { return this; } virtual FuncDeclaration *toAliasFunc() { return this; } @@ -789,8 +779,6 @@ public: bool addPreInvariant() override; bool addPostInvariant() override; - void modifyReturns(Scope *sc, Type *tret); - FuncLiteralDeclaration *isFuncLiteralDeclaration() override { return this; } const char *kind() const override; const char *toPrettyChars(bool QualifyTypes = false) override; diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d index 98bf4dd2aad..f33b5fd543e 100644 --- a/gcc/d/dmd/denum.d +++ b/gcc/d/dmd/denum.d @@ -99,7 +99,7 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol ScopeDsymbol.addMember(sc, sds); } - addEnumMembers(this, sc, sds); + addEnumMembersToSymtab(this, sc, sds); } override void setScope(Scope* sc) diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d index 3b8d9f6722d..d74c8603420 100644 --- a/gcc/d/dmd/dimport.d +++ b/gcc/d/dmd/dimport.d @@ -128,7 +128,7 @@ extern (C++) final class Import : Dsymbol * Returns: * true for errors, false for success */ - bool load(Scope* sc) + extern (D) bool load(Scope* sc) { //printf("Import::load('%s') %p\n", toPrettyChars(), this); // See if existing module diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index fc5a3aaf62c..cbd9740e089 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -2975,6 +2975,9 @@ public: } } + private alias fp_t = extern (D) UnionExp function(const ref Loc loc, Type, Expression, Expression); + private alias fp2_t = extern (D) bool function(const ref Loc loc, EXP, Expression, Expression); + extern (D) private void interpretCommon(BinExp e, fp_t fp) { debug (LOG) diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 9031b157000..548928a0124 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -1095,7 +1095,7 @@ extern (C++) final class Module : Package return Package.symtabInsert(s); } - void deleteObjFile() + extern (D) void deleteObjFile() { if (global.params.obj) File.remove(objfile.toChars()); diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d index 14dbe9c6149..3853512005c 100644 --- a/gcc/d/dmd/dscope.d +++ b/gcc/d/dmd/dscope.d @@ -344,7 +344,7 @@ extern (C++) struct Scope * Returns: * symbol if found, null if not */ - extern (C++) Dsymbol search(const ref Loc loc, Identifier ident, Dsymbol* pscopesym, int flags = IgnoreNone) + extern (D) Dsymbol search(const ref Loc loc, Identifier ident, Dsymbol* pscopesym, int flags = IgnoreNone) { version (LOGSEARCH) { diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index 56aad3eece3..5171e1f3106 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -71,7 +71,7 @@ extern (C++) FuncDeclaration search_toString(StructDeclaration sd) * sc = context * t = type that TypeInfo is being generated for */ -extern (C++) void semanticTypeInfo(Scope* sc, Type t) +extern (D) void semanticTypeInfo(Scope* sc, Type t) { if (sc) { diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index 6538664eace..579a542de3c 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -141,13 +141,14 @@ struct Visibility Kind kind; Package pkg; - extern (D): - - this(Visibility.Kind kind) pure nothrow @nogc @safe + extern(C++) this(Visibility.Kind kind, Package pkg = null) pure nothrow @nogc @safe { this.kind = kind; + this.pkg = pkg; } + extern (D): + /** * Checks if `this` is less or more visible than `other` * diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 4de037c8f68..8309e4a846b 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -2260,7 +2260,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor * so we have to do what addMember() does and install the enum members in the right symbol * table */ - addEnumMembers(ed, sc, sc.getScopesym()); + addEnumMembersToSymtab(ed, sc, sc.getScopesym()); if (sc.flags & SCOPE.Cfile) { @@ -5824,9 +5824,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor * sc = context of `ed` * sds = symbol table that `ed` resides in */ -void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds) +void addEnumMembersToSymtab(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds) { - //printf("addEnumMembers(ed: %p)\n", ed); + const bool isCEnum = (sc.flags & SCOPE.Cfile) != 0; // it's an ImportC enum + //printf("addEnumMembersToSymtab(ed: %s added: %d Cfile: %d)\n", ed.toChars(), ed.added, isCEnum); if (ed.added) return; ed.added = true; @@ -5834,7 +5835,6 @@ void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds) if (!ed.members) return; - const bool isCEnum = (sc.flags & SCOPE.Cfile) != 0; // it's an ImportC enum const bool isAnon = ed.isAnonymous(); if ((isCEnum || isAnon) && !sds.symtab) @@ -5847,10 +5847,15 @@ void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds) { if (EnumMember em = s.isEnumMember()) { + //printf("adding EnumMember %s to %s %d\n", em.toChars(), ed.toChars(), isCEnum); em.ed = ed; if (isCEnum) { - //printf("adding EnumMember %s to %p\n", em.toChars(), ed); + /* C doesn't add the enum member to the symbol table of the enum tag, it adds + * it to the symbol table that the tag is in. This is in contrast to D, where enum + * members become members of the enum tag. To accommodate this, we add + * the enum members to both symbol tables. + */ em.addMember(sc, ed); // add em to ed's symbol table em.addMember(sc, sds); // add em to symbol table that ed is in em.parent = ed; // restore it after previous addMember() changed it diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index ae49dda9315..5dca6dfec6e 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -1241,7 +1241,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol * match this is at least as specialized as td2 * 0 td2 is more specialized than this */ - MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration td2, ArgumentList argumentList) + extern (D) MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration td2, ArgumentList argumentList) { enum LOG_LEASTAS = 0; static if (LOG_LEASTAS) @@ -2258,7 +2258,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol /************************************************** * Declare template parameter tp with value o, and install it in the scope sc. */ - RootObject declareParameter(Scope* sc, TemplateParameter tp, RootObject o) + extern (D) RootObject declareParameter(Scope* sc, TemplateParameter tp, RootObject o) { //printf("TemplateDeclaration.declareParameter('%s', o = %p)\n", tp.ident.toChars(), o); Type ta = isType(o); @@ -2508,7 +2508,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol * Returns: * The last template parameter if it's a `TemplateTupleParameter` */ - TemplateTupleParameter isVariadic() + extern (D) TemplateTupleParameter isVariadic() { size_t dim = parameters.length; if (dim == 0) @@ -6203,7 +6203,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol return false; } - final size_t toHash() + extern (D) final size_t toHash() { if (!hash) { diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 2c55f0ebc94..32ded3bd5f6 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -331,7 +331,7 @@ TemplateDeclaration getFuncTemplateDecl(Dsymbol s) @safe * to serve essentially as a Variant that will sit on the stack * during CTFE to reduce memory consumption. */ -extern (C++) struct UnionExp +extern (D) struct UnionExp { // yes, default constructor does nothing extern (D) this(Expression e) @@ -341,14 +341,14 @@ extern (C++) struct UnionExp /* Extract pointer to Expression */ - extern (C++) Expression exp() return + extern (D) Expression exp() return { return cast(Expression)&u; } /* Convert to an allocated Expression */ - extern (C++) Expression copy() + extern (D) Expression copy() { Expression e = exp(); //if (e.size > sizeof(u)) printf("%s\n", EXPtoString(e.op).ptr); @@ -526,7 +526,7 @@ extern (C++) abstract class Expression : ASTNode /********************************* * Does *not* do a deep copy. */ - final Expression copy() + extern (D) final Expression copy() { Expression e; if (!size) @@ -745,7 +745,7 @@ extern (C++) abstract class Expression : ASTNode return toLvalue(sc, e); } - final Expression implicitCastTo(Scope* sc, Type t) + extern (D) final Expression implicitCastTo(Scope* sc, Type t) { return .implicitCastTo(this, sc, t); } @@ -755,7 +755,7 @@ extern (C++) abstract class Expression : ASTNode return .implicitConvTo(this, t); } - final Expression castTo(Scope* sc, Type t) + extern (D) final Expression castTo(Scope* sc, Type t) { return .castTo(this, sc, t); } @@ -861,7 +861,7 @@ extern (C++) abstract class Expression : ASTNode return checkValue(); } - final bool checkDeprecated(Scope* sc, Dsymbol s) + extern (D) final bool checkDeprecated(Scope* sc, Dsymbol s) { return s.checkDeprecated(loc, sc); } @@ -1205,10 +1205,11 @@ extern (C++) abstract class Expression : ASTNode return false; if (sc.flags & (SCOPE.ctfe | SCOPE.debug_)) return false; - /* The original expression (`new S(...)`) will be verified instead. This - * is to keep errors related to the original code and not the lowering. + /* The original expressions (`new S(...)` or `new S[...]``) will be + * verified instead. This is to keep errors related to the original code + * and not the lowering. */ - if (f.ident == Id._d_newitemT) + if (f.ident == Id._d_newitemT || f.ident == Id._d_newarrayT) return false; if (!f.isNogc()) @@ -1568,12 +1569,6 @@ extern (C++) final class IntegerExp : Expression return new IntegerExp(loc, value, type); } - // Same as create, but doesn't allocate memory. - static void emplace(UnionExp* pue, const ref Loc loc, dinteger_t value, Type type) - { - emplaceExp!(IntegerExp)(pue, loc, value, type); - } - override bool equals(const RootObject o) const { if (this == o) @@ -1641,7 +1636,7 @@ extern (C++) final class IntegerExp : Expression return value; } - void setInteger(dinteger_t value) + extern (D) void setInteger(dinteger_t value) { this.value = normalize(type.toBasetype().ty, value); } @@ -1838,12 +1833,6 @@ extern (C++) final class RealExp : Expression return new RealExp(loc, value, type); } - // Same as create, but doesn't allocate memory. - static void emplace(UnionExp* pue, const ref Loc loc, real_t value, Type type) - { - emplaceExp!(RealExp)(pue, loc, value, type); - } - /******************************** * Test to see if two reals are the same. * Regard NaN's as equivalent. @@ -1936,12 +1925,6 @@ extern (C++) final class ComplexExp : Expression return new ComplexExp(loc, value, type); } - // Same as create, but doesn't allocate memory. - static void emplace(UnionExp* pue, const ref Loc loc, complex_t value, Type type) - { - emplaceExp!(ComplexExp)(pue, loc, value, type); - } - override bool equals(const RootObject o) const { if (this == o) @@ -2277,22 +2260,6 @@ extern (C++) final class StringExp : Expression return new StringExp(loc, string[0 .. len]); } - // Same as create, but doesn't allocate memory. - static void emplace(UnionExp* pue, const ref Loc loc, const(char)* s) - { - emplaceExp!(StringExp)(pue, loc, s.toDString()); - } - - extern (D) static void emplace(UnionExp* pue, const ref Loc loc, const(void)[] string) - { - emplaceExp!(StringExp)(pue, loc, string); - } - - extern (D) static void emplace(UnionExp* pue, const ref Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix) - { - emplaceExp!(StringExp)(pue, loc, string, len, sz, postfix); - } - override bool equals(const RootObject o) const { //printf("StringExp::equals('%s') %s\n", o.toChars(), toChars()); @@ -2428,7 +2395,7 @@ extern (C++) final class StringExp : Expression * i = index * c = code unit to set it to */ - void setCodeUnit(size_t i, dchar c) + extern (D) void setCodeUnit(size_t i, dchar c) { assert(i < len); final switch (sz) @@ -2778,12 +2745,6 @@ extern (C++) final class ArrayLiteralExp : Expression return new ArrayLiteralExp(loc, null, elements); } - // Same as create, but doesn't allocate memory. - static void emplace(UnionExp* pue, const ref Loc loc, Expressions* elements) - { - emplaceExp!(ArrayLiteralExp)(pue, loc, null, elements); - } - override ArrayLiteralExp syntaxCopy() { return new ArrayLiteralExp(loc, @@ -2822,12 +2783,12 @@ extern (C++) final class ArrayLiteralExp : Expression return false; } - Expression getElement(size_t i) + Expression getElement(size_t i) // use opIndex instead { return this[i]; } - Expression opIndex(size_t i) + extern (D) Expression opIndex(size_t i) { auto el = (*elements)[i]; return el ? el : basis; @@ -3063,7 +3024,7 @@ extern (C++) final class StructLiteralExp : Expression * Gets expression at offset of type. * Returns NULL if not found. */ - Expression getField(Type type, uint offset) + extern (D) Expression getField(Type type, uint offset) { //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n", // /*toChars()*/"", type.toChars(), offset); @@ -3113,7 +3074,7 @@ extern (C++) final class StructLiteralExp : Expression * Get index of field. * Returns -1 if not found. */ - int getFieldIndex(Type type, uint offset) + extern (D) int getFieldIndex(Type type, uint offset) { /* Find which field offset is by looking at the field offsets */ @@ -4072,7 +4033,7 @@ extern (C++) abstract class UnaExp : Expression * Returns: * ErrorExp */ - final Expression incompatibleTypes() + extern (D) final Expression incompatibleTypes() { if (e1.type.toBasetype() == Type.terror) return e1; @@ -4112,9 +4073,6 @@ extern (C++) abstract class UnaExp : Expression } } -alias fp_t = UnionExp function(const ref Loc loc, Type, Expression, Expression); -alias fp2_t = bool function(const ref Loc loc, EXP, Expression, Expression); - /*********************************************************** * Base class for binary operators */ @@ -4147,7 +4105,7 @@ extern (C++) abstract class BinExp : Expression * Returns: * ErrorExp */ - final Expression incompatibleTypes() + extern (D) final Expression incompatibleTypes() { if (e1.type.toBasetype() == Type.terror) return e1; @@ -4357,7 +4315,7 @@ extern (C++) abstract class BinExp : Expression } - final Expression reorderSettingAAElem(Scope* sc) + extern (D) final Expression reorderSettingAAElem(Scope* sc) { BinExp be = this; @@ -4729,7 +4687,7 @@ extern (C++) final class DotTemplateInstanceExp : UnaExp return new DotTemplateInstanceExp(loc, e1.syntaxCopy(), ti.name, TemplateInstance.arraySyntaxCopy(ti.tiargs)); } - bool findTempDecl(Scope* sc) + extern (D) bool findTempDecl(Scope* sc) { static if (LOGSEMANTIC) { @@ -5323,12 +5281,6 @@ extern (C++) final class VectorExp : UnaExp return new VectorExp(loc, e, t); } - // Same as create, but doesn't allocate memory. - static void emplace(UnionExp* pue, const ref Loc loc, Expression e, Type type) - { - emplaceExp!(VectorExp)(pue, loc, e, type); - } - override VectorExp syntaxCopy() { return new VectorExp(loc, e1.syntaxCopy(), to.syntaxCopy()); diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index a92d9ada6f5..cfd5198ce79 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -39,7 +39,6 @@ class ClassDeclaration; class OverloadSet; class StringExp; class LoweredAssignExp; -struct UnionExp; #ifdef IN_GCC typedef union tree_node Symbol; #else @@ -47,11 +46,6 @@ struct Symbol; // back end symbol #endif void expandTuples(Expressions *exps, Identifiers *names = nullptr); -bool isTrivialExp(Expression *e); -bool hasSideEffect(Expression *e, bool assumeImpureCalls = false); - -enum BE : int32_t; -BE canThrow(Expression *e, FuncDeclaration *func, ErrorSink *eSink); typedef unsigned char OwnedBy; enum @@ -86,7 +80,6 @@ public: size_t size() const; static void _init(); - Expression *copy(); virtual Expression *syntaxCopy(); // kludge for template.isExpression() @@ -103,13 +96,10 @@ public: virtual bool isLvalue(); virtual Expression *toLvalue(Scope *sc, Expression *e); virtual Expression *modifiableLvalue(Scope *sc, Expression *e); - Expression *implicitCastTo(Scope *sc, Type *t); MATCH implicitConvTo(Type *t); - Expression *castTo(Scope *sc, Type *t); virtual Expression *resolveLoc(const Loc &loc, Scope *sc); virtual bool checkType(); virtual bool checkValue(); - bool checkDeprecated(Scope *sc, Dsymbol *s); virtual Expression *addDtorHook(Scope *sc); Expression *addressOf(); Expression *deref(); @@ -248,7 +238,6 @@ public: dinteger_t value; static IntegerExp *create(const Loc &loc, dinteger_t value, Type *type); - static void emplace(UnionExp *pue, const Loc &loc, dinteger_t value, Type *type); bool equals(const RootObject * const o) const override; dinteger_t toInteger() override; real_t toReal() override; @@ -258,7 +247,6 @@ public: Expression *toLvalue(Scope *sc, Expression *e) override; void accept(Visitor *v) override { v->visit(this); } dinteger_t getInteger() { return value; } - void setInteger(dinteger_t value); template static IntegerExp literal(); }; @@ -278,7 +266,6 @@ public: real_t value; static RealExp *create(const Loc &loc, real_t value, Type *type); - static void emplace(UnionExp *pue, const Loc &loc, real_t value, Type *type); bool equals(const RootObject * const o) const override; bool isIdentical(const Expression *e) const override; dinteger_t toInteger() override; @@ -296,7 +283,6 @@ public: complex_t value; static ComplexExp *create(const Loc &loc, complex_t value, Type *type); - static void emplace(UnionExp *pue, const Loc &loc, complex_t value, Type *type); bool equals(const RootObject * const o) const override; bool isIdentical(const Expression *e) const override; dinteger_t toInteger() override; @@ -376,15 +362,13 @@ public: void *string; // char, wchar, or dchar data size_t len; // number of chars, wchars, or dchars unsigned char sz; // 1: char, 2: wchar, 4: dchar - bool committed; // if type is committed - bool hexString; // if string is parsed from a hex string literal + d_bool committed; // if type is committed + d_bool hexString; // if string is parsed from a hex string literal static StringExp *create(const Loc &loc, const char *s); static StringExp *create(const Loc &loc, const void *s, d_size_t len); - static void emplace(UnionExp *pue, const Loc &loc, const char *s); bool equals(const RootObject * const o) const override; char32_t getCodeUnit(d_size_t i) const; - void setCodeUnit(d_size_t i, char32_t c); StringExp *toStringExp() override; StringExp *toUTF8(Scope *sc); Optional toBool() override; @@ -427,11 +411,9 @@ public: Expressions *elements; static ArrayLiteralExp *create(const Loc &loc, Expressions *elements); - static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements); ArrayLiteralExp *syntaxCopy() override; bool equals(const RootObject * const o) const override; - Expression *getElement(d_size_t i); // use opIndex instead - Expression *opIndex(d_size_t i); + Expression *getElement(d_size_t i); Optional toBool() override; StringExp *toStringExp() override; @@ -490,8 +472,6 @@ public: static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL); bool equals(const RootObject * const o) const override; StructLiteralExp *syntaxCopy() override; - Expression *getField(Type *type, unsigned offset); - int getFieldIndex(Type *type, unsigned offset); Expression *addDtorHook(Scope *sc) override; Expression *toLvalue(Scope *sc, Expression *e) override; @@ -702,7 +682,6 @@ public: Expression *e1; UnaExp *syntaxCopy() override; - Expression *incompatibleTypes(); Expression *resolveLoc(const Loc &loc, Scope *sc) override final; void accept(Visitor *v) override { v->visit(this); } @@ -718,9 +697,6 @@ public: Type *att2; // Save alias this type to detect recursion BinExp *syntaxCopy() override; - Expression *incompatibleTypes(); - - Expression *reorderSettingAAElem(Scope *sc); void accept(Visitor *v) override { v->visit(this); } }; @@ -806,7 +782,6 @@ public: TemplateInstance *ti; DotTemplateInstanceExp *syntaxCopy() override; - bool findTempDecl(Scope *sc); bool checkType() override; bool checkValue() override; void accept(Visitor *v) override { v->visit(this); } @@ -925,7 +900,6 @@ public: OwnedBy ownedByCtfe; static VectorExp *create(const Loc &loc, Expression *e, Type *t); - static void emplace(UnionExp *pue, const Loc &loc, Expression *e, Type *t); VectorExp *syntaxCopy() override; void accept(Visitor *v) override { v->visit(this); } }; @@ -1386,62 +1360,6 @@ public: /****************************************************************/ -/* A type meant as a union of all the Expression types, - * to serve essentially as a Variant that will sit on the stack - * during CTFE to reduce memory consumption. - */ -struct UnionExp -{ - UnionExp() { } // yes, default constructor does nothing - - UnionExp(Expression *e) - { - memcpy(this, (void *)e, e->size()); - } - - /* Extract pointer to Expression - */ - Expression *exp() { return (Expression *)&u; } - - /* Convert to an allocated Expression - */ - Expression *copy(); - -private: - // Ensure that the union is suitably aligned. -#if defined(__GNUC__) || defined(__clang__) - __attribute__((aligned(8))) -#elif defined(_MSC_VER) - __declspec(align(8)) -#elif defined(__DMC__) - #pragma pack(8) -#endif - union - { - char exp [sizeof(Expression)]; - char integerexp[sizeof(IntegerExp)]; - char errorexp [sizeof(ErrorExp)]; - char realexp [sizeof(RealExp)]; - char complexexp[sizeof(ComplexExp)]; - char symoffexp [sizeof(SymOffExp)]; - char stringexp [sizeof(StringExp)]; - char arrayliteralexp [sizeof(ArrayLiteralExp)]; - char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)]; - char structliteralexp [sizeof(StructLiteralExp)]; - char nullexp [sizeof(NullExp)]; - char dotvarexp [sizeof(DotVarExp)]; - char addrexp [sizeof(AddrExp)]; - char indexexp [sizeof(IndexExp)]; - char sliceexp [sizeof(SliceExp)]; - char vectorexp [sizeof(VectorExp)]; - } u; -#if defined(__DMC__) - #pragma pack() -#endif -}; - -/****************************************************************/ - class ObjcClassReferenceExp final : public Expression { public: diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 3472f9254cb..ac8e5715b28 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -4406,6 +4406,58 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor (*exp.arguments)[i] = arg; tb = tb.isTypeDArray().next.toBasetype(); } + + if (nargs == 1) + { + if (global.params.betterC || !sc.needsCodegen()) + goto LskipNewArrayLowering; + + /* Class types may inherit base classes that have errors. + * This may leak errors from the base class to the derived one + * and then to the hook. Semantic analysis is performed eagerly + * to a void this. + */ + if (auto tc = exp.type.nextOf.isTypeClass()) + { + tc.sym.dsymbolSemantic(sc); + if (tc.sym.errors) + goto LskipNewArrayLowering; + } + + auto hook = global.params.tracegc ? Id._d_newarrayTTrace : Id._d_newarrayT; + if (!verifyHookExist(exp.loc, *sc, hook, "new array")) + goto LskipNewArrayLowering; + + /* Lower the memory allocation and initialization of `new T[n]` + * to `_d_newarrayT!T(n)`. + */ + Expression lowering = new IdentifierExp(exp.loc, Id.empty); + lowering = new DotIdExp(exp.loc, lowering, Id.object); + auto tiargs = new Objects(); + /* Remove `inout`, `const`, `immutable` and `shared` to reduce + * the number of generated `_d_newarrayT` instances. + */ + const isShared = exp.type.nextOf.isShared(); + auto t = exp.type.nextOf.unqualify(MODFlags.wild | MODFlags.const_ | + MODFlags.immutable_ | MODFlags.shared_); + tiargs.push(t); + lowering = new DotTemplateInstanceExp(exp.loc, lowering, hook, tiargs); + + auto arguments = new Expressions(); + if (global.params.tracegc) + { + auto funcname = (sc.callsc && sc.callsc.func) ? + sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars(); + arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString())); + arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32)); + arguments.push(new StringExp(exp.loc, funcname.toDString())); + } + arguments.push((*exp.arguments)[0]); + arguments.push(new IntegerExp(exp.loc, isShared, Type.tbool)); + + lowering = new CallExp(exp.loc, lowering, arguments); + exp.lowering = lowering.expressionSemantic(sc); + } } else if (tb.isscalar()) { @@ -4447,6 +4499,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } + LskipNewArrayLowering: //printf("NewExp: '%s'\n", toChars()); //printf("NewExp:type '%s'\n", type.toChars()); semanticTypeInfo(sc, exp.type); diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index ac73e70db34..99848d80643 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -689,7 +689,7 @@ extern (C++) class FuncDeclaration : Declaration * Determine if 'this' overrides fd. * Return !=0 if it does. */ - final int overrides(FuncDeclaration fd) + extern (D) final int overrides(FuncDeclaration fd) { int result = 0; if (fd.ident == ident) @@ -838,7 +838,7 @@ extern (C++) class FuncDeclaration : Declaration * Returns: * base class if overriding, null if not */ - final BaseClass* overrideInterface() + extern (D) final BaseClass* overrideInterface() { for (ClassDeclaration cd = toParent2().isClassDeclaration(); cd; cd = cd.baseClass) { @@ -1215,7 +1215,7 @@ extern (C++) class FuncDeclaration : Declaration * -1 increase nesting by 1 (`fd` is nested within `this`) * LevelError error, `this` cannot call `fd` */ - final int getLevel(FuncDeclaration fd, int intypeof) + extern (D) final int getLevel(FuncDeclaration fd, int intypeof) { //printf("FuncDeclaration::getLevel(fd = '%s')\n", fd.toChars()); Dsymbol fdparent = fd.toParent2(); @@ -1276,8 +1276,8 @@ extern (C++) class FuncDeclaration : Declaration * -1 increase nesting by 1 (`fd` is nested within 'this') * LevelError error */ - final int getLevelAndCheck(const ref Loc loc, Scope* sc, FuncDeclaration fd, - Declaration decl) + extern (D) final int getLevelAndCheck(const ref Loc loc, Scope* sc, FuncDeclaration fd, + Declaration decl) { int level = getLevel(fd, sc.intypeof); if (level != LevelError) @@ -1490,7 +1490,7 @@ extern (C++) class FuncDeclaration : Declaration return purity; } - final PURE isPureBypassingInference() + extern (D) final PURE isPureBypassingInference() { if (purityInprocess) return PURE.fwdref; @@ -1544,7 +1544,7 @@ extern (C++) class FuncDeclaration : Declaration return type.toTypeFunction().trust == TRUST.safe; } - final bool isSafeBypassingInference() + extern (D) final bool isSafeBypassingInference() { return !(safetyInprocess) && isSafe(); } @@ -1612,7 +1612,7 @@ extern (C++) class FuncDeclaration : Declaration return type.toTypeFunction().isnogc; } - final bool isNogcBypassingInference() + extern (D) final bool isNogcBypassingInference() { return !nogcInprocess && isNogc(); } @@ -2935,7 +2935,7 @@ extern (C++) class FuncDeclaration : Declaration * Returns: * `false` if the result cannot be returned by hidden reference. */ - final bool checkNRVO() + extern (D) final bool checkNRVO() { if (!isNRVO() || returns is null) return false; @@ -3939,7 +3939,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration * If B to A conversion is convariant that requires offseet adjusting, * all return statements should be adjusted to return expressions typed A. */ - void modifyReturns(Scope* sc, Type tret) + extern (D) void modifyReturns(Scope* sc, Type tret) { import dmd.statement_rewrite_walker; diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 4048286ce71..5c21be186d8 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -272,9 +272,9 @@ struct CompileEnv DString time; DString vendor; DString timestamp; - bool previewIn; - bool ddocOutput; - bool shortenedMethods; + d_bool previewIn; + d_bool ddocOutput; + d_bool shortenedMethods; }; struct Global diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index 9d585cb898b..d935bd3480b 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -58,6 +58,7 @@ struct HdrGenState bool hdrgen; /// true if generating header file bool ddoc; /// true if generating Ddoc file bool fullDump; /// true if generating a full AST dump file + bool importcHdr; /// true if generating a .di file from an ImportC file bool fullQual; /// fully qualify types when printing int tpltMember; @@ -85,6 +86,7 @@ extern (C++) void genhdrfile(Module m, ref OutBuffer buf) buf.writenl(); HdrGenState hgs; hgs.hdrgen = true; + hgs.importcHdr = (m.filetype == FileType.c); toCBuffer(m, buf, hgs); } @@ -1521,6 +1523,28 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) buf.level--; buf.writeByte('}'); buf.writenl(); + + if (!hgs.importcHdr) + return; + + /* C enums get their members inserted into the symbol table of the enum declaration. + * This is accomplished in addEnumMembersToSymtab(). + * But when generating D code from ImportC code, D rulez are followed. + * Accomplish this by generating an alias declaration for each member + */ + foreach (em; *d.members) + { + if (!em) + continue; + buf.writestring("alias "); + buf.writestring(em.ident.toString); + buf.writestring(" = "); + buf.writestring(d.ident.toString); + buf.writeByte('.'); + buf.writestring(em.ident.toString); + buf.writeByte(';'); + buf.writenl(); + } } void visitNspace(Nspace d) @@ -1541,6 +1565,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) void visitStructDeclaration(StructDeclaration d) { + //printf("visitStructDeclaration() %s\n", d.ident.toChars()); buf.writestring(d.kind()); buf.writeByte(' '); if (!d.isAnonymous()) @@ -1595,6 +1620,8 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) { if (d.storage_class & STC.local) return; + if (d.adFlags & d.hidden) + return; buf.writestring("alias "); if (d.aliassym) { @@ -1663,7 +1690,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs) //printf("FuncDeclaration::toCBuffer() '%s'\n", f.toChars()); if (stcToBuffer(buf, f.storage_class)) buf.writeByte(' '); - auto tf = cast(TypeFunction)f.type; + auto tf = f.type.isTypeFunction(); typeToBuffer(tf, f.ident, buf, &hgs); if (hgs.hdrgen) @@ -4038,6 +4065,7 @@ private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs) void visitIdentifier(TypeIdentifier t) { + //printf("visitTypeIdentifier() %s\n", t.ident.toChars()); buf.writestring(t.ident.toString()); visitTypeQualifiedHelper(t); } @@ -4064,11 +4092,14 @@ private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs) void visitEnum(TypeEnum t) { + //printf("visitEnum: %s\n", t.sym.toChars()); buf.writestring(hgs.fullQual ? t.sym.toPrettyChars() : t.sym.toChars()); } void visitStruct(TypeStruct t) { + //printf("visitTypeStruct() %s\n", t.sym.toChars()); + // https://issues.dlang.org/show_bug.cgi?id=13776 // Don't use ti.toAlias() to avoid forward reference error // while printing messages. @@ -4095,6 +4126,11 @@ private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs) { if (t.mod & MODFlags.const_) buf.writestring("const "); + if (hgs.importcHdr && t.id) + { + buf.writestring(t.id.toChars()); + return; + } buf.writestring(Token.toChars(t.tok)); buf.writeByte(' '); if (t.id) diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d index b506e6feb66..5fcda91b435 100644 --- a/gcc/d/dmd/id.d +++ b/gcc/d/dmd/id.d @@ -321,6 +321,8 @@ immutable Msgtable[] msgtable = { "_d_newclassTTrace" }, { "_d_newitemT" }, { "_d_newitemTTrace" }, + { "_d_newarrayT" }, + { "_d_newarrayTTrace" }, { "_d_assert_fail" }, { "dup" }, { "_aaApply" }, diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h index ff25ba2045d..31ee61a65fb 100644 --- a/gcc/d/dmd/import.h +++ b/gcc/d/dmd/import.h @@ -41,7 +41,6 @@ public: const char *kind() const override; Visibility visible() override; Import *syntaxCopy(Dsymbol *s) override; // copy only syntax trees - void load(Scope *sc); void importAll(Scope *sc) override; Dsymbol *toAlias() override; void addMember(Scope *sc, ScopeDsymbol *sds) override; diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h index 4ab5848454e..67d0527a3b2 100644 --- a/gcc/d/dmd/init.h +++ b/gcc/d/dmd/init.h @@ -79,7 +79,6 @@ public: d_bool isCarray; // C array semantics bool isAssociativeArray() const; - Expression *toAssocArrayLiteral(); void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d index ef2bd0af779..9fe48b88844 100644 --- a/gcc/d/dmd/location.d +++ b/gcc/d/dmd/location.d @@ -64,7 +64,7 @@ nothrow: this.messageStyle = messageStyle; } - extern (D) this(const(char)* filename, uint linnum, uint charnum) @safe + extern (C++) this(const(char)* filename, uint linnum, uint charnum) @safe { this._linnum = linnum; this._charnum = charnum; diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h index ce512667694..6e8153d485a 100644 --- a/gcc/d/dmd/module.h +++ b/gcc/d/dmd/module.h @@ -127,7 +127,6 @@ public: Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override; bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0) override; Dsymbol *symtabInsert(Dsymbol *s) override; - void deleteObjFile(); static void runDeferredSemantic(); static void runDeferredSemantic2(); static void runDeferredSemantic3(); diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 70a0c032e65..6af140f7491 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -1393,7 +1393,7 @@ extern (C++) abstract class Type : ASTNode * For our new type 'this', which is type-constructed from t, * fill in the cto, ito, sto, scto, wto shortcuts. */ - final void fixTo(Type t) + extern (D) final void fixTo(Type t) { // If fixing this: immutable(T*) by t: immutable(T)*, // cache t to this.xto won't break transitivity. @@ -1528,7 +1528,7 @@ extern (C++) abstract class Type : ASTNode /*************************** * Look for bugs in constructing types. */ - final void check() + extern (D) final void check() { if (mcache) with (mcache) @@ -1722,7 +1722,7 @@ extern (C++) abstract class Type : ASTNode * Apply STCxxxx bits to existing type. * Use *before* semantic analysis is run. */ - final Type addSTC(StorageClass stc) + extern (D) final Type addSTC(StorageClass stc) { Type t = this; if (t.isImmutable()) @@ -2555,7 +2555,7 @@ extern (C++) abstract class Type : ASTNode * Return the mask that an integral type will * fit into. */ - final uinteger_t sizemask() + extern (D) final uinteger_t sizemask() { uinteger_t m; switch (toBasetype().ty) @@ -5227,7 +5227,7 @@ extern (C++) abstract class TypeQualified : Type // us a `TypeQualified` abstract override TypeQualified syntaxCopy(); - final void syntaxCopyHelper(TypeQualified t) + extern (D) final void syntaxCopyHelper(TypeQualified t) { //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t.toChars(), toChars()); idents.setDim(t.idents.length); @@ -5265,17 +5265,17 @@ extern (C++) abstract class TypeQualified : Type } } - final void addIdent(Identifier ident) + extern (D) final void addIdent(Identifier ident) { idents.push(ident); } - final void addInst(TemplateInstance inst) + extern (D) final void addInst(TemplateInstance inst) { idents.push(inst); } - final void addIndex(RootObject e) + extern (D) final void addIndex(RootObject e) { idents.push(e); } diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h index aeeee8c7dad..e72d9187ca4 100644 --- a/gcc/d/dmd/mtype.h +++ b/gcc/d/dmd/mtype.h @@ -39,8 +39,6 @@ typedef union tree_node type; typedef struct TYPE type; #endif -void semanticTypeInfo(Scope *sc, Type *t); - Type *typeSemantic(Type *t, const Loc &loc, Scope *sc); Type *merge(Type *type); @@ -272,9 +270,6 @@ public: Type *wildConstOf(); Type *sharedWildOf(); Type *sharedWildConstOf(); - void fixTo(Type *t); - void check(); - Type *addSTC(StorageClass stc); Type *castMod(MOD mod); Type *addMod(MOD mod); virtual Type *addStorageClass(StorageClass stc); @@ -316,7 +311,6 @@ public: virtual bool hasInvariant(); virtual Type *nextOf(); Type *baseElemOf(); - uinteger_t sizemask(); virtual bool needsDestruction(); virtual bool needsCopyOrPostblit(); virtual bool needsNested(); @@ -707,10 +701,6 @@ public: // representing ident.ident!tiargs.ident. ... etc. Objects idents; - void syntaxCopyHelper(TypeQualified *t); - void addIdent(Identifier *ident); - void addInst(TemplateInstance *inst); - void addIndex(RootObject *expr); uinteger_t size(const Loc &loc) override; void accept(Visitor *v) override { v->visit(this); } @@ -937,7 +927,5 @@ public: /**************************************************************/ -bool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2); - // If the type is a class or struct, returns the symbol for it, else null. AggregateDeclaration *isAggregate(Type *t); diff --git a/gcc/d/dmd/objc.h b/gcc/d/dmd/objc.h index a5cc6f1b089..40f634e9122 100644 --- a/gcc/d/dmd/objc.h +++ b/gcc/d/dmd/objc.h @@ -30,8 +30,6 @@ struct ObjcSelector static void _init(); - ObjcSelector(const char *sv, size_t len, size_t pcount); - static ObjcSelector *create(FuncDeclaration *fdecl); }; diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h index 3c4ae495265..178542e37b0 100644 --- a/gcc/d/dmd/scope.h +++ b/gcc/d/dmd/scope.h @@ -126,6 +126,4 @@ struct Scope AliasDeclaration *aliasAsg; // if set, then aliasAsg is being assigned a new value, // do not set wasRead for it - - Dsymbol *search(const Loc &loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone); }; diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d index 465bffe4da0..80c9a46958f 100644 --- a/gcc/d/dmd/sideeffect.d +++ b/gcc/d/dmd/sideeffect.d @@ -32,7 +32,7 @@ import dmd.visitor; * 1. save evaluation order * 2. prevent sharing of sub-expression in AST */ -extern (C++) bool isTrivialExp(Expression e) +bool isTrivialExp(Expression e) { extern (C++) final class IsTrivialExp : StoppableVisitor { @@ -70,7 +70,7 @@ extern (C++) bool isTrivialExp(Expression e) * assumeImpureCalls = whether function calls should always be assumed to * be impure (e.g. debug is allowed to violate purity) */ -extern (C++) bool hasSideEffect(Expression e, bool assumeImpureCalls = false) +bool hasSideEffect(Expression e, bool assumeImpureCalls = false) { extern (C++) final class LambdaHasSideEffect : StoppableVisitor { diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d index 5a31e07dc0f..b5906c8edc3 100644 --- a/gcc/d/dmd/statement.d +++ b/gcc/d/dmd/statement.d @@ -114,7 +114,7 @@ extern (C++) abstract class Statement : ASTNode * Returns: * `true` if statement uses exception handling */ - final bool usesEH() + extern (D) final bool usesEH() { extern (C++) final class UsesEH : StoppableVisitor { @@ -153,7 +153,7 @@ extern (C++) abstract class Statement : ASTNode * Returns: * `true` if statement 'comes from' somewhere else, like a goto */ - final bool comeFrom() + extern (D) final bool comeFrom() { extern (C++) final class ComeFrom : StoppableVisitor { @@ -192,7 +192,7 @@ extern (C++) abstract class Statement : ASTNode * Returns: * `true` if statement has executable code. */ - final bool hasCode() + extern (D) final bool hasCode() { extern (C++) final class HasCode : StoppableVisitor { diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h index 73feb3f912b..ef8423f1cf7 100644 --- a/gcc/d/dmd/statement.h +++ b/gcc/d/dmd/statement.h @@ -116,8 +116,6 @@ public: virtual Statement *getRelatedLabeled() { return this; } virtual bool hasBreak() const; virtual bool hasContinue() const; - bool usesEH(); - bool comeFrom(); bool hasCode(); virtual Statement *last(); @@ -709,7 +707,7 @@ class AsmStatement : public Statement { public: Token *tokens; - bool caseSensitive; // for register names + d_bool caseSensitive; // for register names AsmStatement *syntaxCopy() override; void accept(Visitor *v) override { v->visit(this); } diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h index 8622b5c6483..44f95ec0ec3 100644 --- a/gcc/d/dmd/template.h +++ b/gcc/d/dmd/template.h @@ -96,12 +96,8 @@ public: Visibility visible() override; - MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration* td2, ArgumentList argumentList); - RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o); - TemplateDeclaration *isTemplateDeclaration() override { return this; } - TemplateTupleParameter *isVariadic(); bool isDeprecated() const override; bool isOverloadable() const override; @@ -298,7 +294,6 @@ public: const char *toChars() const override; const char* toPrettyCharsHelper() override final; Identifier *getIdent() override final; - hash_t toHash(); bool isDiscardable(); bool needsCodegen(); diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d index c76d549550a..317a6e6c382 100644 --- a/gcc/d/dmd/tokens.d +++ b/gcc/d/dmd/tokens.d @@ -900,7 +900,7 @@ extern (C++) struct Token nothrow: - int isKeyword() pure const @safe @nogc + extern (D) int isKeyword() pure const @safe @nogc { foreach (kw; keywords) { diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h index b1f633fb9d9..560942d1e47 100644 --- a/gcc/d/dmd/tokens.h +++ b/gcc/d/dmd/tokens.h @@ -469,10 +469,7 @@ struct Token Identifier *ident; }; - void free(); - Token() : next(NULL) {} - int isKeyword(); const char *toChars() const; static const char *toChars(TOK value); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 72180b100af..29f114a1b99 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -2368,22 +2368,10 @@ public: if (e->arguments->length == 1) { - /* Single dimension array allocations. */ - Expression *arg = (*e->arguments)[0]; - - if (tarray->next->size () == 0) - { - /* Array element size is unknown. */ - this->result_ = d_array_value (build_ctype (e->type), - size_int (0), null_pointer_node); - return; - } - - libcall_fn libcall = tarray->next->isZeroInit () - ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT; - result = build_libcall (libcall, tb, 2, - build_typeinfo (e, e->type), - build_expr (arg)); + /* Single dimension array allocations has already been handled by + the front-end. */ + gcc_assert (e->lowering); + result = build_expr (e->lowering); } else { diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def index 4d1ba09f1a7..f7887e1548f 100644 --- a/gcc/d/runtime.def +++ b/gcc/d/runtime.def @@ -70,13 +70,8 @@ DEF_D_RUNTIME (DYNAMIC_CAST, "_d_dynamic_cast", RT(OBJECT), DEF_D_RUNTIME (INTERFACE_CAST, "_d_interface_cast", RT(OBJECT), P2(OBJECT, CLASSINFO), 0) -/* Used when calling new on an array. The `i' variant is for when the - initializer is nonzero, and the `m' variant is when initializing a - multi-dimensional array. */ -DEF_D_RUNTIME (NEWARRAYT, "_d_newarrayT", RT(ARRAY_VOID), - P2(CONST_TYPEINFO, SIZE_T), 0) -DEF_D_RUNTIME (NEWARRAYIT, "_d_newarrayiT", RT(ARRAY_VOID), - P2(CONST_TYPEINFO, SIZE_T), 0) +/* Used when calling `new' on a multi-dimensional array. + The `i' variant is for when the initializer is nonzero. */ DEF_D_RUNTIME (NEWARRAYMTX, "_d_newarraymTX", RT(ARRAY_VOID), P2(CONST_TYPEINFO, ARRAY_SIZE_T), 0) DEF_D_RUNTIME (NEWARRAYMITX, "_d_newarraymiTX", RT(ARRAY_VOID), diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d b/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d index ebefe33f2db..6d3b223db0e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice10727a.d @@ -4,6 +4,8 @@ TEST_OUTPUT: --- fail_compilation/imports/foo10727a.d(34): Error: undefined identifier `Frop` +fail_compilation/imports/foo10727a.d(26): Error: template instance `foo10727a.CirBuff!(Foo)` error instantiating +fail_compilation/imports/foo10727a.d(31): instantiated from here: `Bar!(Foo)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d b/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d index 125ac12b193..4a59d5ce6b5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice10727b.d @@ -4,6 +4,8 @@ TEST_OUTPUT: --- fail_compilation/imports/foo10727b.d(25): Error: undefined identifier `Frop` +fail_compilation/imports/foo10727b.d(17): Error: template instance `foo10727b.CirBuff!(Foo)` error instantiating +fail_compilation/imports/foo10727b.d(22): instantiated from here: `Bar!(Foo)` --- */ diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 794600274a3..2a0baf09a4b 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -4c18eed9674e04c1ca89fbc8bd5c4e483eb5477c +e48bc0987dfec35bc76a3015ee3e85906ce86dfd The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d index 25083597761..54f8767139c 100644 --- a/libphobos/libdruntime/core/internal/array/construction.d +++ b/libphobos/libdruntime/core/internal/array/construction.d @@ -11,6 +11,11 @@ module core.internal.array.construction; import core.internal.traits : Unqual; +debug(PRINTF) +{ + import core.stdc.stdio; +} + /** * Does array initialization (not assignment) from another array of the same element type. * Params: @@ -319,3 +324,165 @@ void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted assert(!didThrow); assert(counter == 4); } + +/** + * Allocate an array with the garbage collector. Also initalize elements if + * their type has an initializer. Otherwise, not zero-initialize the array. + * + * Has three variants: + * `_d_newarrayU` leaves elements uninitialized + * `_d_newarrayT` initializes to 0 or based on initializer + * + * Params: + * length = `.length` of resulting array + * + * Returns: + * newly allocated array + */ +T[] _d_newarrayU(T)(size_t length, bool isShared=false) pure nothrow @nogc @trusted +{ + alias PureType = T[] function(size_t length, bool isShared) pure nothrow @nogc @trusted; + return (cast(PureType) &_d_newarrayUImpl!T)(length, isShared); +} + +T[] _d_newarrayUImpl(T)(size_t length, bool isShared=false) @trusted +{ + import core.exception : onOutOfMemoryError; + import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc; + + size_t elemSize = T.sizeof; + size_t arraySize; + + debug(PRINTF) printf("_d_newarrayU(length = x%zu, size = %zu)\n", length, elemSize); + if (length == 0 || elemSize == 0) + return null; + + version (D_InlineAsm_X86) + { + asm pure nothrow @nogc + { + mov EAX, elemSize ; + mul EAX, length ; + mov arraySize, EAX ; + jnc Lcontinue ; + } + } + else version (D_InlineAsm_X86_64) + { + asm pure nothrow @nogc + { + mov RAX, elemSize ; + mul RAX, length ; + mov arraySize, RAX ; + jnc Lcontinue ; + } + } + else + { + import core.checkedint : mulu; + + bool overflow = false; + arraySize = mulu(elemSize, length, overflow); + if (!overflow) + goto Lcontinue; + } + +Loverflow: + onOutOfMemoryError(); + assert(0); + +Lcontinue: + auto info = __arrayAlloc!T(arraySize); + if (!info.base) + goto Loverflow; + debug(PRINTF) printf("p = %p\n", info.base); + + auto arrstart = __arrayStart(info); + + __setArrayAllocLength!T(info, arraySize, isShared); + + return (cast(T*) arrstart)[0 .. length]; +} + +/// ditto +T[] _d_newarrayT(T)(size_t length, bool isShared=false) @trusted +{ + T[] result = _d_newarrayU!T(length, isShared); + + static if (__traits(isZeroInit, T)) + { + import core.stdc.string : memset; + memset(result.ptr, 0, length * T.sizeof); + } + else + { + import core.internal.lifetime : emplaceInitializer; + foreach (ref elem; result) + emplaceInitializer(elem); + } + + return result; +} + +unittest +{ + { + // zero-initialization + struct S { int x, y; } + S[] s = _d_newarrayT!S(10); + + assert(s !is null); + assert(s.length == 10); + foreach (ref elem; s) + { + assert(elem.x == 0); + assert(elem.y == 0); + } + } + { + // S.init + struct S { int x = 2, y = 3; } + S[] s = _d_newarrayT!S(10); + + assert(s.length == 10); + foreach (ref elem; s) + { + assert(elem.x == 2); + assert(elem.y == 3); + } + } +} + +unittest +{ + int pblits; + + struct S + { + this(this) { pblits++; } + } + + S[] s = _d_newarrayT!S(2); + + assert(s.length == 2); + assert(pblits == 0); +} + +version (D_ProfileGC) +{ + /** + * TraceGC wrapper around $(REF _d_newitemT, core,lifetime). + */ + T[] _d_newarrayTTrace(T)(string file, int line, string funcname, size_t length, bool isShared) @trusted + { + version (D_TypeInfo) + { + import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure; + mixin(TraceHook!(T.stringof, "_d_newarrayT")); + + return _d_newarrayT!T(length, isShared); + } + else + assert(0, "Cannot create new array if compiling without support for runtime type information!"); + } +} diff --git a/libphobos/libdruntime/core/internal/array/utils.d b/libphobos/libdruntime/core/internal/array/utils.d index a16005e714d..57eb14bd6a7 100644 --- a/libphobos/libdruntime/core/internal/array/utils.d +++ b/libphobos/libdruntime/core/internal/array/utils.d @@ -10,6 +10,25 @@ module core.internal.array.utils; import core.internal.traits : Parameters; +import core.memory : GC; + +alias BlkInfo = GC.BlkInfo; +alias BlkAttr = GC.BlkAttr; + +private +{ + enum : size_t + { + PAGESIZE = 4096, + BIGLENGTHMASK = ~(PAGESIZE - 1), + SMALLPAD = 1, + MEDPAD = ushort.sizeof, + LARGEPREFIX = 16, // 16 bytes padding at the front of the array + LARGEPAD = LARGEPREFIX + 1, + MAXSMALLSIZE = 256-SMALLPAD, + MAXMEDSIZE = (PAGESIZE / 2) - MEDPAD + } +} auto gcStatsPure() nothrow pure { @@ -136,3 +155,220 @@ template isPostblitNoThrow(T) { else enum isPostblitNoThrow = true; } + +/** + * Clear padding that might not be zeroed by the GC (it assumes it is within the + * requested size from the start, but it is actually at the end of the allocated + * block). + * + * Params: + * info = array allocation data + * arrSize = size of the array in bytes + * padSize = size of the padding in bytes + */ +void __arrayClearPad()(ref BlkInfo info, size_t arrSize, size_t padSize) nothrow pure +{ + import core.stdc.string; + if (padSize > MEDPAD && !(info.attr & BlkAttr.NO_SCAN) && info.base) + { + if (info.size < PAGESIZE) + memset(info.base + arrSize, 0, padSize); + else + memset(info.base, 0, LARGEPREFIX); + } +} + +/** + * Allocate an array memory block by applying the proper padding and assigning + * block attributes if not inherited from the existing block. + * + * Params: + * arrSize = size of the allocated array in bytes + * Returns: + * `BlkInfo` with allocation metadata + */ +BlkInfo __arrayAlloc(T)(size_t arrSize) @trusted +{ + import core.checkedint; + import core.lifetime : TypeInfoSize; + import core.internal.traits : hasIndirections; + + enum typeInfoSize = TypeInfoSize!T; + BlkAttr attr = BlkAttr.APPENDABLE; + + size_t padSize = arrSize > MAXMEDSIZE ? + LARGEPAD : + ((arrSize > MAXSMALLSIZE ? MEDPAD : SMALLPAD) + typeInfoSize); + + bool overflow; + auto paddedSize = addu(arrSize, padSize, overflow); + + if (overflow) + return BlkInfo(); + + /* `extern(C++)` classes don't have a classinfo pointer in their vtable, + * so the GC can't finalize them. + */ + static if (typeInfoSize) + attr |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE; + static if (!hasIndirections!T) + attr |= BlkAttr.NO_SCAN; + + auto bi = GC.qalloc(paddedSize, attr, typeid(T)); + __arrayClearPad(bi, arrSize, padSize); + return bi; +} + +/** + * Get the start of the array for the given block. + * + * Params: + * info = array metadata + * Returns: + * pointer to the start of the array + */ +void *__arrayStart()(return scope BlkInfo info) nothrow pure +{ + return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0); +} + +/** + * Set the allocated length of the array block. This is called when an array + * is appended to or its length is set. + * + * The allocated block looks like this for blocks < PAGESIZE: + * `|elem0|elem1|elem2|...|elemN-1|emptyspace|N*elemsize|` + * + * The size of the allocated length at the end depends on the block size: + * a block of 16 to 256 bytes has an 8-bit length. + * a block with 512 to pagesize/2 bytes has a 16-bit length. + * + * For blocks >= pagesize, the length is a size_t and is at the beginning of the + * block. The reason we have to do this is because the block can extend into + * more pages, so we cannot trust the block length if it sits at the end of the + * block, because it might have just been extended. If we can prove in the + * future that the block is unshared, we may be able to change this, but I'm not + * sure it's important. + * + * In order to do put the length at the front, we have to provide 16 bytes + * buffer space in case the block has to be aligned properly. In x86, certain + * SSE instructions will only work if the data is 16-byte aligned. In addition, + * we need the sentinel byte to prevent accidental pointers to the next block. + * Because of the extra overhead, we only do this for page size and above, where + * the overhead is minimal compared to the block size. + * + * So for those blocks, it looks like: + * `|N*elemsize|padding|elem0|elem1|...|elemN-1|emptyspace|sentinelbyte|`` + * + * where `elem0` starts 16 bytes after the first byte. + */ +bool __setArrayAllocLength(T)(ref BlkInfo info, size_t newLength, bool isShared, size_t oldLength = ~0) +{ + import core.atomic; + import core.lifetime : TypeInfoSize; + + size_t typeInfoSize = TypeInfoSize!T; + + if (info.size <= 256) + { + import core.checkedint; + + bool overflow; + auto newLengthPadded = addu(newLength, + addu(SMALLPAD, typeInfoSize, overflow), + overflow); + + if (newLengthPadded > info.size || overflow) + // new size does not fit inside block + return false; + + auto length = cast(ubyte *)(info.base + info.size - typeInfoSize - SMALLPAD); + if (oldLength != ~0) + { + if (isShared) + { + return cas(cast(shared)length, cast(ubyte)oldLength, cast(ubyte)newLength); + } + else + { + if (*length == cast(ubyte)oldLength) + *length = cast(ubyte)newLength; + else + return false; + } + } + else + { + // setting the initial length, no cas needed + *length = cast(ubyte)newLength; + } + if (typeInfoSize) + { + auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof); + *typeInfo = cast()typeid(T); + } + } + else if (info.size < PAGESIZE) + { + if (newLength + MEDPAD + typeInfoSize > info.size) + // new size does not fit inside block + return false; + auto length = cast(ushort *)(info.base + info.size - typeInfoSize - MEDPAD); + if (oldLength != ~0) + { + if (isShared) + { + return cas(cast(shared)length, cast(ushort)oldLength, cast(ushort)newLength); + } + else + { + if (*length == oldLength) + *length = cast(ushort)newLength; + else + return false; + } + } + else + { + // setting the initial length, no cas needed + *length = cast(ushort)newLength; + } + if (typeInfoSize) + { + auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof); + *typeInfo = cast()typeid(T); + } + } + else + { + if (newLength + LARGEPAD > info.size) + // new size does not fit inside block + return false; + auto length = cast(size_t *)(info.base); + if (oldLength != ~0) + { + if (isShared) + { + return cas(cast(shared)length, cast(size_t)oldLength, cast(size_t)newLength); + } + else + { + if (*length == oldLength) + *length = newLength; + else + return false; + } + } + else + { + // setting the initial length, no cas needed + *length = newLength; + } + if (typeInfoSize) + { + auto typeInfo = cast(TypeInfo*)(info.base + size_t.sizeof); + *typeInfo = cast()typeid(T); + } + } + return true; // resize succeeded +} diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d index 3a55ca916c2..6b083eaa926 100644 --- a/libphobos/libdruntime/core/lifetime.d +++ b/libphobos/libdruntime/core/lifetime.d @@ -2731,7 +2731,8 @@ if (is(T == class)) { import core.internal.traits : hasIndirections; import core.exception : onOutOfMemoryError; - import core.memory : GC, pureMalloc; + import core.memory : pureMalloc; + import core.memory : GC; alias BlkAttr = GC.BlkAttr; @@ -2820,11 +2821,11 @@ T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted T* _d_newitemT(T)() @trusted { import core.internal.lifetime : emplaceInitializer; - import core.internal.traits : hasElaborateDestructor, hasIndirections; + import core.internal.traits : hasIndirections; import core.memory : GC; auto flags = !hasIndirections!T ? GC.BlkAttr.NO_SCAN : GC.BlkAttr.NONE; - immutable tiSize = hasElaborateDestructor!T ? size_t.sizeof : 0; + immutable tiSize = TypeInfoSize!T; immutable itemSize = T.sizeof; immutable totalSize = itemSize + tiSize; if (tiSize) @@ -3004,3 +3005,9 @@ version (D_ProfileGC) assert(0, "Cannot create new `struct` if compiling without support for runtime type information!"); } } + +template TypeInfoSize(T) +{ + import core.internal.traits : hasElaborateDestructor; + enum TypeInfoSize = hasElaborateDestructor!T ? size_t.sizeof : 0; +} diff --git a/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d b/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d new file mode 100644 index 00000000000..aa39ac4bb49 --- /dev/null +++ b/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d @@ -0,0 +1,41 @@ +//Written in the D programming language + +/++ + D header file for FreeBSD's ifaddrs.h. + + Copyright: Copyright 2023 + License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) + +/ +module core.sys.freebsd.ifaddrs; + +version (FreeBSD): +extern(C): +@nogc: +nothrow: + +import core.sys.posix.sys.socket : sockaddr; + +struct ifaddrs +{ + ifaddrs* ifa_next; + char* ifa_name; + uint ifa_flags; + sockaddr* ifa_addr; + sockaddr* ifa_netmask; + sockaddr* ifa_dstaddr; + void* ifa_data; +} + +struct ifmaddrs +{ + ifmaddrs* ifma_next; + sockaddr* ifma_name; + sockaddr* ifma_addr; + sockaddr* ifma_lladdr; +} + +int getifaddrs(ifaddrs**); +void freeifaddrs(ifaddrs*); +int getifmaddrs(ifmaddrs**); +void freeifmaddrs(ifmaddrs*); diff --git a/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d b/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d new file mode 100644 index 00000000000..9f830610fc8 --- /dev/null +++ b/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d @@ -0,0 +1,42 @@ +//Written in the D programming language + +/++ + D header file for FreeBSD's net/if_dl.h. + + Copyright: Copyright 2023 + License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) + +/ +module core.sys.freebsd.net.if_dl; + +version (FreeBSD): +extern(C): +@nogc: +nothrow: + +import core.sys.freebsd.sys.types : caddr_t, c_caddr_t; +import core.sys.posix.sys.socket : sa_family_t, sockaddr; + +struct sockaddr_dl +{ + ubyte sdl_len; + sa_family_t sdl_family; + ushort sdl_index; + ubyte sdl_type; + ubyte sdl_nlen; + ubyte sdl_alen; + ubyte sdl_slen; + ubyte[46] sdl_data; +} + +auto LLADDR()(sockaddr_dl* s) { return cast(caddr_t)(s.sdl_data.ptr + s.sdl_nlen); } +auto CLLADDR()(const sockaddr_dl* s) { return cast(c_caddr_t)(s.sdl_data.ptr + s.sdl_nlen); } +ushort LLINDEX()(const sockaddr_dl* s) { return s.sdl_index; } + +struct ifnet; +sockaddr_dl* link_alloc_sdl(size_t, int); +void link_free_sdl(sockaddr* sa); +sockaddr_dl* link_init_sdl(ifnet*, sockaddr*, ubyte); + +void link_addr(const char*, sockaddr_dl*); +char* link_ntoa(const sockaddr_dl*); diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/socket.d b/libphobos/libdruntime/core/sys/freebsd/sys/socket.d new file mode 100644 index 00000000000..6d61286ddfa --- /dev/null +++ b/libphobos/libdruntime/core/sys/freebsd/sys/socket.d @@ -0,0 +1,131 @@ +//Written in the D programming language + +/++ + D header file for FreeBSD's extensions to POSIX's sys/socket.h. + + Copyright: Copyright 2023 + License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) + +/ +module core.sys.freebsd.sys.socket; + +public import core.sys.posix.sys.socket; + +version (FreeBSD): +extern(C): +@nogc: +nothrow: + +// Creation flags, OR'ed into socket() and socketpair() type argument. +enum : uint +{ + SOCK_CLOEXEC = 0x10000000, + SOCK_NONBLOCK = 0x20000000, +} + +// Option flags per-socket. +enum : uint +{ + SO_USELOOPBACK = 0x00000040, + SO_TIMESTAMP = 0x00000400, + SO_ACCEPTFILTER = 0x00001000, + SO_BINTIME = 0x00002000, + + SO_NO_OFFLOAD = 0x00004000, + SO_NO_DDP = 0x00008000, + SO_REUSEPORT_LB = 0x00010000, + SO_RERROR = 0x00020000, +} + + +// Additional options, not kept in so_options. +enum : uint +{ + SO_LABEL = 0x1009, + SO_PEERLABEL = 0x1010, + SO_LISTENQLIMIT = 0x1011, + SO_LISTENQLEN = 0x1012, + SO_LISTENINCQLEN = 0x1013, + SO_SETFIB = 0x1014, + SO_USER_COOKIE = 0x1015, + SO_PROTOCOL = 0x1016, + SO_PROTOTYPE = SO_PROTOCOL, + SO_TS_CLOCK = 0x1017, + SO_MAX_PACING_RATE = 0x1018, + SO_DOMAIN = 0x1019, + + SO_TS_REALTIME_MICRO = 0, + SO_TS_BINTIME = 1, + SO_TS_REALTIME = 2, + SO_TS_MONOTONIC = 3, + SO_TS_DEFAULT = SO_TS_REALTIME_MICRO, + SO_TS_CLOCK_MAX = SO_TS_MONOTONIC, +} + +/+ + Space reserved for new socket options added by third-party vendors. + This range applies to all socket option levels. New socket options + in FreeBSD should always use an option value less than SO_VENDOR. + +/ +enum : uint +{ + SO_VENDOR = 0x80000000, +} + +struct accept_filter_arg +{ + char[16] af_name; + char [256-16] af_arg; +} + +// Address families. +enum : uint +{ + AF_LOCAL = AF_UNIX, + + AF_IMPLINK = 3, + AF_PUP = 4, + AF_CHAOS = 5, + AF_NETBIOS = 6, + AF_ISO = 7, + AF_OSI = AF_ISO, + AF_ECMA = 8, + AF_DATAKIT = 9, + AF_CCITT = 10, + AF_SNA = 11, + AF_DECnet = 12, + AF_DLI = 13, + AF_LAT = 14, + AF_HYLINK = 15, + + AF_ROUTE = 17, + AF_LINK = 18, + pseudo_AF_XTP = 19, + AF_COIP = 20, + AF_CNT = 21, + pseudo_AF_RTIP = 22, + + AF_SIP = 24, + pseudo_AF_PIP = 25, + AF_ISDN = 26, + AF_E164 = AF_ISDN, + pseudo_AF_KEY = 27, + + AF_NATM = 29, + AF_ATM = 30, + pseudo_AF_HDRCMPLT = 31, + AF_NETGRAPH = 32, + AF_SLOW = 33, + AF_SCLUSTER = 34, + AF_ARP = 35, + AF_BLUETOOTH = 36, + AF_IEEE80211 = 37, + AF_NETLINK = 38, + + AF_INET_SDP = 40, + + AF_INET6_SDP = 42, + AF_HYPERV = 43, + AF_DIVERT = 44, + AF_MAX = 44, +} diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/types.d b/libphobos/libdruntime/core/sys/freebsd/sys/types.d new file mode 100644 index 00000000000..b927ddf815b --- /dev/null +++ b/libphobos/libdruntime/core/sys/freebsd/sys/types.d @@ -0,0 +1,58 @@ +//Written in the D programming language + +/++ + D header file for FreeBSD's extensions to POSIX's sys/types.h. + + Copyright: Copyright 2023 + License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) + +/ +module core.sys.freebsd.sys.types; + +public import core.sys.posix.sys.types; + +version (FreeBSD): +extern(C): +@nogc: +nothrow: + +import core.stdc.config; + +alias caddr_t = ubyte*; +alias c_caddr_t = const(ubyte)*; + +alias cpuwhich_t = int; +alias cpulevel_t = int; +alias cpusetid_t = int; + +alias critical_t = size_t; +alias daddr_t = long; + +alias fixpt_t = uint; + +alias accmode_t = int; + +alias register_t = size_t; + +alias sbintime_t = long; + +alias segsz_t = size_t; + +alias u_register_t = size_t; + +alias cap_ioctl_t = size_t; + +alias kpaddr_t = ulong; +alias kvaddr_t = ulong; +alias ksize_t = ulong; +alias kssize_t = long; + +alias vm_offset_t = size_t; +alias vm_ooffset_t = ulong; +alias vm_paddr_t = ulong; +alias vm_pindex_t = ulong; +alias vm_size_t = size_t; + +alias rman_res_t = ulong; + +alias syscallarg_t = register_t; diff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d index f0ce29f3925..642b3839aa0 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/types.d +++ b/libphobos/libdruntime/core/sys/posix/sys/types.d @@ -187,7 +187,7 @@ else version (FreeBSD) alias c_long ssize_t; alias c_long time_t; alias uint uid_t; - alias uint fflags_t; + alias uint fflags_t; // non-standard } else version (NetBSD) { @@ -866,7 +866,7 @@ else version (Darwin) } else version (FreeBSD) { - alias int lwpid_t; + alias int lwpid_t; // non-standard alias void* pthread_attr_t; alias void* pthread_cond_t; diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index 294d34dbe35..0111be0b617 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -4668,6 +4668,7 @@ version (D_ProfileGC) public import core.internal.array.appending : _d_arrayappendTTrace; public import core.internal.array.concatenation : _d_arraycatnTXTrace; public import core.lifetime : _d_newitemTTrace; + public import core.internal.array.construction : _d_newarrayTTrace; } public import core.internal.array.appending : _d_arrayappendcTXImpl; public import core.internal.array.comparison : __cmp; @@ -4676,6 +4677,7 @@ public import core.internal.array.casting: __ArrayCast; public import core.internal.array.concatenation : _d_arraycatnTX; public import core.internal.array.construction : _d_arrayctor; public import core.internal.array.construction : _d_arraysetctor; +public import core.internal.array.construction : _d_newarrayT; public import core.internal.array.arrayassign : _d_arrayassign_l; public import core.internal.array.arrayassign : _d_arrayassign_r; public import core.internal.array.arrayassign : _d_arraysetassign; diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d index 1245374ec5f..af3c6bb1296 100644 --- a/libphobos/libdruntime/rt/lifetime.d +++ b/libphobos/libdruntime/rt/lifetime.d @@ -13,6 +13,7 @@ module rt.lifetime; import core.attribute : weak; +import core.internal.array.utils : __arrayStart, __arrayClearPad; import core.memory; debug(PRINTF) import core.stdc.stdio; static import rt.tlsgc; @@ -226,7 +227,6 @@ size_t structTypeInfoSize(const TypeInfo ti) pure nothrow @nogc private class ArrayAllocLengthLock {} - /** Set the allocated length of the array block. This is called any time an array is appended to or its length is set. @@ -386,14 +386,6 @@ private size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure return *cast(size_t *)(info.base); } -/** - get the start of the array for the given block - */ -private void *__arrayStart(return scope BlkInfo info) nothrow pure -{ - return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0); -} - /** get the padding required to allocate size bytes. Note that the padding is NOT included in the passed in size. Therefore, do NOT call this function @@ -404,22 +396,6 @@ private size_t __arrayPad(size_t size, const TypeInfo tinext) nothrow pure @trus return size > MAXMEDSIZE ? LARGEPAD : ((size > MAXSMALLSIZE ? MEDPAD : SMALLPAD) + structTypeInfoSize(tinext)); } -/** - clear padding that might not be zeroed by the GC (it assumes it is within the - requested size from the start, but it is actually at the end of the allocated block) - */ -private void __arrayClearPad(ref BlkInfo info, size_t arrsize, size_t padsize) nothrow pure -{ - import core.stdc.string; - if (padsize > MEDPAD && !(info.attr & BlkAttr.NO_SCAN) && info.base) - { - if (info.size < PAGESIZE) - memset(info.base + arrsize, 0, padsize); - else - memset(info.base, 0, LARGEPREFIX); - } -} - /** allocate an array memory block by applying the proper padding and assigning block attributes if not inherited from the existing block diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 9a979272d6e..a7bf856d747 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -d945686a4ff7d9fda0e2ee8d2ee201b66be2a287 +2458e8f82e3004197d8a66239a6b72e17264bb26 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/parallelism.d b/libphobos/src/std/parallelism.d index 9b231f3ac8a..3fe8cd61fe0 100644 --- a/libphobos/src/std/parallelism.d +++ b/libphobos/src/std/parallelism.d @@ -1581,7 +1581,7 @@ public: auto logs = new double[10_000_000]; // Parallel foreach works with or without an index - // variable. It can be iterate by ref if range.front + // variable. It can iterate by ref if range.front // returns by ref. // Iterate over logs using work units of size 100. diff --git a/libphobos/src/std/range/primitives.d b/libphobos/src/std/range/primitives.d index ef34a85e5ec..1a3fb06cf99 100644 --- a/libphobos/src/std/range/primitives.d +++ b/libphobos/src/std/range/primitives.d @@ -540,13 +540,9 @@ private void putChar(R, E)(ref R r, E e) if (isSomeChar!E) { // https://issues.dlang.org/show_bug.cgi?id=9186: Can't use (E[]).init - ref const( char)[] cstringInit(); - ref const(wchar)[] wstringInit(); - ref const(dchar)[] dstringInit(); - - enum csCond = is(typeof(doPut(r, cstringInit()))); - enum wsCond = is(typeof(doPut(r, wstringInit()))); - enum dsCond = is(typeof(doPut(r, dstringInit()))); + enum csCond = is(typeof(doPut(r, (){ ref const( char)[] cstringInit(); return cstringInit(); }()))); + enum wsCond = is(typeof(doPut(r, (){ ref const(wchar)[] wstringInit(); return wstringInit(); }()))); + enum dsCond = is(typeof(doPut(r, (){ ref const(dchar)[] dstringInit(); return dstringInit(); }()))); //Use "max" to avoid static type demotion enum ccCond = is(typeof(doPut(r, char.max))); diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d index 2ed7ee527b0..aa69aacfd10 100644 --- a/libphobos/src/std/traits.d +++ b/libphobos/src/std/traits.d @@ -67,6 +67,7 @@ * $(LREF isAssignable) * $(LREF isCovariantWith) * $(LREF isImplicitlyConvertible) + * $(LREF isQualifierConvertible) * )) * $(TR $(TD Type Constructors) $(TD * $(LREF InoutOf) @@ -5166,6 +5167,62 @@ enum bool isImplicitlyConvertible(From, To) = is(From : To); static assert( isImplicitlyConvertible!(string, const(char)[])); } +/** +Is `From` $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible) to `To`? +*/ +enum bool isQualifierConvertible(From, To) = + is(immutable From == immutable To) && is(From* : To*); + +/// +@safe unittest +{ + // Mutable and immmutable both convert to const... + static assert( isQualifierConvertible!(char, const(char))); + static assert( isQualifierConvertible!(immutable(char), const(char))); + // ...but const does not convert back to mutable or immutable + static assert(!isQualifierConvertible!(const(char), char)); + static assert(!isQualifierConvertible!(const(char), immutable(char))); +} + +@safe unittest +{ + import std.meta : AliasSeq; + + alias Ts = AliasSeq!(int, const int, shared int, inout int, const shared int, + const inout int, inout shared int, const inout shared int, immutable int); + + // https://dlang.org/spec/const3.html#implicit_qualifier_conversions + enum _ = 0; + static immutable bool[Ts.length][Ts.length] conversions = [ + // m c s i cs ci is cis im + [1, 1, _, _, _, _, _, _, _], // mutable + [_, 1, _, _, _, _, _, _, _], // const + [_, _, 1, _, 1, _, _, _, _], // shared + [_, 1, _, 1, _, 1, _, _, _], // inout + [_, _, _, _, 1, _, _, _, _], // const shared + [_, 1, _, _, _, 1, _, _, _], // const inout + [_, _, _, _, 1, _, 1, 1, _], // inout shared + [_, _, _, _, 1, _, _, 1, _], // const inout shared + [_, 1, _, _, 1, 1, _, 1, 1], // immutable + ]; + + static foreach (i, From; Ts) + { + static foreach (j, To; Ts) + { + static assert(isQualifierConvertible!(From, To) == conversions[i][j], + "`isQualifierConvertible!(" ~ From.stringof ~ ", " ~ To.stringof ~ ")`" + ~ " should be `" ~ (conversions[i][j] ? "true" : "false") ~ "`"); + } + } +} + +@safe unittest +{ + // int* -> void* is not a qualifier conversion + static assert(!isQualifierConvertible!(int, void)); +} + /** Returns `true` iff a value of type `Rhs` can be assigned to a variable of type `Lhs`.