@@ -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.
@@ -1 +1 @@
-v2.105.2
+v2.106.0-beta.1
@@ -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)
@@ -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;
@@ -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;
@@ -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); }
@@ -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
@@ -133,7 +133,7 @@ extern (C++) final class StaticForeach : RootObject
this.rangefe = rangefe;
}
- StaticForeach syntaxCopy()
+ extern (D) StaticForeach syntaxCopy()
{
return new StaticForeach(
loc,
@@ -53,8 +53,6 @@ public:
ForeachRangeStatement *rangefe;
d_bool needExpansion;
-
- StaticForeach *syntaxCopy();
};
class DVCondition : public Condition
@@ -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
@@ -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();
@@ -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;
@@ -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
@@ -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;
@@ -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)
@@ -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
@@ -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)
@@ -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());
@@ -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)
{
@@ -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)
{
@@ -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`
*
@@ -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
@@ -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)
{
@@ -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());
@@ -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:
@@ -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);
@@ -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;
@@ -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
@@ -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)
@@ -321,6 +321,8 @@ immutable Msgtable[] msgtable =
{ "_d_newclassTTrace" },
{ "_d_newitemT" },
{ "_d_newitemTTrace" },
+ { "_d_newarrayT" },
+ { "_d_newarrayTTrace" },
{ "_d_assert_fail" },
{ "dup" },
{ "_aaApply" },
@@ -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;
@@ -79,7 +79,6 @@ public:
d_bool isCarray; // C array semantics
bool isAssociativeArray() const;
- Expression *toAssocArrayLiteral();
void accept(Visitor *v) override { v->visit(this); }
};
@@ -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;
@@ -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();
@@ -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);
}
@@ -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);
@@ -30,8 +30,6 @@ struct ObjcSelector
static void _init();
- ObjcSelector(const char *sv, size_t len, size_t pcount);
-
static ObjcSelector *create(FuncDeclaration *fdecl);
};
@@ -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);
};
@@ -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
{
@@ -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
{
@@ -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); }
@@ -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();
@@ -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)
{
@@ -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);
@@ -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
{
@@ -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),
@@ -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)`
---
*/
@@ -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)`
---
*/
@@ -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.
@@ -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!");
+ }
+}
@@ -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
+}
@@ -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;
+}
new file mode 100644
@@ -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*);
new file mode 100644
@@ -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*);
new file mode 100644
@@ -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,
+}
new file mode 100644
@@ -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;
@@ -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;
@@ -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;
@@ -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
@@ -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.
@@ -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.
@@ -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)));
@@ -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`.