aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/ChangeLog75
-rw-r--r--gcc/d/d-compiler.cc37
-rw-r--r--gcc/d/d-lang.cc25
-rw-r--r--gcc/d/d-spec.cc50
-rw-r--r--gcc/d/decl.cc15
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/expressionsem.d6
-rw-r--r--gcc/d/dmd/globals.h1
-rw-r--r--gcc/d/dmd/lexer.d4
-rw-r--r--gcc/d/dmd/location.d23
-rw-r--r--gcc/d/dmd/typesem.d16
-rw-r--r--gcc/d/gdc.texi6
-rw-r--r--gcc/d/imports.cc6
-rw-r--r--gcc/d/lang.opt4
-rw-r--r--gcc/d/lang.opt.urls3
-rw-r--r--gcc/d/types.cc20
16 files changed, 241 insertions, 52 deletions
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 23b8a81..f816c70 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,78 @@
+2025-04-17 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd 956e73d64e.
+
+2025-04-15 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/119826
+ * types.cc (TypeVisitor::visit (TypeEnum *)): Propagate flags of main
+ enum types to all forward-referenced variants.
+
+2025-04-15 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/119799
+ * decl.cc (DeclVisitor::visit (VarDeclaration *)): Check front-end
+ type size before building the VAR_DECL. Allow C symbols to have a
+ size of `0'.
+
+2025-04-15 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/119817
+ * imports.cc (ImportVisitor::visit (OverloadSet *)): Don't push
+ NULL_TREE to vector of import symbols.
+
+2025-04-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/109023
+ * d-compiler.cc: Include dmd/errors.h.
+ (Compiler::onImport): Implement.
+ * d-lang.cc (d_handle_option): Handle -finclude-imports.
+ (d_parse_file): Run semantic on included imports.
+ * gdc.texi: Document -finclude-imports.
+ * lang.opt: Add finclude-imports.
+ * lang.opt.urls: Regenerate.
+
+2025-04-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/119758
+ * d-lang.cc (d_parse_file): Use endswith in test for -fonly= argument.
+ * d-spec.cc (lang_specific_driver): Rework -fonly= and pass all input
+ files to the front-end compiler when the option is seen.
+
+2025-04-11 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ * dmd/MERGE: Merge upstream dmd 1b34fea478.
+
+2025-04-09 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/118309
+ * modules.cc: Include debug.h
+ (d_finish_compilation): Call debug_hooks->type_decl on all TYPE_DECLs.
+ * types.cc: Remove toplev.h include.
+ (finish_aggregate_type): Don't call rest_of_type_compilation or
+ rest_of_decl_compilation on type.
+ (TypeVisitor::visit (TypeEnum *)): Likewise.
+
+2025-04-09 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/117832
+ * d-tree.h (build_padded_constructor): New prototype.
+ * d-codegen.cc (build_padded_constructor): New function.
+ (d_array_value): Call it.
+ (build_memset_call): Likewise.
+ (build_struct_literal): Likewise.
+ (underlying_complex_expr): Likewise.
+ (build_array_from_val): Likewise.
+ (build_array_from_exprs): Likewise.
+ (d_build_call): Likewise.
+ (get_frame_for_symbol): Likewise.
+ * d-convert.cc (convert_for_rvalue): Likewise.
+ (convert_for_assignment): Likewise.
+ * decl.cc (class DeclVisitor): Likewise.
+ * expr.cc (class ExprVisitor): Likewise.
+ * modules.cc (layout_moduleinfo): Likewise.
+ * typeinfo.cc (class TypeInfoVisitor): Likewise.
+
2025-04-08 Iain Buclaw <ibuclaw@gdcproject.org>
* dmd/MERGE: Merge upstream dmd 51816cd01d.
diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc
index 160539d..e18f5d3 100644
--- a/gcc/d/d-compiler.cc
+++ b/gcc/d/d-compiler.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "dmd/compiler.h"
+#include "dmd/errors.h"
#include "dmd/expression.h"
#include "dmd/identifier.h"
#include "dmd/module.h"
@@ -164,7 +165,39 @@ Compiler::onParseModule (Module *m)
driver intends on compiling the import. */
bool
-Compiler::onImport (Module *)
+Compiler::onImport (Module *m)
{
- return false;
+ if (!includeImports)
+ return false;
+
+ if (m->filetype != FileType::d && m->filetype != FileType::c)
+ return false;
+
+ /* All imports modules are included except those in the runtime library. */
+ ModuleDeclaration *md = m->md;
+ if (md && md->id)
+ {
+ if (md->packages.length >= 1)
+ {
+ if (!strcmp (md->packages.ptr[0]->toChars (), "core")
+ || !strcmp (md->packages.ptr[0]->toChars (), "std")
+ || !strcmp (md->packages.ptr[0]->toChars (), "gcc")
+ || !strcmp (md->packages.ptr[0]->toChars (), "etc"))
+ return false;
+ }
+ else if (!strcmp (md->id->toChars (), "object"))
+ return false;
+ }
+ else if (m->ident)
+ {
+ if (!strcmp (m->ident->toChars (), "object"))
+ return false;
+ }
+
+ /* This import will be compiled. */
+ if (global.params.v.verbose)
+ message ("compileimport (%s)", m->srcfile.toChars ());
+
+ compiledImports.push (m);
+ return true;
}
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index b3786be..ec2ea59 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -523,6 +523,10 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
global.params.ignoreUnsupportedPragmas = value;
break;
+ case OPT_finclude_imports:
+ includeImports = true;
+ break;
+
case OPT_finvariants:
global.params.useInvariants = value ? CHECKENABLEon : CHECKENABLEoff;
break;
@@ -1085,9 +1089,9 @@ d_parse_file (void)
/* Buffer for contents of .ddoc files. */
OutBuffer ddocbuf;
- /* In this mode, the first file name is supposed to be a duplicate
- of one of the input files. */
- if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
+ /* In this mode, the main input file is supposed to be the same as the one
+ given by -fonly=. */
+ if (d_option.fonly && !endswith (main_input_filename, d_option.fonly))
error ("%<-fonly=%> argument is different from first input file name");
for (size_t i = 0; i < num_in_fnames; i++)
@@ -1309,6 +1313,21 @@ d_parse_file (void)
dmd::semantic3 (m, NULL);
}
+ if (includeImports)
+ {
+ for (size_t i = 0; i < compiledImports.length; i++)
+ {
+ Module *m = compiledImports[i];
+ gcc_assert (m->isRoot ());
+
+ if (global.params.v.verbose)
+ message ("semantic3 %s", m->toChars ());
+
+ dmd::semantic3 (m, NULL);
+ modules.push (m);
+ }
+ }
+
Module::runDeferredSemantic3 ();
/* Check again, incase semantic3 pass loaded any more modules. */
diff --git a/gcc/d/d-spec.cc b/gcc/d/d-spec.cc
index 7f4a779..c788048 100644
--- a/gcc/d/d-spec.cc
+++ b/gcc/d/d-spec.cc
@@ -104,8 +104,8 @@ lang_specific_driver (cl_decoded_option **in_decoded_options,
/* The total number of arguments with the new stuff. */
unsigned int num_args = 1;
- /* "-fonly" if it appears on the command line. */
- const char *only_source_option = 0;
+ /* "-fonly=" if it appears on the command line. */
+ const char *only_source_arg = 0;
/* Whether the -o option was used. */
bool saw_opt_o = false;
@@ -280,13 +280,13 @@ lang_specific_driver (cl_decoded_option **in_decoded_options,
case OPT_fonly_:
args[i] |= SKIPOPT;
- only_source_option = decoded_options[i].orig_option_with_args_text;
+ only_source_arg = arg;
if (arg != NULL)
{
- const char *suffix = strrchr (only_source_option, '.');
+ const char *suffix = strrchr (only_source_arg, '.');
if (suffix == NULL || strcmp (suffix, ".d") != 0)
- only_source_option = concat (only_source_option, ".d", NULL);
+ only_source_arg = concat (only_source_arg, ".d", NULL);
}
break;
@@ -335,48 +335,52 @@ lang_specific_driver (cl_decoded_option **in_decoded_options,
+ (phobos_library != PHOBOS_NOLINK) * 4 + 2;
new_decoded_options = XNEWVEC (cl_decoded_option, num_args);
- i = 0;
j = 0;
/* Copy the 0th argument, i.e., the name of the program itself. */
- new_decoded_options[j++] = decoded_options[i++];
+ new_decoded_options[j++] = decoded_options[0];
/* NOTE: We start at 1 now, not 0. */
- while (i < argc)
+ for (i = 1; i < argc; i++)
{
if (args[i] & SKIPOPT)
- {
- ++i;
- continue;
- }
-
- new_decoded_options[j] = decoded_options[i];
+ continue;
if (!saw_libcxx && (args[i] & WITHLIBCXX))
{
- --j;
saw_libcxx = &decoded_options[i];
+ continue;
}
- if (args[i] & DSOURCE)
+ if (only_source_arg && (args[i] & DSOURCE))
{
- if (only_source_option)
- --j;
+ if (!endswith (decoded_options[i].arg, only_source_arg))
+ continue;
}
- i++;
+ new_decoded_options[j] = decoded_options[i];
j++;
}
- if (only_source_option)
+ if (only_source_arg)
{
- const char *only_source_arg = only_source_option + 7;
+ /* Generate -fonly= option, then copy D input sources that were initially
+ skipped in first pass over all decoded_options. */
generate_option (OPT_fonly_, only_source_arg, 1, CL_DRIVER,
&new_decoded_options[j]);
j++;
- generate_option_input_file (only_source_arg,
- &new_decoded_options[j++]);
+ for (i = 1; i < argc; i++)
+ {
+ if (!(args[i] & DSOURCE))
+ continue;
+
+ if (endswith (decoded_options[i].arg, only_source_arg))
+ continue;
+
+ new_decoded_options[j] = decoded_options[i];
+ j++;
+ }
}
/* If no reason to link against libphobos library, then don't add it. */
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 136f78b..9ddf7cf 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -791,6 +791,12 @@ public:
}
else if (d->isDataseg ())
{
+ /* When the front-end type size is invalid, an error has already been
+ given for the declaration or type. */
+ dinteger_t size = dmd::size (d->type, d->loc);
+ if (size == SIZE_INVALID)
+ return;
+
tree decl = get_symbol_decl (d);
/* Only need to build the VAR_DECL for extern declarations. */
@@ -804,9 +810,7 @@ public:
return;
/* How big a symbol can be should depend on back-end. */
- tree size = build_integer_cst (dmd::size (d->type, d->loc),
- build_ctype (Type::tsize_t));
- if (!valid_constant_size_p (size))
+ if (!valid_constant_size_p (build_integer_cst (size, size_type_node)))
{
error_at (make_location_t (d->loc), "size is too large");
return;
@@ -835,8 +839,9 @@ public:
}
/* Frontend should have already caught this. */
- gcc_assert (!integer_zerop (size)
- || d->type->toBasetype ()->isTypeSArray ());
+ gcc_assert ((size != 0 && size != SIZE_INVALID)
+ || d->type->toBasetype ()->isTypeSArray ()
+ || d->isCsymbol ());
d_finish_decl (decl);
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index a05a50e..58d19b4 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-51816cd01deee5cc1d7d2c6e1e24788ec655b73e
+956e73d64e532a68213970316c2590c572ec03f3
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/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 19111e3..b02f6ea 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -6978,10 +6978,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
while (1)
{
AttribDeclaration ad = s.isAttribDeclaration();
- if (!ad)
- break;
- if (ad.decl && ad.decl.length == 1)
+ if (ad && ad.decl && ad.decl.length == 1)
s = (*ad.decl)[0];
+ else
+ break;
}
//printf("inserting '%s' %p into sc = %p\n", s.toChars(), s, sc);
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 59952a2..62a575e 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -421,6 +421,7 @@ struct SourceLoc
uint32_t line;
uint32_t column;
uint32_t fileOffset;
+ DString fileContent;
};
struct Loc
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 63313ac..ed9f7f1 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -132,7 +132,7 @@ class Lexer
// debug printf("Lexer::Lexer(%p)\n", base);
// debug printf("lexer.filename = %s\n", filename);
token = Token.init;
- this.baseLoc = newBaseLoc(filename, endoffset);
+ this.baseLoc = newBaseLoc(filename, base[0 .. endoffset]);
this.linnum = 1;
this.base = base;
this.end = base + endoffset;
@@ -224,7 +224,7 @@ class Lexer
inTokenStringConstant = 0;
lastDocLine = 0;
- baseLoc = newBaseLoc("#defines", slice.length);
+ baseLoc = newBaseLoc("#defines", slice);
scanloc = baseLoc.getLoc(0);
}
diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d
index 54b3fb6..393ffb8 100644
--- a/gcc/d/dmd/location.d
+++ b/gcc/d/dmd/location.d
@@ -64,7 +64,7 @@ nothrow:
extern (C++) static Loc singleFilename(const char* filename)
{
Loc result;
- locFileTable ~= new BaseLoc(filename.toDString, locIndex, 0, [0]);
+ locFileTable ~= new BaseLoc(filename.toDString, null, locIndex, 0, [0]);
result.index = locIndex++;
return result;
}
@@ -235,16 +235,20 @@ struct SourceLoc
uint column; /// column number (starts at 1)
uint fileOffset; /// byte index into file
+ /// Index `fileOffset` into this to to obtain source code context of this location
+ const(char)[] fileContent;
+
// aliases for backwards compatibility
alias linnum = line;
alias charnum = column;
- this(const(char)[] filename, uint line, uint column, uint fileOffset = 0) nothrow @nogc pure @safe
+ this(const(char)[] filename, uint line, uint column, uint fileOffset = 0, const(char)[] fileContent = null) nothrow @nogc pure @safe
{
this.filename = filename;
this.line = line;
this.column = column;
this.fileOffset = fileOffset;
+ this.fileContent = fileContent;
}
this(Loc loc) nothrow @nogc @trusted
@@ -300,15 +304,15 @@ private size_t fileTableIndex(uint index) nothrow @nogc
* Create a new source location map for a file
* Params:
* filename = source file name
- * size = space to reserve for locations, equal to the file size in bytes
+ * fileContent = content of source file
* Returns: new BaseLoc
*/
-BaseLoc* newBaseLoc(const(char)* filename, size_t size) nothrow
+BaseLoc* newBaseLoc(const(char)* filename, const(char)[] fileContent) nothrow
{
- locFileTable ~= new BaseLoc(filename.toDString, locIndex, 1, [0]);
+ locFileTable ~= new BaseLoc(filename.toDString, fileContent, locIndex, 1, [0]);
// Careful: the endloc of a FuncDeclaration can
// point to 1 past the very last byte in the file, so account for that
- locIndex += size + 1;
+ locIndex += fileContent.length + 1;
return locFileTable[$ - 1];
}
@@ -354,6 +358,7 @@ struct BaseLoc
@safe nothrow:
const(char)[] filename; /// Source file name
+ const(char)[] fileContents; /// Source file contents
uint startIndex; /// Subtract this from Loc.index to get file offset
int startLine = 1; /// Line number at index 0
uint[] lines; /// For each line, the file offset at which it starts. At index 0 there's always a 0 entry.
@@ -384,11 +389,11 @@ struct BaseLoc
{
auto fname = filename.toDString;
if (substitutions.length == 0)
- substitutions ~= BaseLoc(this.filename, 0, 0);
+ substitutions ~= BaseLoc(this.filename, null, 0, 0);
if (fname.length == 0)
fname = substitutions[$ - 1].filename;
- substitutions ~= BaseLoc(fname, offset, cast(int) (line - lines.length + startLine - 2));
+ substitutions ~= BaseLoc(fname, null, offset, cast(int) (line - lines.length + startLine - 2));
}
/// Returns: `loc` modified by substitutions from #file / #line directives
@@ -408,7 +413,7 @@ struct BaseLoc
private SourceLoc getSourceLoc(uint offset) @nogc
{
const i = getLineIndex(offset);
- const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset);
+ const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset, fileContents);
return substitute(sl);
}
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index 3bc0489..d4c7a58 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -3266,9 +3266,19 @@ Type merge(Type type)
case Tsarray:
// prevents generating the mangle if the array dim is not yet known
- if (!type.isTypeSArray().dim.isIntegerExp())
- return type;
- goto default;
+ if (auto ie = type.isTypeSArray().dim.isIntegerExp())
+ {
+ // After TypeSemantic, the length is always converted to size_t, but the parser
+ // usually generates regular integer types (e.g. in cast(const ubyte[2])) which
+ // it may try to merge, which then leads to failing implicit conversions as 2LU != 2
+ // according to Expression.equals. Only merge array types with size_t lengths for now.
+ // https://github.com/dlang/dmd/issues/21179
+ if (ie.type != Type.tsize_t)
+ return type;
+
+ goto default;
+ }
+ return type;
case Tenum:
break;
diff --git a/gcc/d/gdc.texi b/gcc/d/gdc.texi
index 2cb0c4a62..3a8bea0 100644
--- a/gcc/d/gdc.texi
+++ b/gcc/d/gdc.texi
@@ -277,6 +277,12 @@ Sets @code{__traits(getTargetInfo, "cppStd")} to @code{202002}.
Sets @code{__traits(getTargetInfo, "cppStd")} to @code{202302}.
@end table
+@opindex finclude-imports
+@item -finclude-imports
+Include imported modules in the compilation, as if they were given on the
+command line. When this option is enabled, all imported modules are compiled
+except those that are part of libphobos.
+
@opindex finvariants
@opindex fno-invariants
@item -fno-invariants
diff --git a/gcc/d/imports.cc b/gcc/d/imports.cc
index 776caaf..16e4df6 100644
--- a/gcc/d/imports.cc
+++ b/gcc/d/imports.cc
@@ -182,7 +182,11 @@ public:
vec_alloc (tset, d->a.length);
for (size_t i = 0; i < d->a.length; i++)
- vec_safe_push (tset, build_import_decl (d->a[i]));
+ {
+ tree overload = build_import_decl (d->a[i]);
+ if (overload != NULL_TREE)
+ vec_safe_push (tset, overload);
+ }
this->result_ = build_tree_list_vec (tset);
tset->truncate (0);
diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt
index 50c6f2f..298ff58 100644
--- a/gcc/d/lang.opt
+++ b/gcc/d/lang.opt
@@ -327,6 +327,10 @@ fignore-unknown-pragmas
D
Ignore unsupported pragmas.
+finclude-imports
+D RejectNegative
+Include imported modules in the compilation.
+
finvariants
D Var(flag_invariants)
Generate code for class invariant contracts.
diff --git a/gcc/d/lang.opt.urls b/gcc/d/lang.opt.urls
index fa311d4..b4886bf 100644
--- a/gcc/d/lang.opt.urls
+++ b/gcc/d/lang.opt.urls
@@ -155,6 +155,9 @@ LangUrlSuffix_D(gdc/Runtime-Options.html#index-fextern-std)
fignore-unknown-pragmas
LangUrlSuffix_D(gdc/Warnings.html#index-fignore-unknown-pragmas)
+finclude-imports
+LangUrlSuffix_D(gdc/Runtime-Options.html#index-finclude-imports)
+
finvariants
LangUrlSuffix_D(gdc/Runtime-Options.html#index-finvariants)
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index e43fa88..1c74840 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -1179,6 +1179,26 @@ public:
layout_type (t->ctype);
+ /* Fix up all forward-referenced variants of this enum type. */
+ for (tree v = TYPE_MAIN_VARIANT (t->ctype); v;
+ v = TYPE_NEXT_VARIANT (v))
+ {
+ if (v == t->ctype)
+ continue;
+
+ TYPE_VALUES (v) = TYPE_VALUES (t->ctype);
+ TYPE_LANG_SPECIFIC (v) = TYPE_LANG_SPECIFIC (t->ctype);
+ TYPE_MIN_VALUE (v) = TYPE_MIN_VALUE (t->ctype);
+ TYPE_MAX_VALUE (v) = TYPE_MAX_VALUE (t->ctype);
+ TYPE_UNSIGNED (v) = TYPE_UNSIGNED (t->ctype);
+ TYPE_SIZE (v) = TYPE_SIZE (t->ctype);
+ TYPE_SIZE_UNIT (v) = TYPE_SIZE_UNIT (t->ctype);
+ SET_TYPE_MODE (v, TYPE_MODE (t->ctype));
+ TYPE_PRECISION (v) = TYPE_PRECISION (t->ctype);
+ SET_TYPE_ALIGN (v, TYPE_ALIGN (t->ctype));
+ TYPE_USER_ALIGN (v) = TYPE_USER_ALIGN (t->ctype);
+ }
+
/* Complete forward-referenced fields of this enum type. */
finish_incomplete_fields (t->ctype);
}