Skip to content

Commit d2a9c83

Browse files
authored
Merge pull request #4962 from ldc-developers/merge-2.112
Merge upstream stable
2 parents 9db6d95 + c0a3972 commit d2a9c83

File tree

151 files changed

+4068
-2465
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+4068
-2465
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# LDC master
22

33
#### Big news
4-
- Frontend, druntime and Phobos are at version ~[2.112.0](https://dlang.org/changelog/2.112.0.html). (#4949)
4+
- Frontend, druntime and Phobos are at version ~[2.112.0](https://dlang.org/changelog/2.112.0.html), incl. new command-line options `-extI`, `-dllimport=externalOnly` and `-edition`. (#4949, #4962)
55
- **Breaking change for dcompute**: The special `@kernel` UDA is now a function and _**requires**_ parentheses as in `@kernel() void foo(){}`. Optionally you can provide launch dimensions, `@kernel([2,4,8])`, to specify to the compute runtime how the kernel is intended to be launched.
66

77
#### Platform support

dmd/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ Note that these groups have no strict meaning, the category assignments are a bi
170170

171171
| File | Purpose |
172172
|-------------------------------------------------------------------------|-------------------------------------------|
173-
| [iasm.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/iasm.d) | Inline assembly depending on the compiler |
174-
| [iasmdmd.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/iasmdmd.d) | Inline assembly for DMD |
175-
| [iasmgcc.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/iasmgcc.d) | Inline assembly for GDC |
173+
| [iasm/package.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/iasm/package.d) | Inline assembly depending on the compiler |
174+
| [iasm/dmdx86.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/iasm/dmd.d) | Inline assembly for DMD X86_64 |
175+
| [iasm/dmdaarch64.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/iasm/aarch64.d) | Inline assembly for DMD AArch64 |
176+
| [iasm/gcc.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/iasm/gcc.d) | Inline assembly for GDC |
176177

177178
**Other**
178179

dmd/aggregate.d

Lines changed: 1 addition & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import dmd.declaration;
2525
import dmd.dscope;
2626
import dmd.dstruct;
2727
import dmd.dsymbol;
28-
import dmd.dsymbolsem : dsymbolSemantic, determineFields, search, determineSize, include;
28+
import dmd.dsymbolsem : dsymbolSemantic, determineSize, include;
2929
import dmd.dtemplate;
3030
import dmd.errors;
3131
import dmd.expression;
@@ -37,7 +37,6 @@ import dmd.identifier;
3737
import dmd.location;
3838
import dmd.mtype;
3939
import dmd.tokens;
40-
import dmd.typesem : defaultInit, addMod, size;
4140
import dmd.visitor;
4241

4342
/**
@@ -195,86 +194,6 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
195194
return ok ? structsize : SIZE_INVALID;
196195
}
197196

198-
/***************************************
199-
* Calculate field[i].overlapped and overlapUnsafe, and check that all of explicit
200-
* field initializers have unique memory space on instance.
201-
* Returns:
202-
* true if any errors happen.
203-
*/
204-
extern (D) final bool checkOverlappedFields()
205-
{
206-
//printf("AggregateDeclaration::checkOverlappedFields() %s\n", toChars());
207-
assert(sizeok == Sizeok.done);
208-
size_t nfields = fields.length;
209-
if (isNested())
210-
{
211-
auto cd = isClassDeclaration();
212-
if (!cd || !cd.baseClass || !cd.baseClass.isNested())
213-
nfields--;
214-
if (vthis2 && !(cd && cd.baseClass && cd.baseClass.vthis2))
215-
nfields--;
216-
}
217-
bool errors = false;
218-
219-
// Fill in missing any elements with default initializers
220-
foreach (i; 0 .. nfields)
221-
{
222-
auto vd = fields[i];
223-
if (vd.errors)
224-
{
225-
errors = true;
226-
continue;
227-
}
228-
229-
const vdIsVoidInit = vd._init && vd._init.isVoidInitializer();
230-
231-
// Find overlapped fields with the hole [vd.offset .. vd.offset.size()].
232-
foreach (j; 0 .. nfields)
233-
{
234-
if (i == j)
235-
continue;
236-
auto v2 = fields[j];
237-
if (v2.errors)
238-
{
239-
errors = true;
240-
continue;
241-
}
242-
if (!vd.isOverlappedWith(v2))
243-
continue;
244-
245-
// vd and v2 are overlapping.
246-
vd.overlapped = true;
247-
v2.overlapped = true;
248-
249-
if (!MODimplicitConv(vd.type.mod, v2.type.mod))
250-
v2.overlapUnsafe = true;
251-
if (!MODimplicitConv(v2.type.mod, vd.type.mod))
252-
vd.overlapUnsafe = true;
253-
254-
if (i > j)
255-
continue;
256-
257-
if (!v2._init)
258-
continue;
259-
260-
if (v2._init.isVoidInitializer())
261-
continue;
262-
263-
if (vd._init && !vdIsVoidInit && v2._init)
264-
{
265-
.error(loc, "overlapping default initialization for field `%s` and `%s`", v2.toChars(), vd.toChars());
266-
errors = true;
267-
}
268-
else if (v2._init && i < j)
269-
{
270-
.error(v2.loc, "union field `%s` with default initialization `%s` must be before field `%s`",
271-
v2.toChars(), dmd.hdrgen.toChars(v2._init), vd.toChars());
272-
errors = true;
273-
}
274-
}
275-
}
276-
return errors;
277-
}
278197

279198
override final Type getType()
280199
{
@@ -433,46 +352,6 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
433352
return visibility.kind == Visibility.Kind.export_;
434353
}
435354

436-
/*******************************************
437-
* Look for constructor declaration.
438-
*/
439-
extern (D) final Dsymbol searchCtor()
440-
{
441-
auto s = this.search(Loc.initial, Id.ctor);
442-
if (s)
443-
{
444-
if (!(s.isCtorDeclaration() ||
445-
s.isTemplateDeclaration() ||
446-
s.isOverloadSet()))
447-
{
448-
error(s.loc, "%s name `__ctor` is not allowed", s.kind);
449-
errorSupplemental(s.loc, "identifiers starting with `__` are reserved for internal use");
450-
errors = true;
451-
s = null;
452-
}
453-
}
454-
if (s && s.toParent() != this)
455-
s = null; // search() looks through ancestor classes
456-
if (s)
457-
{
458-
// Finish all constructors semantics to determine this.noDefaultCtor.
459-
static int searchCtor(Dsymbol s, void*)
460-
{
461-
auto f = s.isCtorDeclaration();
462-
if (f && f.semanticRun == PASS.initial)
463-
f.dsymbolSemantic(null);
464-
return 0;
465-
}
466-
467-
for (size_t i = 0; i < members.length; i++)
468-
{
469-
auto sm = (*members)[i];
470-
sm.apply(&searchCtor, null);
471-
}
472-
}
473-
return s;
474-
}
475-
476355
override final Visibility visible() pure nothrow @nogc @safe
477356
{
478357
return visibility;

dmd/astenums.d

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ enum Sizeok : ubyte
1919
}
2020

2121
/// D Language version
22-
enum Edition : ubyte
22+
enum Edition : ushort
2323
{
24-
none,
25-
legacy, /// Before the introduction of editions
26-
v2024, /// Experimental first new edition
27-
latest = v2024 /// Newest edition that this compiler knows of
24+
v2023 = 2023, /// Edition.min for default edition
25+
v2024, /// first Edition
26+
v2025, /// next Edition
27+
/// use Edition.max for latest edition
2828
}
2929

3030
enum Baseok : ubyte
@@ -77,9 +77,10 @@ enum STC : ulong // transfer changes to declaration.h
7777
ref_ = 0x4_0000, /// `ref`
7878
scope_ = 0x8_0000, /// `scope`
7979

80-
scopeinferred = 0x20_0000, /// `scope` has been inferred and should not be part of mangling, `scope_` must also be set
81-
return_ = 0x40_0000, /// 'return ref' or 'return scope' for function parameters
82-
returnScope = 0x80_0000, /// if `ref return scope` then resolve to `ref` and `return scope`
80+
scopeinferred = 0x10_0000, /// `scope` has been inferred and should not be part of mangling, `scope_` must also be set
81+
return_ = 0x20_0000, /// 'return ref' or 'return scope' for function parameters
82+
returnScope = 0x40_0000, /// if `ref return scope` then resolve to `ref` and `return scope`
83+
returnRef = 0x80_0000, /// if `return ref`
8384

8485
returninferred = 0x100_0000, /// `return` has been inferred and should not be part of mangling, `return_` must also be set
8586
immutable_ = 0x200_0000, /// `immutable`

dmd/attrib.d

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import dmd.declaration;
3232
import dmd.dmodule;
3333
import dmd.dscope;
3434
import dmd.dsymbol;
35-
import dmd.dsymbolsem : include;
3635
import dmd.expression;
3736
import dmd.func;
3837
import dmd.globals;

dmd/cli.d

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,14 +343,19 @@ dmd -cov -unittest myprog.d
343343
(only imports).`,
344344
),
345345
Option("dllimport=<value>",
346-
"Windows only: select symbols to dllimport (none/defaultLibsOnly/all)",
347-
`Which global variables to dllimport implicitly if not defined in a root module
346+
"Windows only: select symbols to dllimport (none/defaultLibsOnly/externalOnly/all)",
347+
`Which symbols to dllimport implicitly if not defined in a module that is being compiled
348348
$(UL
349349
$(LI $(I none): None)
350-
$(LI $(I defaultLibsOnly): Only druntime/Phobos symbols)
350+
$(LI $(I defaultLibsOnly): Only druntime/Phobos symbols and any from a module that is marked as external to binary)
351+
$(LI $(I externalOnly): Only symbols found from a module that is marked as external to binary)
351352
$(LI $(I all): All)
352353
)`,
353354
),
355+
Option("edition[=<NNNN>G[<filename>]]",
356+
"set language edition to edition year, apply to <filename>",
357+
"set edition to default, to a particular year NNNN, apply only to a particular $(I filename)"
358+
),
354359
Option("extern-std=<standard>",
355360
"set C++ name mangling compatibility with <standard>",
356361
"Standards supported are:
@@ -468,6 +473,9 @@ dmd -cov -unittest myprog.d
468473
Option("I=<directory>",
469474
"look for imports also in directory"
470475
),
476+
Option("extI=<directory>",
477+
"look for imports that are out of the currently compiling binary, used to set the module as DllImport"
478+
),
471479
Option("i[=<pattern>]",
472480
"include imported modules in the compilation",
473481
q"{$(P Enables "include imports" mode, where the compiler will include imported

dmd/common/bitfields.d

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@
1010
*/
1111
module dmd.common.bitfields;
1212

13+
//version = Has_Bitfields; // does not work (yet) because hashOf doesn't work on bitfields
14+
version(Has_Bitfields)
15+
version = Debugger_friendly; // without Has_Bitfields, this uses more space by using S
16+
1317
/**
1418
* Generate code for bit fields inside a struct/class body
1519
* Params:
1620
* S = type of a struct with only boolean fields, which should become bit fields
1721
* T = type of bit fields variable, must have enough bits to store all booleans
1822
* Returns: D code with a bit fields variable and getter / setter functions
1923
*/
20-
extern (D) string generateBitFields(S, T)()
24+
extern (D) string generateBitFields(S, T, int ID = __LINE__)()
2125
if (__traits(isUnsigned, T))
2226
{
2327
import core.bitop: bsr;
@@ -55,22 +59,57 @@ if (__traits(isUnsigned, T))
5559
static assert(bitInfo.totalSize <= T.sizeof * 8,
5660
"sum of bit field size "~toString!(bitInfo.totalSize)~" exceeds storage type `"~T.stringof~"`");
5761

62+
version(Debugger_friendly)
63+
{
64+
// unique name needed to allow same name as in base class using `alias`, but without overloading
65+
string bitfieldsName = "bitfields" ~ toString!(ID);
66+
string bitfieldsRead = T.stringof~" "~bitfieldsName~"() const pure { return 0";
67+
string bitfieldsWrite = "void "~bitfieldsName~"("~T.stringof~" v) {\n";
68+
}
69+
5870
foreach (size_t i, mem; __traits(allMembers, S))
5971
{
6072
enum typeName = typeof(__traits(getMember, S, mem)).stringof;
6173
enum shift = toString!(bitInfo.offset[i]);
6274
enum sizeMask = toString!((1 << bitInfo.size[i]) - 1); // 0x01 for bool, 0xFF for ubyte etc.
63-
result ~= "
64-
"~typeName~" "~mem~"() const scope { return cast("~typeName~") ((bitFields >>> "~shift~") & "~sizeMask~"); }
65-
"~typeName~" "~mem~"("~typeName~" v) scope
75+
version(Debugger_friendly)
76+
{
77+
string memacc = mem;
78+
bitfieldsRead ~= "\n| (cast("~T.stringof~")("~memacc~" & "~sizeMask~") << "~shift~")";
79+
bitfieldsWrite ~= memacc~" = cast("~typeName~")((v >> "~shift~") & "~sizeMask~");\n";
80+
result ~= typeName~" "~mem;
81+
version(Has_Bitfields)
82+
result ~= " : "~toString!(bitInfo.size[i]);
83+
enum meminit = __traits(getMember, S.init, mem);
84+
result ~= " = "~meminit.stringof~";\n";
85+
}
86+
else
6687
{
67-
bitFields &= ~("~sizeMask~" << "~shift~");
68-
bitFields |= v << "~shift~";
69-
return v;
70-
}";
88+
result ~= "
89+
"~typeName~" "~mem~"() const scope { return cast("~typeName~") ((bitFields >>> "~shift~") & "~sizeMask~"); }
90+
"~typeName~" "~mem~"("~typeName~" v) scope
91+
{
92+
bitFields &= ~("~sizeMask~" << "~shift~");
93+
bitFields |= v << "~shift~";
94+
return v;
95+
}";
96+
}
97+
}
98+
version(Debugger_friendly)
99+
{
100+
bitfieldsRead ~= ";\n}\n";
101+
bitfieldsWrite ~= "}\n";
102+
result ~= "alias bitFields = "~bitfieldsName~";\n";
103+
result ~= bitfieldsRead ~ bitfieldsWrite;
104+
result ~= "\n}\n";
105+
return result;
106+
}
107+
else
108+
{
109+
result ~= "\n}\n";
110+
enum TP initVal = bitInfo.initialValue;
111+
return result ~ " private "~T.stringof~" bitFields = " ~ toString!(initVal) ~ ";\n";
71112
}
72-
enum TP initVal = bitInfo.initialValue;
73-
return result ~ "\n}\n private "~T.stringof~" bitFields = " ~ toString!(initVal) ~ ";\n";
74113
}
75114

76115
///

0 commit comments

Comments
 (0)