diff options
Diffstat (limited to 'gcc/d')
-rw-r--r-- | gcc/d/ChangeLog | 75 | ||||
-rw-r--r-- | gcc/d/d-compiler.cc | 37 | ||||
-rw-r--r-- | gcc/d/d-lang.cc | 25 | ||||
-rw-r--r-- | gcc/d/d-spec.cc | 50 | ||||
-rw-r--r-- | gcc/d/decl.cc | 15 | ||||
-rw-r--r-- | gcc/d/dmd/MERGE | 2 | ||||
-rw-r--r-- | gcc/d/dmd/expressionsem.d | 6 | ||||
-rw-r--r-- | gcc/d/dmd/globals.h | 1 | ||||
-rw-r--r-- | gcc/d/dmd/lexer.d | 4 | ||||
-rw-r--r-- | gcc/d/dmd/location.d | 23 | ||||
-rw-r--r-- | gcc/d/dmd/typesem.d | 16 | ||||
-rw-r--r-- | gcc/d/gdc.texi | 6 | ||||
-rw-r--r-- | gcc/d/imports.cc | 6 | ||||
-rw-r--r-- | gcc/d/lang.opt | 4 | ||||
-rw-r--r-- | gcc/d/lang.opt.urls | 3 | ||||
-rw-r--r-- | gcc/d/types.cc | 20 |
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); } |