aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/aggregate.d8
-rw-r--r--gcc/d/dmd/aggregate.h8
-rw-r--r--gcc/d/dmd/aliasthis.h2
-rw-r--r--gcc/d/dmd/attrib.h1
-rw-r--r--gcc/d/dmd/canthrow.d2
-rw-r--r--gcc/d/dmd/cond.d2
-rw-r--r--gcc/d/dmd/cond.h2
-rw-r--r--gcc/d/dmd/cparse.d17
-rw-r--r--gcc/d/dmd/dcast.d2
-rw-r--r--gcc/d/dmd/dclass.d8
-rw-r--r--gcc/d/dmd/declaration.d1
-rw-r--r--gcc/d/dmd/declaration.h12
-rw-r--r--gcc/d/dmd/denum.d2
-rw-r--r--gcc/d/dmd/dimport.d2
-rw-r--r--gcc/d/dmd/dinterpret.d3
-rw-r--r--gcc/d/dmd/dmodule.d2
-rw-r--r--gcc/d/dmd/dscope.d2
-rw-r--r--gcc/d/dmd/dstruct.d2
-rw-r--r--gcc/d/dmd/dsymbol.d7
-rw-r--r--gcc/d/dmd/dsymbolsem.d15
-rw-r--r--gcc/d/dmd/dtemplate.d8
-rw-r--r--gcc/d/dmd/expression.d90
-rw-r--r--gcc/d/dmd/expression.h88
-rw-r--r--gcc/d/dmd/expressionsem.d53
-rw-r--r--gcc/d/dmd/func.d20
-rw-r--r--gcc/d/dmd/globals.h6
-rw-r--r--gcc/d/dmd/hdrgen.d38
-rw-r--r--gcc/d/dmd/id.d2
-rw-r--r--gcc/d/dmd/import.h1
-rw-r--r--gcc/d/dmd/init.h1
-rw-r--r--gcc/d/dmd/location.d2
-rw-r--r--gcc/d/dmd/module.h1
-rw-r--r--gcc/d/dmd/mtype.d16
-rw-r--r--gcc/d/dmd/mtype.h12
-rw-r--r--gcc/d/dmd/objc.h2
-rw-r--r--gcc/d/dmd/scope.h2
-rw-r--r--gcc/d/dmd/sideeffect.d4
-rw-r--r--gcc/d/dmd/statement.d6
-rw-r--r--gcc/d/dmd/statement.h4
-rw-r--r--gcc/d/dmd/template.h5
-rw-r--r--gcc/d/dmd/tokens.d2
-rw-r--r--gcc/d/dmd/tokens.h3
-rw-r--r--gcc/d/expr.cc20
-rw-r--r--gcc/d/runtime.def9
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice10727a.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice10727b.d2
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/internal/array/construction.d167
-rw-r--r--libphobos/libdruntime/core/internal/array/utils.d236
-rw-r--r--libphobos/libdruntime/core/lifetime.d13
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/ifaddrs.d41
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/net/if_dl.d42
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/socket.d131
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/types.d58
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/types.d4
-rw-r--r--libphobos/libdruntime/object.d2
-rw-r--r--libphobos/libdruntime/rt/lifetime.d26
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/parallelism.d2
-rw-r--r--libphobos/src/std/range/primitives.d10
-rw-r--r--libphobos/src/std/traits.d57
63 files changed, 962 insertions, 334 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index bfadeaa..2a0baf0 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 fd05dcf..b272d4b 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 68b5f1b..d9b48b5 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 4b107e0..58a0126 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 389cff4..092490f 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 1e75598..f47a1f6 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 bb1fd6f..8aece3b 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 e4d1096..9fa8a25 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 45094d1..d02ae13 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 d183b82..0b738cd 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 9f661ea..e4d5805 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 0fbbb11..09a4f4e 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 40463b4..d634e7f 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 71f2baa..8cd295f 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 98bf4dd..f33b5fd 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 3b8d9f6..d74c860 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 fc5a3aa..cbd9740 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 9031b15..548928a 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 14dbe9c..3853512 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 56aad3e..5171e1f 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 6538664..579a542 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 4de037c..8309e4a 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 ae49dda..5dca6df 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 2c55f0eb..32ded3b 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 a92d9ad..cfd5198 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<int v>
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<bool> 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<bool> 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 3472f92..ac8e571 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 ac73e70..99848d8 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 4048286..5c21be1 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 9d585cb..d935bd3 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 b506e6f..5fcda91 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 ff25ba2..31ee61a 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 4ab5848..67d0527 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 ef2bd0a..9fe48b8 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 ce51266..6e8153d 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 70a0c03..6af140f 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 aeeee8c..e72d918 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 a5cc6f1..40f634e 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 3c4ae49..178542e 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 465bffe..80c9a46 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 5a31e07..b5906c8 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 73feb3f..ef8423f 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 8622b5c..44f95ec 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 c76d549..317a6e6 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 b1f633f..560942d 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 72180b1..29f114a 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 4d1ba09..f7887e1 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 ebefe33..6d3b223 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 125ac12..4a59d5c 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 7946002..2a0baf0 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 2508359..54f8767 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 a16005e..57eb14b 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 3a55ca9..6b083ea 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 0000000..aa39ac4
--- /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 0000000..9f83061
--- /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 0000000..6d61286
--- /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 0000000..b927ddf
--- /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 f0ce29f..642b383 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 294d34d..0111be0 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 1245374..af3c6bb 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.
@@ -387,14 +387,6 @@ private size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure
}
/**
- 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
with the size of an allocated block.
@@ -405,22 +397,6 @@ private size_t __arrayPad(size_t size, const TypeInfo tinext) nothrow pure @trus
}
/**
- 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 9a97927..a7bf856 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 9b231f3..3fe8cd6 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 ef34a85..1a3fb06 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 2ed7ee5..aa69aac 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)
@@ -5167,6 +5168,62 @@ enum bool isImplicitlyConvertible(From, To) = is(From : To);
}
/**
+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`.