aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-12-07 11:55:12 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2023-12-11 11:06:23 +0100
commitf9b4dbb8ac75f96c4897ba9aafcaf0bbad4fbe44 (patch)
tree0cbb768778c3ece2ccdae2f1e34aceb483917c1d /gcc
parent63194a0e8ede9e15dfa01c6ec7aeea8f7702d3b7 (diff)
downloadgcc-f9b4dbb8ac75f96c4897ba9aafcaf0bbad4fbe44.zip
gcc-f9b4dbb8ac75f96c4897ba9aafcaf0bbad4fbe44.tar.gz
gcc-f9b4dbb8ac75f96c4897ba9aafcaf0bbad4fbe44.tar.bz2
d: Merge upstream dmd, druntime 2bbf64907c, phobos b64bfbf91
D front-end changes: - Import dmd v2.106.0. D runtime changes: - Import druntime v2.106.0. Phobos changes: - Import phobos v2.106.0. gcc/d/ChangeLog: * Make-lang.in (D_FRONTEND_OBJS): Rename d/common-string.o to d/common-smallbuffer.o. * dmd/MERGE: Merge upstream dmd 2bbf64907c. * dmd/VERSION: Bump version to v2.106.0. * modules.cc (layout_moduleinfo_fields): Update for new front-end interface. (layout_moduleinfo): Likewise. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 2bbf64907c. * src/MERGE: Merge upstream phobos b64bfbf91.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/d/Make-lang.in2
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/aggregate.d10
-rw-r--r--gcc/d/dmd/aggregate.h1
-rw-r--r--gcc/d/dmd/attrib.d67
-rw-r--r--gcc/d/dmd/attrib.h9
-rw-r--r--gcc/d/dmd/canthrow.d2
-rw-r--r--gcc/d/dmd/common/README.md2
-rw-r--r--gcc/d/dmd/common/file.d15
-rw-r--r--gcc/d/dmd/common/smallbuffer.d (renamed from gcc/d/dmd/common/string.d)49
-rw-r--r--gcc/d/dmd/cparse.d8
-rw-r--r--gcc/d/dmd/dcast.d12
-rw-r--r--gcc/d/dmd/denum.d7
-rw-r--r--gcc/d/dmd/dimport.d16
-rw-r--r--gcc/d/dmd/dmodule.d36
-rw-r--r--gcc/d/dmd/dsymbol.d172
-rw-r--r--gcc/d/dmd/dsymbol.h5
-rw-r--r--gcc/d/dmd/dsymbolsem.d214
-rw-r--r--gcc/d/dmd/dtemplate.d7
-rw-r--r--gcc/d/dmd/enum.h1
-rw-r--r--gcc/d/dmd/escape.d2
-rw-r--r--gcc/d/dmd/expressionsem.d2
-rw-r--r--gcc/d/dmd/hdrgen.d27
-rw-r--r--gcc/d/dmd/import.h1
-rw-r--r--gcc/d/dmd/initsem.d20
-rw-r--r--gcc/d/dmd/module.h1
-rw-r--r--gcc/d/dmd/nspace.d14
-rw-r--r--gcc/d/dmd/nspace.h1
-rw-r--r--gcc/d/dmd/parse.d12
-rw-r--r--gcc/d/dmd/root/file.d2
-rw-r--r--gcc/d/dmd/root/filename.d4
-rw-r--r--gcc/d/dmd/root/speller.d2
-rw-r--r--gcc/d/dmd/root/string.d2
-rw-r--r--gcc/d/dmd/typesem.d58
-rw-r--r--gcc/d/modules.cc4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/dbitfields.d34
38 files changed, 453 insertions, 374 deletions
diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in
index b3007a9..a0d4d7c 100644
--- a/gcc/d/Make-lang.in
+++ b/gcc/d/Make-lang.in
@@ -95,7 +95,7 @@ D_FRONTEND_OBJS = \
d/common-bitfields.o \
d/common-file.o \
d/common-outbuffer.o \
- d/common-string.o \
+ d/common-smallbuffer.o \
d/compiler.o \
d/cond.o \
d/constfold.o \
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index aa0062c..5edcee1 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-ff57fec51558013b25cadb7e83da9f4675915d56
+2bbf64907cbbb483d003e0a8fcf8b502e4883799
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 41fdc65..8c95cd0 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.106.0-rc.1
+v2.106.0
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index 307bb01..352ca88 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -178,16 +178,6 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol
return sc2;
}
- override final void setScope(Scope* sc)
- {
- // Might need a scope to resolve forward references. The check for
- // semanticRun prevents unnecessary setting of _scope during deferred
- // setScope phases for aggregates which already finished semantic().
- // See https://issues.dlang.org/show_bug.cgi?id=16607
- if (semanticRun < PASS.semanticdone)
- ScopeDsymbol.setScope(sc);
- }
-
/***************************************
* Returns:
* The total number of fields minus the number of hidden fields.
diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h
index cd8f1a1..98fa6bd 100644
--- a/gcc/d/dmd/aggregate.h
+++ b/gcc/d/dmd/aggregate.h
@@ -113,7 +113,6 @@ public:
Sizeok sizeok; // set when structsize contains valid data
virtual Scope *newScope(Scope *sc);
- void setScope(Scope *sc) override final;
virtual void finalizeSize() = 0;
uinteger_t size(const Loc &loc) override final;
bool fill(const Loc &loc, Expressions &elements, bool ctorinit);
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 251e2e8..faf0489 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -123,19 +123,6 @@ extern (C++) abstract class AttribDeclaration : Dsymbol
return sc;
}
- override void setScope(Scope* sc)
- {
- Dsymbols* d = include(sc);
- //printf("\tAttribDeclaration::setScope '%s', d = %p\n",toChars(), d);
- if (d)
- {
- Scope* sc2 = newScope(sc);
- d.foreachDsymbol( s => s.setScope(sc2) );
- if (sc2 != sc)
- sc2.pop();
- }
- }
-
override void importAll(Scope* sc)
{
Dsymbols* d = include(sc);
@@ -338,14 +325,6 @@ extern (C++) final class DeprecatedDeclaration : StorageClassDeclaration
return scx;
}
- override void setScope(Scope* sc)
- {
- //printf("DeprecatedDeclaration::setScope() %p\n", this);
- if (decl)
- Dsymbol.setScope(sc); // for forward reference
- return AttribDeclaration.setScope(sc);
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -433,13 +412,6 @@ extern (C++) final class CPPMangleDeclaration : AttribDeclaration
sc.aligndecl, sc.inlining);
}
- override void setScope(Scope* sc)
- {
- if (decl)
- Dsymbol.setScope(sc); // for forward reference
- return AttribDeclaration.setScope(sc);
- }
-
override const(char)* toChars() const
{
return toString().ptr;
@@ -703,13 +675,6 @@ extern (C++) final class AnonDeclaration : AttribDeclaration
return new AnonDeclaration(loc, isunion, Dsymbol.arraySyntaxCopy(decl));
}
- override void setScope(Scope* sc)
- {
- if (decl)
- Dsymbol.setScope(sc);
- return AttribDeclaration.setScope(sc);
- }
-
override void setFieldOffset(AggregateDeclaration ad, ref FieldState fieldState, bool isunion)
{
//printf("\tAnonDeclaration::setFieldOffset %s %p\n", isunion ? "union" : "struct", this);
@@ -913,11 +878,6 @@ extern (C++) class ConditionalDeclaration : AttribDeclaration
}
}
- override void setScope(Scope* sc)
- {
- include(sc).foreachDsymbol( s => s.setScope(sc) );
- }
-
override void accept(Visitor v)
{
v.visit(this);
@@ -983,13 +943,6 @@ extern (C++) final class StaticIfDeclaration : ConditionalDeclaration
}
}
- override void setScope(Scope* sc)
- {
- // do not evaluate condition before semantic pass
- // But do set the scope, in case we need it for forward referencing
- Dsymbol.setScope(sc);
- }
-
override void importAll(Scope* sc)
{
// do not evaluate condition before semantic pass
@@ -1104,13 +1057,6 @@ extern (C++) final class StaticForeachDeclaration : AttribDeclaration
// change this to give semantics to documentation comments on static foreach declarations
}
- override void setScope(Scope* sc)
- {
- // do not evaluate condition before semantic pass
- // But do set the scope, in case we need it for forward referencing
- Dsymbol.setScope(sc);
- }
-
override void importAll(Scope* sc)
{
// do not evaluate aggregate before semantic pass
@@ -1209,11 +1155,6 @@ extern (C++) final class MixinDeclaration : AttribDeclaration
return new MixinDeclaration(loc, Expression.arraySyntaxCopy(exps));
}
- override void setScope(Scope* sc)
- {
- Dsymbol.setScope(sc);
- }
-
override const(char)* kind() const
{
return "mixin";
@@ -1264,14 +1205,6 @@ extern (C++) final class UserAttributeDeclaration : AttribDeclaration
return sc2;
}
- override void setScope(Scope* sc)
- {
- //printf("UserAttributeDeclaration::setScope() %p\n", this);
- if (decl)
- Dsymbol.setScope(sc); // for forward reference of UDAs
- return AttribDeclaration.setScope(sc);
- }
-
extern (D) static Expressions* concat(Expressions* udas1, Expressions* udas2)
{
Expressions* udas;
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index efea9af..98c5e52 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -26,7 +26,6 @@ public:
virtual Dsymbols *include(Scope *sc);
virtual Scope *newScope(Scope *sc);
- void setScope(Scope *sc) override;
void importAll(Scope *sc) override;
void addComment(const utf8_t *comment) override;
const char *kind() const override;
@@ -61,7 +60,6 @@ public:
DeprecatedDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
- void setScope(Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -84,7 +82,6 @@ public:
CPPMangleDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
- void setScope(Scope *sc) override;
const char *toChars() const override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -135,7 +132,6 @@ public:
unsigned anonalignsize; // size of anonymous struct for alignment purposes
AnonDeclaration *syntaxCopy(Dsymbol *s) override;
- void setScope(Scope *sc) override;
void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion) override;
const char *kind() const override;
AnonDeclaration *isAnonDeclaration() override { return this; }
@@ -163,7 +159,6 @@ public:
bool oneMember(Dsymbol **ps, Identifier *ident) override final;
Dsymbols *include(Scope *sc) override;
void addComment(const utf8_t *comment) override final;
- void setScope(Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -176,7 +171,6 @@ public:
StaticIfDeclaration *syntaxCopy(Dsymbol *s) override;
Dsymbols *include(Scope *sc) override;
- void setScope(Scope *sc) override;
void importAll(Scope *sc) override;
StaticIfDeclaration *isStaticIfDeclaration() override { return this; }
const char *kind() const override;
@@ -196,7 +190,6 @@ public:
bool oneMember(Dsymbol **ps, Identifier *ident) override;
Dsymbols *include(Scope *sc) override;
void addComment(const utf8_t *comment) override;
- void setScope(Scope *sc) override;
void importAll(Scope *sc) override;
const char *kind() const override;
void accept(Visitor *v) override { v->visit(this); }
@@ -223,7 +216,6 @@ public:
d_bool compiled;
MixinDeclaration *syntaxCopy(Dsymbol *s) override;
- void setScope(Scope *sc) override;
const char *kind() const override;
void accept(Visitor *v) override { v->visit(this); }
};
@@ -239,7 +231,6 @@ public:
UserAttributeDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
- void setScope(Scope *sc) override;
Expressions *getAttributes();
const char *kind() const override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index 6730592..5a608a9 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -22,7 +22,6 @@ import dmd.declaration;
import dmd.dsymbol;
import dmd.errorsink;
import dmd.expression;
-import dmd.expressionsem;
import dmd.func;
import dmd.globals;
import dmd.init;
@@ -81,6 +80,7 @@ CT canThrow(Expression e, FuncDeclaration func, ErrorSink eSink)
if (!f.isDtorDeclaration())
errorSupplementalInferredAttr(f, 10, false, STC.nothrow_);
+ import dmd.expressionsem : checkOverriddenDtor;
f.checkOverriddenDtor(null, e.loc, dd => dd.type.toTypeFunction().isnothrow, "not nothrow");
}
else if (func)
diff --git a/gcc/d/dmd/common/README.md b/gcc/d/dmd/common/README.md
index 853fd4f..ad507c7 100644
--- a/gcc/d/dmd/common/README.md
+++ b/gcc/d/dmd/common/README.md
@@ -5,4 +5,4 @@
| [bitfields.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/common/bitfields.d) | Pack multiple boolean fields into bit fields |
| [file.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/common/file.d) | Functions and objects dedicated to file I/O and management |
| [outbuffer.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/common/outbuffer.d) | An expandable buffer in which you can write text or binary data |
-| [string.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/common/string.d) | Common string functions including filename manipulation |
+| [string.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/common/smallbuffer.d) | Common string functions including filename manipulation |
diff --git a/gcc/d/dmd/common/file.d b/gcc/d/dmd/common/file.d
index 076f357..704110f 100644
--- a/gcc/d/dmd/common/file.d
+++ b/gcc/d/dmd/common/file.d
@@ -17,13 +17,13 @@ module dmd.common.file;
import core.stdc.errno : errno;
import core.stdc.stdio : fprintf, remove, rename, stderr;
import core.stdc.stdlib : exit;
-import core.stdc.string : strerror;
+import core.stdc.string : strerror, strlen;
import core.sys.windows.winbase;
import core.sys.windows.winnt;
import core.sys.posix.fcntl;
import core.sys.posix.unistd;
-import dmd.common.string;
+import dmd.common.smallbuffer;
nothrow:
@@ -129,7 +129,8 @@ struct FileMapping(Datum)
enum openFlags = CREATE_ALWAYS;
}
- handle = filename.asDString.extendedPathThen!(p => CreateFileW(p.ptr, createFileMode, 0, null, openFlags, FILE_ATTRIBUTE_NORMAL, null));
+ handle = filename[0 .. strlen(filename)].
+ extendedPathThen!(p => CreateFileW(p.ptr, createFileMode, 0, null, openFlags, FILE_ATTRIBUTE_NORMAL, null));
if (handle == invalidHandle)
{
static if (is(Datum == const))
@@ -312,7 +313,7 @@ struct FileMapping(Datum)
else version(Windows)
{
import core.sys.windows.winbase;
- if (deleteme.asDString.extendedPathThen!(p => DeleteFileW(p.ptr)) == 0)
+ if (deleteme[0 .. strlen(deleteme)].extendedPathThen!(p => DeleteFileW(p.ptr)) == 0)
{
fprintf(stderr, "DeleteFileW error %d\n", GetLastError());
return false;
@@ -447,8 +448,8 @@ struct FileMapping(Datum)
else version(Windows)
{
import core.sys.windows.winbase;
- auto r = oldname.asDString.extendedPathThen!(
- p1 => filename.asDString.extendedPathThen!(p2 => MoveFileExW(p1.ptr, p2.ptr, MOVEFILE_REPLACE_EXISTING))
+ auto r = oldname[0 .. strlen(oldname)].extendedPathThen!(
+ p1 => filename[0 .. strlen(filename)].extendedPathThen!(p2 => MoveFileExW(p1.ptr, p2.ptr, MOVEFILE_REPLACE_EXISTING))
);
if (r == 0)
{
@@ -483,7 +484,7 @@ extern(D) static bool writeFile(const(char)* name, const void[] data) nothrow
else version (Windows)
{
DWORD numwritten; // here because of the gotos
- const nameStr = name.asDString;
+ const nameStr = name[0 .. strlen(name)];
// work around Windows file path length limitation
// (see documentation for extendedPathThen).
HANDLE h = nameStr.extendedPathThen!
diff --git a/gcc/d/dmd/common/string.d b/gcc/d/dmd/common/smallbuffer.d
index 9453a34..ec0eaae 100644
--- a/gcc/d/dmd/common/string.d
+++ b/gcc/d/dmd/common/smallbuffer.d
@@ -4,11 +4,11 @@
* Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
* Authors: Walter Bright, https://www.digitalmars.com
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
- * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/string.d, common/_string.d)
- * Documentation: https://dlang.org/phobos/dmd_common_string.html
- * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/common/string.d
+ * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/smallbuffer.d, common/_smallbuffer.d)
+ * Documentation: https://dlang.org/phobos/dmd_common_smallbuffer.html
+ * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/common/smallbuffer
*/
-module dmd.common.string;
+module dmd.common.smallbuffer;
nothrow:
@@ -107,33 +107,11 @@ unittest
}
/**
-Converts a zero-terminated C string to a D slice. Takes linear time and allocates no memory.
-
-Params:
-stringz = the C string to be converted
-
-Returns:
-a slice comprehending the string. The terminating 0 is not part of the slice.
-*/
-auto asDString(C)(C* stringz) pure @nogc nothrow
-{
- import core.stdc.string : strlen;
- return stringz[0 .. strlen(stringz)];
-}
-
-///
-unittest
-{
- const char* p = "123".ptr;
- assert(p.asDString == "123");
-}
-
-/**
(Windows only) Converts a narrow string to a wide string using `buffer` as strorage. Returns a slice managed by
`buffer` containing the converted string. The terminating zero is not part of the returned slice,
but is guaranteed to follow it.
*/
-version(Windows) wchar[] toWStringz(const(char)[] narrow, ref SmallBuffer!wchar buffer) nothrow
+version(Windows) wchar[] toWStringz(scope const(char)[] narrow, ref SmallBuffer!wchar buffer) nothrow
{
import core.sys.windows.winnls : MultiByteToWideChar;
import dmd.common.file : CodePage;
@@ -141,16 +119,17 @@ version(Windows) wchar[] toWStringz(const(char)[] narrow, ref SmallBuffer!wchar
if (narrow is null)
return null;
- const requiredLength = MultiByteToWideChar(CodePage, 0, narrow.ptr, cast(int) narrow.length, buffer.ptr, cast(int) buffer.length);
- if (requiredLength < cast(int) buffer.length)
+ size_t length;
+ int i;
+ while (1)
{
- buffer[requiredLength] = 0;
- return buffer[0 .. requiredLength];
+ // https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
+ length = MultiByteToWideChar(CodePage, 0, narrow.ptr, cast(int) narrow.length, buffer.ptr, cast(int) buffer.length);
+ if (length < buffer.length)
+ break;
+ buffer.create(length + 1);
+ assert(++i == 1); // ensure loop should only execute once or twice
}
-
- buffer.create(requiredLength + 1);
- const length = MultiByteToWideChar(CodePage, 0, narrow.ptr, cast(int) narrow.length, buffer.ptr, requiredLength);
- assert(length == requiredLength);
buffer[length] = 0;
return buffer[0 .. length];
}
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index ed5f1f8..89a5948 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -1890,6 +1890,14 @@ final class CParser(AST) : Parser!AST
if (specifier.alignExps)
error("no alignment-specifier for typedef declaration"); // C11 6.7.5-2
+ if (specifier.vector_size)
+ {
+ auto length = new AST.IntegerExp(token.loc, specifier.vector_size / dt.size(), AST.Type.tuns32);
+ auto tsa = new AST.TypeSArray(dt, length);
+ dt = new AST.TypeVector(tsa);
+ specifier.vector_size = 0; // used it up
+ }
+
bool isalias = true;
if (auto ts = dt.isTypeStruct())
{
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 14c67f0..bb86b08 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -68,7 +68,6 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
Expression visit(Expression e)
{
// printf("Expression.implicitCastTo(%s of type %s) => %s\n", e.toChars(), e.type.toChars(), t.toChars());
-
if (const match = (sc && sc.flags & SCOPE.Cfile) ? e.cimplicitConvTo(t) : e.implicitConvTo(t))
{
// no need for an extra cast when matching is exact
@@ -802,8 +801,8 @@ extern(C++) MATCH implicitConvTo(Expression e, Type t)
return result;
}
- else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray))
- {
+ else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray || typeb.ty == Tpointer))
+ { // Tpointer because ImportC eagerly converts Tsarray to Tpointer
result = MATCH.exact;
// Convert array literal to vector type
TypeVector tv = tb.isTypeVector();
@@ -1487,6 +1486,10 @@ MATCH cimplicitConvTo(Expression e, Type t)
if (tb.equals(typeb))
return MATCH.exact;
+
+ if (tb.isTypeVector() || typeb.isTypeVector())
+ return implicitConvTo(e, t); // permissive checking doesn't apply to vectors
+
if ((typeb.isintegral() || typeb.isfloating()) &&
(tb.isintegral() || tb.isfloating()))
return MATCH.convert;
@@ -2298,9 +2301,10 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
ae.type = tp;
}
}
- else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray))
+ else if (tb.ty == Tvector && (typeb.ty == Tarray || typeb.ty == Tsarray || typeb.ty == Tpointer))
{
// Convert array literal to vector type
+ // The Tpointer case comes from C eagerly converting Tsarray to Tpointer
TypeVector tv = tb.isTypeVector();
TypeSArray tbase = tv.basetype.isTypeSArray();
assert(tbase.ty == Tsarray);
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index 797f6ee..5713be1 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -83,13 +83,6 @@ extern (C++) final class EnumDeclaration : ScopeDsymbol
return ed;
}
- override void setScope(Scope* sc)
- {
- if (semanticRun > PASS.initial)
- return;
- ScopeDsymbol.setScope(sc);
- }
-
override bool oneMember(Dsymbol* ps, Identifier ident)
{
if (isAnonymous())
diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d
index 0132e49..5c01a9f 100644
--- a/gcc/d/dmd/dimport.d
+++ b/gcc/d/dmd/dimport.d
@@ -305,22 +305,6 @@ extern (C++) final class Import : Dsymbol
return this;
}
- override void setScope(Scope* sc)
- {
- Dsymbol.setScope(sc);
- if (aliasdecls.length)
- {
- if (!mod)
- importAll(sc);
-
- sc = sc.push(mod);
- sc.visibility = visibility;
- foreach (ad; aliasdecls)
- ad.setScope(sc);
- sc = sc.pop();
- }
- }
-
override bool overloadInsert(Dsymbol s)
{
/* Allow multiple imports with the same package base, but disallow
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index 5f5de63..d096e43 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -33,6 +33,7 @@ import dmd.errorsink;
import dmd.expression;
import dmd.expressionsem;
import dmd.file_manager;
+import dmd.func;
import dmd.globals;
import dmd.id;
import dmd.identifier;
@@ -969,7 +970,7 @@ extern (C++) final class Module : Package
* If this works out well, it can be extended to all modules
* before any semantic() on any of them.
*/
- setScope(sc); // remember module scope for semantic
+ this.setScope(sc); // remember module scope for semantic
for (size_t i = 0; i < members.length; i++)
{
Dsymbol s = (*members)[i];
@@ -1576,3 +1577,36 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod)
return buf;
}
+
+/*******************************************
+ * Look for member of the form:
+ * const(MemberInfo)[] getMembers(string);
+ * Returns NULL if not found
+ */
+extern(C++) FuncDeclaration findGetMembers(ScopeDsymbol dsym)
+{
+ import dmd.opover : search_function;
+ Dsymbol s = search_function(dsym, Id.getmembers);
+ FuncDeclaration fdx = s ? s.isFuncDeclaration() : null;
+ version (none)
+ {
+ // Finish
+ __gshared TypeFunction tfgetmembers;
+ if (!tfgetmembers)
+ {
+ Scope sc;
+ sc.eSink = global.errorSink;
+ auto parameters = new Parameters();
+ Parameters* p = new Parameter(STC.in_, Type.tchar.constOf().arrayOf(), null, null);
+ parameters.push(p);
+ Type tret = null;
+ TypeFunction tf = new TypeFunction(parameters, tret, VarArg.none, LINK.d);
+ tfgetmembers = tf.dsymbolSemantic(Loc.initial, &sc).isTypeFunction();
+ }
+ if (fdx)
+ fdx = fdx.overloadExactMatch(tfgetmembers);
+ }
+ if (fdx && fdx.isVirtual())
+ fdx = null;
+ return fdx;
+}
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index a52745f..8f5a292 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -31,7 +31,6 @@ import dmd.dmodule;
import dmd.dversion;
import dmd.dscope;
import dmd.dstruct;
-import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
import dmd.expression;
@@ -44,11 +43,9 @@ import dmd.lexer;
import dmd.location;
import dmd.mtype;
import dmd.nspace;
-import dmd.opover;
import dmd.root.aav;
import dmd.root.rmem;
import dmd.rootobject;
-import dmd.root.speller;
import dmd.root.string;
import dmd.statement;
import dmd.staticassert;
@@ -386,40 +383,6 @@ extern (C++) class Dsymbol : ASTNode
return '`' ~ cstr.toDString() ~ "`\0";
}
- final bool checkDeprecated(const ref Loc loc, Scope* sc)
- {
- if (global.params.useDeprecated == DiagnosticReporting.off)
- return false;
- if (!this.isDeprecated())
- return false;
- // Don't complain if we're inside a deprecated symbol's scope
- if (sc.isDeprecated())
- return false;
- // Don't complain if we're inside a template constraint
- // https://issues.dlang.org/show_bug.cgi?id=21831
- if (sc.flags & SCOPE.constraint)
- return false;
-
- const(char)* message = null;
- for (Dsymbol p = this; p; p = p.parent)
- {
- message = p.depdecl ? p.depdecl.getMessage() : null;
- if (message)
- break;
- }
- if (message)
- deprecation(loc, "%s `%s` is deprecated - %s", kind, toPrettyChars, message);
- else
- deprecation(loc, "%s `%s` is deprecated", kind, toPrettyChars);
-
- if (auto ti = sc.parent ? sc.parent.isInstantiated() : null)
- ti.printInstantiationTrace(Classification.deprecation);
- else if (auto ti = sc.parent ? sc.parent.isTemplateInstance() : null)
- ti.printInstantiationTrace(Classification.deprecation);
-
- return true;
- }
-
/**********************************
* Determine which Module a Dsymbol is in.
*/
@@ -749,113 +712,10 @@ extern (C++) class Dsymbol : ASTNode
return toAlias();
}
- /*************************************
- * Set scope for future semantic analysis so we can
- * deal better with forward references.
- */
- void setScope(Scope* sc)
- {
- //printf("Dsymbol::setScope() %p %s, %p stc = %llx\n", this, toChars(), sc, sc.stc);
- if (!sc.nofree)
- sc.setNoFree(); // may need it even after semantic() finishes
- _scope = sc;
- if (sc.depdecl)
- depdecl = sc.depdecl;
- if (!userAttribDecl)
- userAttribDecl = sc.userAttribDecl;
- }
-
void importAll(Scope* sc)
{
}
- extern (D) final Dsymbol search_correct(Identifier ident)
- {
- /***************************************************
- * Search for symbol with correct spelling.
- */
- extern (D) Dsymbol symbol_search_fp(const(char)[] seed, out int cost)
- {
- /* If not in the lexer's string table, it certainly isn't in the symbol table.
- * Doing this first is a lot faster.
- */
- if (!seed.length)
- return null;
- Identifier id = Identifier.lookup(seed);
- if (!id)
- return null;
- cost = 0; // all the same cost
- Dsymbol s = this;
- Module.clearCache();
- return s.search(Loc.initial, id, IgnoreErrors);
- }
-
- if (global.gag)
- return null; // don't do it for speculative compiles; too time consuming
- // search for exact name first
- if (auto s = this.search(Loc.initial, ident, IgnoreErrors))
- return s;
- return speller!symbol_search_fp(ident.toString());
- }
-
- /***************************************
- * Search for identifier id as a member of `this`.
- * `id` may be a template instance.
- *
- * Params:
- * loc = location to print the error messages
- * sc = the scope where the symbol is located
- * id = the id of the symbol
- * flags = the search flags which can be `SearchLocalsOnly` or `IgnorePrivateImports`
- *
- * Returns:
- * symbol found, NULL if not
- */
- extern (D) final Dsymbol searchX(const ref Loc loc, Scope* sc, RootObject id, int flags)
- {
- //printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars());
- Dsymbol s = toAlias();
- Dsymbol sm;
- if (Declaration d = s.isDeclaration())
- {
- if (d.inuse)
- {
- .error(loc, "circular reference to `%s`", d.toPrettyChars());
- return null;
- }
- }
- switch (id.dyncast())
- {
- case DYNCAST.identifier:
- sm = s.search(loc, cast(Identifier)id, flags);
- break;
- case DYNCAST.dsymbol:
- {
- // It's a template instance
- //printf("\ttemplate instance id\n");
- Dsymbol st = cast(Dsymbol)id;
- TemplateInstance ti = st.isTemplateInstance();
- sm = s.search(loc, ti.name);
- if (!sm)
- return null;
- sm = sm.toAlias();
- TemplateDeclaration td = sm.isTemplateDeclaration();
- if (!td)
- return null; // error but handled later
- ti.tempdecl = td;
- if (!ti.semanticRun)
- ti.dsymbolSemantic(sc);
- sm = ti.toAlias();
- break;
- }
- case DYNCAST.type:
- case DYNCAST.expression:
- default:
- assert(0);
- }
- return sm;
- }
-
bool overloadInsert(Dsymbol s)
{
//printf("Dsymbol::overloadInsert('%s')\n", s.toChars());
@@ -1468,38 +1328,6 @@ public:
return "ScopeDsymbol";
}
- /*******************************************
- * Look for member of the form:
- * const(MemberInfo)[] getMembers(string);
- * Returns NULL if not found
- */
- final FuncDeclaration findGetMembers()
- {
- Dsymbol s = search_function(this, Id.getmembers);
- FuncDeclaration fdx = s ? s.isFuncDeclaration() : null;
- version (none)
- {
- // Finish
- __gshared TypeFunction tfgetmembers;
- if (!tfgetmembers)
- {
- Scope sc;
- sc.eSink = global.errorSink;
- auto parameters = new Parameters();
- Parameters* p = new Parameter(STC.in_, Type.tchar.constOf().arrayOf(), null, null);
- parameters.push(p);
- Type tret = null;
- TypeFunction tf = new TypeFunction(parameters, tret, VarArg.none, LINK.d);
- tfgetmembers = tf.dsymbolSemantic(Loc.initial, &sc).isTypeFunction();
- }
- if (fdx)
- fdx = fdx.overloadExactMatch(tfgetmembers);
- }
- if (fdx && fdx.isVirtual())
- fdx = null;
- return fdx;
- }
-
/********************************
* Insert Dsymbol in table.
* Params:
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index e0c2046..15c9970 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -205,7 +205,6 @@ public:
const char *locToChars();
bool equals(const RootObject * const o) const override;
bool isAnonymous() const;
- bool checkDeprecated(const Loc &loc, Scope *sc);
Module *getModule();
bool isCsymbol();
Module *getAccessModule();
@@ -228,7 +227,6 @@ public:
virtual const char *kind() const;
virtual Dsymbol *toAlias(); // resolve real symbol
virtual Dsymbol *toAlias2();
- virtual void setScope(Scope *sc);
virtual void importAll(Scope *sc);
virtual bool overloadInsert(Dsymbol *s);
virtual uinteger_t size(const Loc &loc);
@@ -342,7 +340,6 @@ public:
bool isforwardRef() override final;
static void multiplyDefined(const Loc &loc, Dsymbol *s1, Dsymbol *s2);
const char *kind() const override;
- FuncDeclaration *findGetMembers();
virtual Dsymbol *symtabInsert(Dsymbol *s);
virtual Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);
bool hasStaticCtorOrDtor() override;
@@ -431,3 +428,5 @@ public:
void addMember(Dsymbol *dsym, Scope *sc, ScopeDsymbol *sds);
Dsymbol *search(Dsymbol *d, const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
+bool checkDeprecated(Dsymbol *d, const Loc &loc, Scope *sc);
+void setScope(Dsymbol *d, Scope *sc);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 430377f..060abfe 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -212,6 +212,39 @@ const(char)* getMessage(DeprecatedDeclaration dd)
return dd.msgstr;
}
+bool checkDeprecated(Dsymbol d, const ref Loc loc, Scope* sc)
+{
+ if (global.params.useDeprecated == DiagnosticReporting.off)
+ return false;
+ if (!d.isDeprecated())
+ return false;
+ // Don't complain if we're inside a deprecated symbol's scope
+ if (sc.isDeprecated())
+ return false;
+ // Don't complain if we're inside a template constraint
+ // https://issues.dlang.org/show_bug.cgi?id=21831
+ if (sc.flags & SCOPE.constraint)
+ return false;
+
+ const(char)* message = null;
+ for (Dsymbol p = d; p; p = p.parent)
+ {
+ message = p.depdecl ? p.depdecl.getMessage() : null;
+ if (message)
+ break;
+ }
+ if (message)
+ deprecation(loc, "%s `%s` is deprecated - %s", d.kind, d.toPrettyChars, message);
+ else
+ deprecation(loc, "%s `%s` is deprecated", d.kind, d.toPrettyChars);
+
+ if (auto ti = sc.parent ? sc.parent.isInstantiated() : null)
+ ti.printInstantiationTrace(Classification.deprecation);
+ else if (auto ti = sc.parent ? sc.parent.isTemplateInstance() : null)
+ ti.printInstantiationTrace(Classification.deprecation);
+
+ return true;
+}
// Returns true if a contract can appear without a function body.
package bool allowsContractWithoutBody(FuncDeclaration funcdecl)
@@ -7811,6 +7844,37 @@ extern(C++) Dsymbol search(Dsymbol d, const ref Loc loc, Identifier ident, int f
return v.result;
}
+Dsymbol search_correct(Dsymbol d, Identifier ident)
+{
+ /***************************************************
+ * Search for symbol with correct spelling.
+ */
+ Dsymbol symbol_search_fp(const(char)[] seed, out int cost)
+ {
+ /* If not in the lexer's string table, it certainly isn't in the symbol table.
+ * Doing this first is a lot faster.
+ */
+ if (!seed.length)
+ return null;
+ Identifier id = Identifier.lookup(seed);
+ if (!id)
+ return null;
+ cost = 0; // all the same cost
+ Dsymbol s = d;
+ Module.clearCache();
+ return s.search(Loc.initial, id, IgnoreErrors);
+ }
+
+ if (global.gag)
+ return null; // don't do it for speculative compiles; too time consuming
+ // search for exact name first
+ if (auto s = d.search(Loc.initial, ident, IgnoreErrors))
+ return s;
+
+ import dmd.root.speller : speller;
+ return speller!symbol_search_fp(ident.toString());
+}
+
private extern(C++) class SearchVisitor : Visitor
{
alias visit = Visitor.visit;
@@ -8407,3 +8471,153 @@ private extern(C++) class SearchVisitor : Visitor
return setResult(s);
}
}
+/*************************************
+ * Set scope for future semantic analysis so we can
+ * deal better with forward references.
+ *
+ * Params:
+ * d = dsymbol for which the scope is set
+ * sc = scope that is used to set the value
+ */
+extern(C++) void setScope(Dsymbol d, Scope* sc)
+{
+ scope setScopeVisitor = new SetScopeVisitor(sc);
+ d.accept(setScopeVisitor);
+}
+
+private extern(C++) class SetScopeVisitor : Visitor
+{
+ alias visit = typeof(super).visit;
+ Scope* sc;
+
+ this(Scope* sc)
+ {
+ this.sc = sc;
+ }
+
+ override void visit(Dsymbol d)
+ {
+ //printf("Dsymbol::setScope() %p %s, %p stc = %llx\n", d, d.toChars(), sc, sc.stc);
+ if (!sc.nofree)
+ sc.setNoFree(); // may need it even after semantic() finishes
+ d._scope = sc;
+ if (sc.depdecl)
+ d.depdecl = sc.depdecl;
+ if (!d.userAttribDecl)
+ d.userAttribDecl = sc.userAttribDecl;
+ }
+
+ override void visit(Import i)
+ {
+ visit(cast(Dsymbol)i);
+ if (i.aliasdecls.length)
+ {
+ if (!i.mod)
+ i.importAll(sc);
+
+ sc = sc.push(i.mod);
+ sc.visibility = i.visibility;
+ foreach (ad; i.aliasdecls)
+ ad.setScope(sc);
+ sc = sc.pop();
+ }
+ }
+
+ override void visit(Nspace ns)
+ {
+ visit(cast(Dsymbol)ns);
+ if (ns.members)
+ {
+ assert(sc);
+ sc = sc.push(ns);
+ sc.linkage = LINK.cpp; // namespaces default to C++ linkage
+ sc.parent = ns;
+ ns.members.foreachDsymbol(s => s.setScope(sc));
+ sc.pop();
+ }
+ }
+
+ override void visit(EnumDeclaration ed)
+ {
+ if (ed.semanticRun > PASS.initial)
+ return;
+ visit(cast(Dsymbol)ed);
+ }
+
+ override void visit(AggregateDeclaration ad)
+ {
+ // Might need a scope to resolve forward references. The check for
+ // semanticRun prevents unnecessary setting of _scope during deferred
+ // setScope phases for aggregates which already finished semantic().
+ // See https://issues.dlang.org/show_bug.cgi?id=16607
+ if (ad.semanticRun < PASS.semanticdone)
+ visit(cast(Dsymbol)ad);
+ }
+
+ override void visit(AttribDeclaration atr)
+ {
+ Dsymbols* d = atr.include(sc);
+ //printf("\tAttribDeclaration::setScope '%s', d = %p\n",toChars(), d);
+ if (d)
+ {
+ Scope* sc2 = atr.newScope(sc);
+ d.foreachDsymbol( s => s.setScope(sc2) );
+ if (sc2 != sc)
+ sc2.pop();
+ }
+ }
+
+ override void visit(DeprecatedDeclaration dd)
+ {
+ //printf("DeprecatedDeclaration::setScope() %p\n", this);
+ if (dd.decl)
+ visit(cast(Dsymbol)dd); // for forward reference
+ visit(cast(AttribDeclaration)dd);
+ }
+
+ override void visit(CPPMangleDeclaration cppmd)
+ {
+ if (cppmd.decl)
+ visit(cast(Dsymbol)cppmd); // for forward reference
+ visit(cast(AttribDeclaration)cppmd);
+ }
+
+ override void visit(AnonDeclaration anond)
+ {
+ if (anond.decl)
+ visit(cast(Dsymbol)anond); // for forward reference
+ visit(cast(AttribDeclaration)anond);
+ }
+
+ override void visit(ConditionalDeclaration condd)
+ {
+ condd.include(sc).foreachDsymbol( s => s.setScope(sc) );
+ }
+
+ override void visit(StaticIfDeclaration sid)
+ {
+ // do not evaluate condition before semantic pass
+ // But do set the scope, in case we need it for forward referencing
+ visit(cast(Dsymbol)sid); // for forward reference
+ }
+
+ override void visit(StaticForeachDeclaration sfd)
+ {
+ // do not evaluate condition before semantic pass
+ // But do set the scope, in case we need it for forward referencing
+ visit(cast(Dsymbol)sfd); // for forward reference
+ }
+
+ override void visit(MixinDeclaration md)
+ {
+ visit(cast(Dsymbol)md);
+ }
+
+ override void visit(UserAttributeDeclaration uad)
+ {
+ //printf("UserAttributeDeclaration::setScope() %p\n", this);
+ if (uad.decl)
+ visit(cast(Dsymbol)uad);
+ visit(cast(AttribDeclaration)uad);
+ }
+}
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 037e0d0..326d663 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -7515,7 +7515,12 @@ extern (C++) class TemplateInstance : ScopeDsymbol
}
//printf("\t-. mi = %s\n", mi.toPrettyChars());
- assert(!memberOf || (!memberOf.isRoot() && mi.isRoot()), "can only re-append from non-root to root module");
+ if (memberOf) // already appended to some module
+ {
+ assert(mi.isRoot(), "can only re-append to a root module");
+ if (memberOf.isRoot())
+ return null; // no need to move to another root module
+ }
Dsymbols* a = mi.members;
a.push(this);
diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h
index e17e8cf..5f91ead 100644
--- a/gcc/d/dmd/enum.h
+++ b/gcc/d/dmd/enum.h
@@ -46,7 +46,6 @@ public:
bool inuse(bool v);
EnumDeclaration *syntaxCopy(Dsymbol *s) override;
- void setScope(Scope *sc) override;
bool oneMember(Dsymbol **ps, Identifier *ident) override;
Type *getType() override;
const char *kind() const override;
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index e25fc84..f928b08 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -2343,7 +2343,7 @@ void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f)
VarDeclaration[10] tmp = void;
size_t dim = (funcdecl.vthis !is null) + (funcdecl.parameters ? funcdecl.parameters.length : 0);
- import dmd.common.string : SmallBuffer;
+ import dmd.common.smallbuffer : SmallBuffer;
auto sb = SmallBuffer!VarDeclaration(dim, tmp[]);
VarDeclaration[] array = sb[];
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index e6b9018..1664bf2 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -4387,7 +4387,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
auto e = initializerToExpression(init, t, (sc.flags & SCOPE.Cfile) != 0);
if (!e)
{
- error(cle.loc, "cannot convert initializer `%s` to expression", init.toChars());
+ error(cle.loc, "cannot convert initializer `%s` to expression", toChars(init));
return setError();
}
result = e;
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index ac2dda3..0944ade 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -1968,6 +1968,10 @@ private void visitVarDecl(VarDeclaration v, bool anywritten, ref OutBuffer buf,
v._init.initializerToBuffer(buf, &hgs);
}
+ const commentIt = hgs.importcHdr && isSpecialCName(v.ident);
+ if (commentIt)
+ buf.writestring("/+");
+
if (anywritten)
{
buf.writestring(", ");
@@ -2000,8 +2004,31 @@ private void visitVarDecl(VarDeclaration v, bool anywritten, ref OutBuffer buf,
buf.writestring(" = ");
vinit(v);
}
+ if (commentIt)
+ buf.writestring("+/");
}
+/*************************************
+ * The names __DATE__, __TIME__,__EOF__, __VENDOR__, __TIMESTAMP__, __VERSION__
+ * are special to the D lexer and cannot be used as D source variable names.
+ * Params:
+ * id = name to check
+ * Returns:
+ * true if special C name
+ */
+private bool isSpecialCName(Identifier id)
+{
+ auto s = id.toString();
+ if (s.length >= 7 && s[0] == '_' && s[1] == '_' &&
+ (id == Id.DATE ||
+ id == Id.TIME ||
+ id == Id.EOFX ||
+ id == Id.VENDOR ||
+ id == Id.TIMESTAMP ||
+ id == Id.VERSIONX))
+ return true;
+ return false;
+}
/*********************************************
* Print expression to buffer.
diff --git a/gcc/d/dmd/import.h b/gcc/d/dmd/import.h
index aeb3621..624cd74 100644
--- a/gcc/d/dmd/import.h
+++ b/gcc/d/dmd/import.h
@@ -43,7 +43,6 @@ public:
Import *syntaxCopy(Dsymbol *s) override; // copy only syntax trees
void importAll(Scope *sc) override;
Dsymbol *toAlias() override;
- void setScope(Scope* sc) override;
bool overloadInsert(Dsymbol *s) override;
Import *isImport() override { return this; }
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index 76c2d89..6d31f95 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -199,7 +199,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
uint length;
const(uint) amax = 0x80000000;
bool errors = false;
- //printf("ArrayInitializer::semantic(%s), ai: %s %p\n", t.toChars(), i.toChars(), i);
+ //printf("ArrayInitializer::semantic(%s), ai: %s\n", t.toChars(), toChars(i));
if (i.sem) // if semantic() already run
{
return i;
@@ -600,7 +600,17 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
Initializer visitC(CInitializer ci)
{
- //printf("CInitializer::semantic() tx: %s t: %s ci: %s\n", (tx ? tx.toChars() : "".ptr), t.toChars(), ci.toChars());
+ //printf("CInitializer::semantic() tx: %s t: %s ci: %s\n", (tx ? tx.toChars() : "".ptr), t.toChars(), toChars(ci));
+ static if (0)
+ if (auto ts = tx.isTypeStruct())
+ {
+ import dmd.common.outbuffer;
+ OutBuffer buf;
+ HdrGenStage hgs;
+ toCBuffer(ts.sym, buf, hgs);
+ printf("%s\n", buf.peekChars());
+ }
+
/* Rewrite CInitializer into ExpInitializer, ArrayInitializer, or StructInitializer
*/
t = t.toBasetype();
@@ -794,6 +804,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
for (size_t index = 0; index < ci.initializerList.length; )
{
CInitializer cprev;
+ size_t indexprev;
L1:
DesigInit di = ci.initializerList[index];
Designators* dlist = di.designatorList;
@@ -827,6 +838,7 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
/* The peeling didn't work, so unpeel it
*/
ci = cprev;
+ index = indexprev;
di = ci.initializerList[index];
goto L2;
}
@@ -837,12 +849,14 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ
{
if (fieldi == nfields)
break;
- if (index == 0 && ci.initializerList.length == 1 && di.initializer.isCInitializer())
+ if (/*index == 0 && ci.initializerList.length == 1 &&*/ di.initializer.isCInitializer())
{
/* Try peeling off this set of { } and see if it works
*/
cprev = ci;
ci = di.initializer.isCInitializer();
+ indexprev = index;
+ index = 0;
goto L1;
}
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 92efc16..cab0b0a 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -169,3 +169,4 @@ struct ModuleDeclaration
};
extern void getLocalClasses(Module* mod, Array<ClassDeclaration* >& aclasses);
+FuncDeclaration *findGetMembers(ScopeDsymbol *dsym);
diff --git a/gcc/d/dmd/nspace.d b/gcc/d/dmd/nspace.d
index a49e0bf..22c6e63 100644
--- a/gcc/d/dmd/nspace.d
+++ b/gcc/d/dmd/nspace.d
@@ -85,20 +85,6 @@ extern (C++) final class Nspace : ScopeDsymbol
return ns;
}
- override void setScope(Scope* sc)
- {
- ScopeDsymbol.setScope(sc);
- if (members)
- {
- assert(sc);
- sc = sc.push(this);
- sc.linkage = LINK.cpp; // namespaces default to C++ linkage
- sc.parent = this;
- members.foreachDsymbol(s => s.setScope(sc));
- sc.pop();
- }
- }
-
override bool hasPointers()
{
//printf("Nspace::hasPointers() %s\n", toChars());
diff --git a/gcc/d/dmd/nspace.h b/gcc/d/dmd/nspace.h
index 7d30402..701cc93 100644
--- a/gcc/d/dmd/nspace.h
+++ b/gcc/d/dmd/nspace.h
@@ -21,7 +21,6 @@ class Nspace final : public ScopeDsymbol
public:
Expression *identExp;
Nspace *syntaxCopy(Dsymbol *s) override;
- void setScope(Scope *sc) override;
bool hasPointers() override;
void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion) override;
const char *kind() const override;
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index f9d174a..b6f30b9 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -8428,7 +8428,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
AST.TemplateParameters* tpl = null;
nextToken();
- if (token.value == TOK.leftParenthesis)
+ if (token.value != TOK.leftParenthesis)
+ {
+ error("expected `(` following `is`, not `%s`", token.toChars());
+ goto Lerr;
+ }
+ else
{
nextToken();
if (token.value == TOK.identifier && peekNext() == TOK.leftParenthesis)
@@ -8476,11 +8481,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else
check(TOK.rightParenthesis);
}
- else
- {
- error("`type identifier : specialization` expected following `is`");
- goto Lerr;
- }
e = new AST.IsExp(loc, targ, ident, tok, tspec, tok2, tpl);
break;
}
diff --git a/gcc/d/dmd/root/file.d b/gcc/d/dmd/root/file.d
index 1fb1056..fdf13d4 100644
--- a/gcc/d/dmd/root/file.d
+++ b/gcc/d/dmd/root/file.d
@@ -24,7 +24,7 @@ import dmd.root.rmem;
import dmd.root.string;
import dmd.common.file;
-import dmd.common.string;
+import dmd.common.smallbuffer;
nothrow:
diff --git a/gcc/d/dmd/root/filename.d b/gcc/d/dmd/root/filename.d
index 631c08c..8f31f21 100644
--- a/gcc/d/dmd/root/filename.d
+++ b/gcc/d/dmd/root/filename.d
@@ -37,7 +37,7 @@ version (Windows)
import core.sys.windows.windef;
import core.sys.windows.winnls;
- import dmd.common.string : extendedPathThen;
+ import dmd.common.smallbuffer : extendedPathThen;
extern (Windows) DWORD GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR*) nothrow @nogc;
extern (Windows) void SetLastError(DWORD) nothrow @nogc;
@@ -1177,7 +1177,7 @@ version(Windows)
*/
private auto toWStringzThen(alias F)(const(char)[] str) nothrow
{
- import dmd.common.string : SmallBuffer, toWStringz;
+ import dmd.common.smallbuffer : SmallBuffer, toWStringz;
if (!str.length) return F(""w.ptr);
diff --git a/gcc/d/dmd/root/speller.d b/gcc/d/dmd/root/speller.d
index b646bdd..7ad08b7 100644
--- a/gcc/d/dmd/root/speller.d
+++ b/gcc/d/dmd/root/speller.d
@@ -42,7 +42,7 @@ private:
import core.stdc.stdlib;
import core.stdc.string;
-import dmd.common.string : SmallBuffer;
+import dmd.common.smallbuffer : SmallBuffer;
enum isSearchFunction(alias fun) = is(searchFunctionType!fun);
alias searchFunctionType(alias fun) = typeof(() {int x; return fun("", x);}());
diff --git a/gcc/d/dmd/root/string.d b/gcc/d/dmd/root/string.d
index 8b204ab..5ee81a9 100644
--- a/gcc/d/dmd/root/string.d
+++ b/gcc/d/dmd/root/string.d
@@ -69,7 +69,7 @@ The return value of `T`
auto toCStringThen(alias dg)(const(char)[] src) nothrow
{
import dmd.root.rmem : mem;
- import dmd.common.string : SmallBuffer;
+ import dmd.common.smallbuffer : SmallBuffer;
const len = src.length + 1;
char[512] small = void;
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index 8795002..2063a95 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -372,6 +372,64 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
pt = t.merge();
}
+/***************************************
+ * Search for identifier id as a member of `this`.
+ * `id` may be a template instance.
+ *
+ * Params:
+ * loc = location to print the error messages
+ * sc = the scope where the symbol is located
+ * id = the id of the symbol
+ * flags = the search flags which can be `SearchLocalsOnly` or `IgnorePrivateImports`
+ *
+ * Returns:
+ * symbol found, NULL if not
+ */
+private Dsymbol searchX(Dsymbol dsym, const ref Loc loc, Scope* sc, RootObject id, int flags)
+{
+ //printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars());
+ Dsymbol s = dsym.toAlias();
+ Dsymbol sm;
+ if (Declaration d = s.isDeclaration())
+ {
+ if (d.inuse)
+ {
+ .error(loc, "circular reference to `%s`", d.toPrettyChars());
+ return null;
+ }
+ }
+ switch (id.dyncast())
+ {
+ case DYNCAST.identifier:
+ sm = s.search(loc, cast(Identifier)id, flags);
+ break;
+ case DYNCAST.dsymbol:
+ {
+ // It's a template instance
+ //printf("\ttemplate instance id\n");
+ Dsymbol st = cast(Dsymbol)id;
+ TemplateInstance ti = st.isTemplateInstance();
+ sm = s.search(loc, ti.name);
+ if (!sm)
+ return null;
+ sm = sm.toAlias();
+ TemplateDeclaration td = sm.isTemplateDeclaration();
+ if (!td)
+ return null; // error but handled later
+ ti.tempdecl = td;
+ if (!ti.semanticRun)
+ ti.dsymbolSemantic(sc);
+ sm = ti.toAlias();
+ break;
+ }
+ case DYNCAST.type:
+ case DYNCAST.expression:
+ default:
+ assert(0);
+ }
+ return sm;
+}
+
/******************************************
* We've mistakenly parsed `t` as a type.
* Redo `t` as an Expression only if there are no type modifiers.
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index e3c1ef9..250743e 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -503,7 +503,7 @@ layout_moduleinfo_fields (Module *decl, tree type)
if (decl->sshareddtor)
layout_moduleinfo_field (ptr_type_node, type, offset);
- if (decl->findGetMembers ())
+ if (findGetMembers (decl))
layout_moduleinfo_field (ptr_type_node, type, offset);
if (decl->sictor)
@@ -571,7 +571,7 @@ layout_moduleinfo (Module *decl)
aimports_dim--;
}
- sgetmembers = decl->findGetMembers ();
+ sgetmembers = findGetMembers (decl);
size_t flags = 0;
if (decl->sctor)
diff --git a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
index 9de436b..a170b77 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
@@ -7,7 +7,7 @@ fail_compilation/misc_parser_err_cov1.d(30): Error: basic type expected, not `)`
fail_compilation/misc_parser_err_cov1.d(31): Error: `__traits(identifier, args...)` expected
fail_compilation/misc_parser_err_cov1.d(31): Error: semicolon expected following auto declaration, not `o`
fail_compilation/misc_parser_err_cov1.d(31): Error: expression expected, not `)`
-fail_compilation/misc_parser_err_cov1.d(32): Error: `type identifier : specialization` expected following `is`
+fail_compilation/misc_parser_err_cov1.d(32): Error: expected `(` following `is`, not `;`
fail_compilation/misc_parser_err_cov1.d(33): Error: semicolon expected following auto declaration, not `auto`
fail_compilation/misc_parser_err_cov1.d(33): Error: found `+` when expecting `(` following `mixin`
fail_compilation/misc_parser_err_cov1.d(35): Error: `key:value` expected for associative array literal
diff --git a/gcc/testsuite/gdc.test/runnable/dbitfields.d b/gcc/testsuite/gdc.test/runnable/dbitfields.d
index 0d1877a..aa154c7 100644
--- a/gcc/testsuite/gdc.test/runnable/dbitfields.d
+++ b/gcc/testsuite/gdc.test/runnable/dbitfields.d
@@ -174,6 +174,39 @@ static assert(test7s() == -1);
static assert(test7s2() == -2);
/******************************************/
+// https://issues.dlang.org/show_bug.cgi?id=24257
+
+struct S24257
+{
+ uint : 15;
+ bool done : 1;
+}
+
+bool advance()
+{
+ S24257 n;
+ n.done = false;
+ n.done = true;
+ return n.done;
+}
+
+bool retard()
+{
+ S24257 n;
+ n.done = true;
+ n.done = false;
+ return n.done;
+}
+
+static assert(advance() == true);
+
+void test24257()
+{
+ assert(advance() == true);
+ assert(retard() == false);
+}
+
+/******************************************/
int main()
{
@@ -184,6 +217,7 @@ int main()
test5();
test6();
test7();
+ test24257();
return 0;
}