diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2024-02-17 21:03:38 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2024-02-17 21:28:58 +0100 |
commit | 5aff58e5ed8f634e0b20892452bde484db93039b (patch) | |
tree | 64900b511f0dbee5f61fb9e3e19c1ee8274f166a /gcc | |
parent | a71d87431d0c4e04a402ef6566be090c470b2b53 (diff) | |
download | gcc-5aff58e5ed8f634e0b20892452bde484db93039b.zip gcc-5aff58e5ed8f634e0b20892452bde484db93039b.tar.gz gcc-5aff58e5ed8f634e0b20892452bde484db93039b.tar.bz2 |
d: Merge dmd, druntime 9471b25db9, phobos 547886846.
D front-end changes:
- Import dmd v2.107.1-rc.1.
D runtime changes:
- Import druntime v2.107.1-rc.1.
Phobos changes:
- Import phobos v2.107.1-rc.1.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 9471b25db9.
* dmd/VERSION: Bump version to v2.107.1-rc.1.
* Make-lang.in (D_FRONTEND_OBJS): Add d/cxxfrontend.o.
* d-attribs.cc (build_attributes): Update for new front-end interface.
* d-builtins.cc (build_frontend_type): Likewise.
(strip_type_modifiers): Likewise.
(covariant_with_builtin_type_p): Likewise.
* d-codegen.cc (declaration_type): Likewise.
(parameter_type): Likewise.
(build_array_struct_comparison): Likewise.
(void_okay_p): Likewise.
* d-convert.cc (convert_expr): Likewise.
(check_valist_conversion): Likewise.
* d-lang.cc (d_generate_ddoc_file): Likewise.
(d_parse_file): Likewise.
* d-target.cc (TargetCPP::toMangle): Likewise.
(TargetCPP::typeInfoMangle): Likewise.
(TargetCPP::thunkMangle): Likewise.
(TargetCPP::parameterType): Likewise.
* decl.cc (d_mangle_decl): Likewise.
(DeclVisitor::visit): Likewise.
(DeclVisitor::visit (CAsmDeclaration *)): New method.
(get_symbol_decl): Update for new front-end interface.
(layout_class_initializer): Likewise.
* expr.cc (ExprVisitor::visit): Likewise.
* intrinsics.cc (maybe_set_intrinsic): Likewise.
(expand_intrinsic_rotate): Likewise.
* modules.cc (layout_moduleinfo_fields): Likewise.
(layout_moduleinfo): Likewise.
* runtime.cc (get_libcall_type): Likewise.
* typeinfo.cc (make_frontend_typeinfo): Likewise.
(TypeInfoVisitor::visit): Likewise.
(create_typeinfo): Likewise.
* types.cc (same_type_p): Likewise.
(build_ctype): Likewise.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 9471b25db9.
* src/MERGE: Merge upstream phobos 547886846.
Diffstat (limited to 'gcc')
77 files changed, 1637 insertions, 696 deletions
diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index d379ef1..eaea6e0 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -104,6 +104,7 @@ D_FRONTEND_OBJS = \ d/cppmangle.o \ d/ctfeexpr.o \ d/ctorflow.o \ + d/cxxfrontend.o \ d/dcast.o \ d/dclass.o \ d/declaration.o \ diff --git a/gcc/d/d-attribs.cc b/gcc/d/d-attribs.cc index 36a139b..0f7ca10 100644 --- a/gcc/d/d-attribs.cc +++ b/gcc/d/d-attribs.cc @@ -320,14 +320,14 @@ build_attributes (Expressions *eattrs) if (!eattrs) return NULL_TREE; - expandTuples (eattrs); + dmd::expandTuples (eattrs); tree attribs = NULL_TREE; for (size_t i = 0; i < eattrs->length; i++) { Expression *attr = (*eattrs)[i]; - Dsymbol *sym = toDsymbol (attr->type, NULL); + Dsymbol *sym = dmd::toDsymbol (attr->type, NULL); if (!sym) { @@ -354,7 +354,7 @@ build_attributes (Expressions *eattrs) /* Get the result of the attribute if it hasn't already been folded. */ if (attr->op == EXP::call) - attr = ctfeInterpret (attr); + attr = dmd::ctfeInterpret (attr); if (attr->op != EXP::structLiteral) { diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc index 24ac456..dc50df4 100644 --- a/gcc/d/d-builtins.cc +++ b/gcc/d/d-builtins.cc @@ -98,14 +98,14 @@ build_frontend_type (tree type) /* Check for char * first. Needs to be done for chars/string. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node) { - dtype = addMod (Type::tchar, dtype->mod); - return addMod (dtype->pointerTo (), mod); + dtype = dmd::addMod (Type::tchar, dtype->mod); + return dmd::addMod (dmd::pointerTo (dtype), mod); } if (dtype->ty == TY::Tfunction) - return addMod (TypePointer::create (dtype), mod); + return dmd::addMod (TypePointer::create (dtype), mod); - return addMod (dtype->pointerTo (), mod); + return dmd::addMod (dmd::pointerTo (dtype), mod); } break; @@ -116,7 +116,7 @@ build_frontend_type (tree type) /* Want to assign ctype directly so that the REFERENCE_TYPE code can be turned into as an `inout' argument. Can't use pointerTo(), because the returned Type is shared. */ - dtype = addMod (TypePointer::create (dtype), mod); + dtype = dmd::addMod (TypePointer::create (dtype), mod); dtype->ctype = type; builtin_converted_decls.safe_push (builtin_data (dtype, type)); return dtype; @@ -125,7 +125,7 @@ build_frontend_type (tree type) case BOOLEAN_TYPE: /* Should be no need for size checking. */ - return addMod (Type::tbool, mod); + return dmd::addMod (Type::tbool, mod); case INTEGER_TYPE: { @@ -143,7 +143,7 @@ build_frontend_type (tree type) || size != dtype->size ()) continue; - return addMod (dtype, mod); + return dmd::addMod (dtype, mod); } break; } @@ -160,7 +160,7 @@ build_frontend_type (tree type) if (dtype->size () != size) continue; - return addMod (dtype, mod); + return dmd::addMod (dtype, mod); } break; } @@ -177,13 +177,13 @@ build_frontend_type (tree type) if (dtype->size () != size) continue; - return addMod (dtype, mod); + return dmd::addMod (dtype, mod); } break; } case VOID_TYPE: - return addMod (Type::tvoid, mod); + return dmd::addMod (Type::tvoid, mod); case ARRAY_TYPE: dtype = build_frontend_type (TREE_TYPE (type)); @@ -197,7 +197,8 @@ build_frontend_type (tree type) length = size_binop (PLUS_EXPR, size_one_node, convert (sizetype, length)); - dtype = addMod (dtype->sarrayOf (TREE_INT_CST_LOW (length)), mod); + dtype = + dmd::addMod (dtype->sarrayOf (TREE_INT_CST_LOW (length)), mod); builtin_converted_decls.safe_push (builtin_data (dtype, type)); return dtype; } @@ -213,11 +214,11 @@ build_frontend_type (tree type) if (!dtype) break; - dtype = addMod (dtype->sarrayOf (nunits), mod); + dtype = dmd::addMod (dtype->sarrayOf (nunits), mod); if (target.isVectorTypeSupported (dtype->size (), dtype->nextOf ())) break; - dtype = addMod (TypeVector::create (dtype), mod); + dtype = dmd::addMod (TypeVector::create (dtype), mod); builtin_converted_decls.safe_push (builtin_data (dtype, type)); return dtype; } @@ -241,9 +242,9 @@ build_frontend_type (tree type) sdecl->alignsize = TYPE_ALIGN_UNIT (type); sdecl->alignment.setDefault (); sdecl->sizeok = Sizeok::done; - sdecl->type = addMod (TypeStruct::create (sdecl), mod); + sdecl->type = dmd::addMod (TypeStruct::create (sdecl), mod); sdecl->type->ctype = type; - merge2 (sdecl->type); + dmd::merge2 (sdecl->type); /* Add both named and anonymous fields as members of the struct. Anonymous fields still need a name in D, so call them "__pad%u". */ @@ -334,7 +335,7 @@ build_frontend_type (tree type) if (args->length != 0 || varargs_p == VARARGnone) { dtype = TypeFunction::create (args, dtype, varargs_p, LINK::c); - return addMod (dtype, mod); + return dmd::addMod (dtype, mod); } } break; @@ -690,10 +691,10 @@ strip_type_modifiers (Type *type) if (type->ty == TY::Tpointer) { Type *tnext = strip_type_modifiers (type->nextOf ()); - return tnext->pointerTo (); + return dmd::pointerTo (tnext); } - return castMod (type, 0); + return dmd::castMod (type, 0); } /* Returns true if types T1 and T2 representing return types or types of @@ -727,7 +728,7 @@ static bool covariant_with_builtin_type_p (Type *t1, Type *t2) { /* Check whether the declared function matches the built-in. */ - if (same_type_p (t1, t2) || covariant (t1, t2) == Covariant::yes) + if (same_type_p (t1, t2) || dmd::covariant (t1, t2) == Covariant::yes) return true; /* May not be covariant because of D attributes applied on t1. diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index dc52816..5bc2339 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -150,14 +150,14 @@ declaration_type (Declaration *decl) TypeFunction *tf = TypeFunction::create (NULL, decl->type, VARARGnone, LINK::d); TypeDelegate *t = TypeDelegate::create (tf); - return build_ctype (merge2 (t)); + return build_ctype (dmd::merge2 (t)); } /* Static array va_list have array->pointer conversions applied. */ if (decl->isParameter () && valist_array_p (decl->type)) { - Type *valist = decl->type->nextOf ()->pointerTo (); - valist = castMod (valist, decl->type->mod); + Type *valist = dmd::pointerTo (decl->type->nextOf ()); + valist = dmd::castMod (valist, decl->type->mod); return build_ctype (valist); } @@ -200,14 +200,14 @@ parameter_type (Parameter *arg) TypeFunction *tf = TypeFunction::create (NULL, arg->type, VARARGnone, LINK::d); TypeDelegate *t = TypeDelegate::create (tf); - return build_ctype (merge2 (t)); + return build_ctype (dmd::merge2 (t)); } /* Static array va_list have array->pointer conversions applied. */ if (valist_array_p (arg->type)) { - Type *valist = arg->type->nextOf ()->pointerTo (); - valist = castMod (valist, arg->type->mod); + Type *valist = dmd::pointerTo (arg->type->nextOf ()); + valist = dmd::castMod (valist, arg->type->mod); return build_ctype (valist); } @@ -1089,7 +1089,7 @@ build_array_struct_comparison (tree_code code, StructDeclaration *sd, add_stmt (build_assign (INIT_EXPR, result, init)); /* Cast pointer-to-array to pointer-to-struct. */ - tree ptrtype = build_ctype (sd->type->pointerTo ()); + tree ptrtype = build_ctype (dmd::pointerTo (sd->type)); tree lentype = TREE_TYPE (length); push_binding_level (level_block); @@ -1859,7 +1859,7 @@ void_okay_p (tree t) if (VOID_TYPE_P (TREE_TYPE (type))) { - tree totype = build_ctype (Type::tuns8->pointerTo ()); + tree totype = build_ctype (dmd::pointerTo (Type::tuns8)); return fold_convert (totype, t); } diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc index 011b22e..4ccbf09 100644 --- a/gcc/d/d-convert.cc +++ b/gcc/d/d-convert.cc @@ -470,7 +470,7 @@ convert_expr (tree exp, Type *etype, Type *totype) dinteger_t esize = ebtype->nextOf ()->size (); dinteger_t tsize = tbtype->nextOf ()->size (); - tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ()); + tree ptrtype = build_ctype (dmd::pointerTo (tbtype->nextOf ())); if (esize != tsize) { @@ -727,12 +727,12 @@ check_valist_conversion (Expression *expr, Type *totype, bool in_assignment) if (VarExp *ve = expr->isVarExp ()) { decl = ve->var; - type = ve->var->type->nextOf ()->pointerTo (); + type = dmd::pointerTo (ve->var->type->nextOf ()); } else if (SymOffExp *se = expr->isSymOffExp ()) { decl = se->var; - type = se->var->type->nextOf ()->pointerTo ()->pointerTo (); + type = dmd::pointerTo (dmd::pointerTo (se->var->type->nextOf ())); } /* Should not be called unless is_valist_parameter_type also matched. */ diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 138a7f9..89ffa7e 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -1029,8 +1029,8 @@ d_generate_ddoc_file (Module *m, OutBuffer &ddocbuf) d_read_ddoc_files (global.params.ddoc.files, ddocbuf); OutBuffer ddocbuf_out; - gendocfile (m, ddocbuf.peekChars (), ddocbuf.length (), global.datetime, - global.errorSink, ddocbuf_out); + dmd::gendocfile (m, ddocbuf.peekChars (), ddocbuf.length (), global.datetime, + global.errorSink, ddocbuf_out); d_write_file (m->docfile.toChars (), ddocbuf_out.peekChars ()); } @@ -1205,7 +1205,7 @@ d_parse_file (void) message ("import %s", m->toChars ()); OutBuffer buf; - genhdrfile (m, global.params.dihdr.fullOutput, buf); + dmd::genhdrfile (m, global.params.dihdr.fullOutput, buf); d_write_file (m->hdrfile.toChars (), buf.peekChars ()); } @@ -1223,7 +1223,7 @@ d_parse_file (void) if (global.params.v.verbose) message ("importall %s", m->toChars ()); - importAll (m, NULL); + dmd::importAll (m, NULL); } if (global.errors) @@ -1247,7 +1247,7 @@ d_parse_file (void) if (global.params.v.verbose) message ("semantic %s", m->toChars ()); - dsymbolSemantic (m, NULL); + dmd::dsymbolSemantic (m, NULL); } /* Do deferred semantic analysis. */ @@ -1278,7 +1278,7 @@ d_parse_file (void) if (global.params.v.verbose) message ("semantic2 %s", m->toChars ()); - semantic2 (m, NULL); + dmd::semantic2 (m, NULL); } Module::runDeferredSemantic2 (); @@ -1294,7 +1294,7 @@ d_parse_file (void) if (global.params.v.verbose) message ("semantic3 %s", m->toChars ()); - semantic3 (m, NULL); + dmd::semantic3 (m, NULL); } Module::runDeferredSemantic3 (); @@ -1318,7 +1318,7 @@ d_parse_file (void) /* Declare the name of the root module as the first global name in order to make the middle-end fully deterministic. */ OutBuffer buf; - mangleToBuffer (Module::rootModule, buf); + dmd::mangleToBuffer (Module::rootModule, buf); first_global_object_name = buf.extractChars (); } @@ -1341,15 +1341,15 @@ d_parse_file (void) if (global.params.v.templates) { - printTemplateStats (global.params.v.templatesListInstances, - global.errorSink); + dmd::printTemplateStats (global.params.v.templatesListInstances, + global.errorSink); } /* Generate JSON files. */ if (global.params.json.doOutput) { OutBuffer buf; - json_generate (modules, buf); + dmd::json_generate (modules, buf); d_write_file (global.params.json.name.ptr, buf.peekChars ()); } @@ -1372,14 +1372,14 @@ d_parse_file (void) OutBuffer buf; buf.doindent = 1; - moduleToBuffer (buf, true, m); + dmd::moduleToBuffer (buf, true, m); message ("%s", buf.peekChars ()); } } /* Generate C++ header files. */ if (global.params.cxxhdr.doOutput) - genCppHdrFiles (modules); + dmd::genCppHdrFiles (modules); if (global.errors) goto had_errors; diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index ff3489c..b9d1244 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -335,7 +335,7 @@ Target::isVectorOpSupported (Type *type, EXP op, Type *) const char * TargetCPP::toMangle (Dsymbol *s) { - return toCppMangleItanium (s); + return dmd::toCppMangleItanium (s); } /* Return the symbol mangling of CD for C++ linkage. */ @@ -343,7 +343,7 @@ TargetCPP::toMangle (Dsymbol *s) const char * TargetCPP::typeInfoMangle (ClassDeclaration *cd) { - return cppTypeInfoMangleItanium (cd); + return dmd::cppTypeInfoMangleItanium (cd); } /* Get mangle name of a this-adjusting thunk to the function declaration FD @@ -352,7 +352,7 @@ TargetCPP::typeInfoMangle (ClassDeclaration *cd) const char * TargetCPP::thunkMangle (FuncDeclaration *fd, int offset) { - return cppThunkMangleItanium (fd, offset); + return dmd::cppThunkMangleItanium (fd, offset); } /* For a vendor-specific type, return a string containing the C++ mangling. @@ -381,11 +381,11 @@ TargetCPP::parameterType (Type *type) Type *tvalist = target.va_listType (Loc (), NULL); if (type->ty == TY::Tsarray && tvalist->ty == TY::Tsarray) { - Type *tb = mutableOf (type->toBasetype ()); + Type *tb = dmd::mutableOf (type->toBasetype ()); if (tb == tvalist) { - tb = type->nextOf ()->pointerTo (); - type = castMod (tb, type->mod); + tb = dmd::pointerTo (type->nextOf ()); + type = dmd::castMod (tb, type->mod); } } diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 827495b..25398a3 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -69,11 +69,11 @@ const char * d_mangle_decl (Dsymbol *decl) { if (decl->isFuncDeclaration ()) - return mangleExact ((FuncDeclaration *) decl); + return dmd::mangleExact ((FuncDeclaration *) decl); else { OutBuffer buf; - mangleToBuffer (decl, buf); + dmd::mangleToBuffer (decl, buf); return buf.extractChars (); } } @@ -332,6 +332,14 @@ public: d->semanticRun = PASS::obj; } + /* Finish a top-level `asm` definition. */ + + void visit (CAsmDeclaration *d) final override + { + tree asm_str = build_expr (d->code); + symtab->finalize_toplevel_asm (asm_str); + } + /* Expand any local variables found in tuples. */ void visit (TupleDeclaration *d) final override @@ -402,7 +410,7 @@ public: void visit (Nspace *d) final override { - if (isError (d) || !d->members) + if (dmd::isError (d) || !d->members) return; for (size_t i = 0; i < d->members->length; i++) @@ -447,7 +455,7 @@ public: void visit (TemplateInstance *d) final override { - if (isError (d)|| !d->members) + if (dmd::isError (d)|| !d->members) return; if (!d->needsCodegen ()) @@ -461,7 +469,7 @@ public: void visit (TemplateMixin *d) final override { - if (isError (d)|| !d->members) + if (dmd::isError (d)|| !d->members) return; for (size_t i = 0; i < d->members->length; i++) @@ -539,7 +547,7 @@ public: continue; /* Ensure function has a return value. */ - if (!functionSemantic (fd)) + if (!dmd::functionSemantic (fd)) has_errors = true; /* No name hiding to check for. */ @@ -765,7 +773,7 @@ public: && d->_init && !d->_init->isVoidInitializer ()) { /* Evaluate RHS for side effects first. */ - Expression *ie = initializerToExpression (d->_init); + Expression *ie = dmd::initializerToExpression (d->_init); add_stmt (build_expr (ie)); Expression *e = d->type->defaultInitLiteral (d->loc); @@ -785,7 +793,7 @@ public: { /* Do not store variables we cannot take the address of, but keep the values for purposes of debugging. */ - if (d->type->isscalar () && !hasPointers (d->type)) + if (d->type->isscalar () && !dmd::hasPointers (d->type)) { tree decl = get_symbol_decl (d); d_pushdecl (decl); @@ -820,7 +828,8 @@ public: /* Use the explicit initializer, this includes `void`. */ if (!d->_init->isVoidInitializer ()) { - Expression *e = initializerToExpression (d->_init, d->type); + Expression *e = + dmd::initializerToExpression (d->_init, d->type); DECL_INITIAL (decl) = build_expr (e, true); } } @@ -857,7 +866,7 @@ public: tree decl = get_symbol_decl (d); ExpInitializer *vinit = d->_init->isExpInitializer (); - Expression *ie = initializerToExpression (vinit); + Expression *ie = dmd::initializerToExpression (vinit); tree exp = build_expr (ie); /* Maybe put variable on list of things needing destruction. */ @@ -964,7 +973,7 @@ public: gcc_assert (!doing_semantic_analysis_p); doing_semantic_analysis_p = true; - functionSemantic3 (d); + dmd::functionSemantic3 (d); Module::runDeferredSemantic3 (); doing_semantic_analysis_p = false; } @@ -1241,7 +1250,7 @@ get_symbol_decl (Declaration *decl) if (!vd->canTakeAddressOf () && !vd->type->isscalar ()) { gcc_assert (vd->_init && !vd->_init->isVoidInitializer ()); - Expression *ie = initializerToExpression (vd->_init); + Expression *ie = dmd::initializerToExpression (vd->_init); decl->csym = build_expr (ie, false); return decl->csym; } @@ -1252,7 +1261,7 @@ get_symbol_decl (Declaration *decl) if (fd) { /* Run full semantic on functions we need to know about. */ - if (!functionSemantic (fd)) + if (!dmd::functionSemantic (fd)) { decl->csym = error_mark_node; return decl->csym; @@ -1301,7 +1310,7 @@ get_symbol_decl (Declaration *decl) /* Non-scalar manifest constants have already been dealt with. */ gcc_assert (vd->type->isscalar ()); - Expression *ie = initializerToExpression (vd->_init); + Expression *ie = dmd::initializerToExpression (vd->_init); DECL_INITIAL (decl->csym) = build_expr (ie, true); } @@ -2398,7 +2407,7 @@ layout_class_initializer (ClassDeclaration *cd) NewExp *ne = NewExp::create (cd->loc, NULL, cd->type, NULL); ne->type = cd->type; - Expression *e = ctfeInterpret (ne); + Expression *e = dmd::ctfeInterpret (ne); gcc_assert (e->op == EXP::classReference); return build_class_instance (e->isClassReferenceExp ()); diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 74c1945..021149a 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -11240a96635074b2f79d908b9348e9c0fbc3c7dc +9471b25db9ed44d71e0e27956430c0c6a09c16db 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 8463aee..1880c98 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.107.0 +v2.107.1-rc.1 diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h index 6a86400..c972f0a 100644 --- a/gcc/d/dmd/aggregate.h +++ b/gcc/d/dmd/aggregate.h @@ -41,8 +41,11 @@ enum class Baseok : uint8_t semanticdone // all base classes semantic done }; -FuncDeclaration *search_toString(StructDeclaration *sd); -void semanticTypeInfoMembers(StructDeclaration *sd); +namespace dmd +{ + FuncDeclaration *search_toString(StructDeclaration *sd); + void semanticTypeInfoMembers(StructDeclaration *sd); +} enum class ClassKind : uint8_t { diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index d462350..536a212 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -136,6 +136,23 @@ final class CParser(AST) : Parser!AST return wrap; } + /* GNU Extensions + * external-declaration: + * simple-asm-expr ; + */ + if (token.value == TOK.asm_) + { + nextToken(); // move past asm + check(TOK.leftParenthesis); + if (token.value != TOK.string_) + error("string literal expected for Asm Definition, not `%s`", token.toChars()); + auto code = cparsePrimaryExp(); + check(TOK.rightParenthesis); + symbols.push(new AST.CAsmDeclaration(code)); + check(TOK.semicolon); + continue; + } + cparseDeclaration(LVL.global); } } diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d index 90b6295..0116aa3 100644 --- a/gcc/d/dmd/cppmangle.d +++ b/gcc/d/dmd/cppmangle.d @@ -65,7 +65,7 @@ package CppOperator isCppOperator(Identifier id) } /// -extern(C++) const(char)* toCppMangleItanium(Dsymbol s) +const(char)* toCppMangleItanium(Dsymbol s) { //printf("toCppMangleItanium(%s)\n", s.toChars()); OutBuffer buf; @@ -75,7 +75,7 @@ extern(C++) const(char)* toCppMangleItanium(Dsymbol s) } /// -extern(C++) const(char)* cppTypeInfoMangleItanium(Dsymbol s) +const(char)* cppTypeInfoMangleItanium(Dsymbol s) { //printf("cppTypeInfoMangle(%s)\n", s.toChars()); OutBuffer buf; @@ -86,7 +86,7 @@ extern(C++) const(char)* cppTypeInfoMangleItanium(Dsymbol s) } /// -extern(C++) const(char)* cppThunkMangleItanium(FuncDeclaration fd, int offset) +const(char)* cppThunkMangleItanium(FuncDeclaration fd, int offset) { //printf("cppThunkMangleItanium(%s)\n", fd.toChars()); OutBuffer buf; diff --git a/gcc/d/dmd/cxxfrontend.d b/gcc/d/dmd/cxxfrontend.d new file mode 100644 index 0000000..1b94a69 --- /dev/null +++ b/gcc/d/dmd/cxxfrontend.d @@ -0,0 +1,623 @@ +/** + * Contains C++ interfaces for interacting with DMD as a library. + * + * Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved + * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) + * 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/cxxfrontend.d, _cxxfrontend.d) + * Documentation: https://dlang.org/phobos/dmd_cxxfrontend.html + * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/cxxfrontend.d + */ +module dmd.cxxfrontend; + +import dmd.aggregate : AggregateDeclaration; +import dmd.arraytypes; +import dmd.astenums; +import dmd.common.outbuffer : OutBuffer; +import dmd.dmodule /*: Module*/; +import dmd.dscope : Scope; +import dmd.dstruct /*: StructDeclaration*/; +import dmd.dsymbol : Dsymbol, ScopeDsymbol, CAsmDeclaration, SearchOpt, SearchOptFlags; +import dmd.dtemplate /*: TemplateInstance, TemplateParameter, Tuple*/; +import dmd.errorsink : ErrorSink; +import dmd.expression /*: Expression*/; +import dmd.func : FuncDeclaration; +import dmd.globals; +import dmd.identifier : Identifier; +import dmd.init : Initializer, NeedInterpret; +import dmd.location : Loc; +import dmd.mtype /*: Covariant, Type, Parameter, ParameterList*/; +import dmd.rootobject : RootObject; +import dmd.statement : Statement, AsmStatement, GccAsmStatement; + +// NB: At some point in the future, we can switch to shortened function syntax. +extern (C++, "dmd"): + +/*********************************************************** + * cppmangle.d + */ +const(char)* toCppMangleItanium(Dsymbol s) +{ + import dmd.cppmangle; + return dmd.cppmangle.toCppMangleItanium(s); +} + +const(char)* cppTypeInfoMangleItanium(Dsymbol s) +{ + import dmd.cppmangle; + return dmd.cppmangle.cppTypeInfoMangleItanium(s); +} + +const(char)* cppThunkMangleItanium(FuncDeclaration fd, int offset) +{ + import dmd.cppmangle; + return dmd.cppmangle.cppThunkMangleItanium(fd, offset); +} + +/*********************************************************** + * dinterpret.d + */ +Expression ctfeInterpret(Expression e) +{ + import dmd.dinterpret; + return dmd.dinterpret.ctfeInterpret(e); +} + +/*********************************************************** + * dmangle.d + */ +const(char)* mangleExact(FuncDeclaration fd) +{ + import dmd.dmangle; + return dmd.dmangle.mangleExact(fd); +} + +void mangleToBuffer(Type t, ref OutBuffer buf) +{ + import dmd.dmangle; + return dmd.dmangle.mangleToBuffer(t, buf); +} + +void mangleToBuffer(Expression e, ref OutBuffer buf) +{ + import dmd.dmangle; + return dmd.dmangle.mangleToBuffer(e, buf); +} + +void mangleToBuffer(Dsymbol s, ref OutBuffer buf) +{ + import dmd.dmangle; + return dmd.dmangle.mangleToBuffer(s, buf); +} + +void mangleToBuffer(TemplateInstance ti, ref OutBuffer buf) +{ + import dmd.dmangle; + return dmd.dmangle.mangleToBuffer(ti, buf); +} + +/*********************************************************** + * dmodule.d + */ +void getLocalClasses(Module mod, ref ClassDeclarations aclasses) +{ + return dmd.dmodule.getLocalClasses(mod, aclasses); +} + +FuncDeclaration findGetMembers(ScopeDsymbol dsym) +{ + return dmd.dmodule.findGetMembers(dsym); +} + +/*********************************************************** + * doc.d + */ +void gendocfile(Module m, const char* ddoctext_ptr, size_t ddoctext_length, + const char* datetime, ErrorSink eSink, ref OutBuffer outbuf) +{ + import dmd.doc; + return dmd.doc.gendocfile(m, ddoctext_ptr, ddoctext_length, datetime, eSink, outbuf); +} + +/*********************************************************** + * dstruct.d + */ +FuncDeclaration search_toString(StructDeclaration sd) +{ + return dmd.dstruct.search_toString(sd); +} + +/*********************************************************** + * dsymbolsem.d + */ +void dsymbolSemantic(Dsymbol dsym, Scope* sc) +{ + import dmd.dsymbolsem; + return dmd.dsymbolsem.dsymbolSemantic(dsym, sc); +} + +void addMember(Dsymbol dsym, Scope* sc, ScopeDsymbol sds) +{ + import dmd.dsymbolsem; + return dmd.dsymbolsem.addMember(dsym, sc, sds); +} + +Dsymbol search(Dsymbol d, const ref Loc loc, Identifier ident, SearchOptFlags + flags = SearchOpt.all) +{ + import dmd.dsymbolsem; + return dmd.dsymbolsem.search(d, loc, ident, flags); +} + +void setScope(Dsymbol d, Scope* sc) +{ + import dmd.dsymbolsem; + return dmd.dsymbolsem.setScope(d, sc); +} + +void importAll(Dsymbol d, Scope* sc) +{ + import dmd.dsymbolsem; + return dmd.dsymbolsem.importAll(d, sc); +} + +/*********************************************************** + * dtemplate.d + */ +inout(Expression) isExpression(inout RootObject o) +{ + return dmd.dtemplate.isExpression(o); +} + +inout(Dsymbol) isDsymbol(inout RootObject o) +{ + return dmd.dtemplate.isDsymbol(o); +} + +inout(Type) isType(inout RootObject o) +{ + return dmd.dtemplate.isType(o); +} + +inout(Tuple) isTuple(inout RootObject o) +{ + return dmd.dtemplate.isTuple(o); +} + +inout(Parameter) isParameter(inout RootObject o) +{ + return dmd.dtemplate.isParameter(o); +} + +inout(TemplateParameter) isTemplateParameter(inout RootObject o) +{ + return dmd.dtemplate.isTemplateParameter(o); +} + +bool isError(const RootObject o) +{ + return dmd.dtemplate.isError(o); +} + +void printTemplateStats(bool listInstances, ErrorSink eSink) +{ + return dmd.dtemplate.printTemplateStats(listInstances, eSink); +} + +/*********************************************************** + * dtoh.d + */ +void genCppHdrFiles(ref Modules ms) +{ + import dmd.dtoh; + return dmd.dtoh.genCppHdrFiles(ms); +} + +/*********************************************************** + * expression.d + */ +void expandTuples(Expressions* exps, Identifiers* names = null) +{ + return dmd.expression.expandTuples(exps, names); +} + +/*********************************************************** + * expressionsem.d + */ +Expression expressionSemantic(Expression e, Scope* sc) +{ + import dmd.expressionsem; + return dmd.expressionsem.expressionSemantic(e, sc); +} + +/*********************************************************** + * funcsem.d + */ +bool functionSemantic(FuncDeclaration fd) +{ + import dmd.funcsem; + return dmd.funcsem.functionSemantic(fd); +} + +bool functionSemantic3(FuncDeclaration fd) +{ + import dmd.funcsem; + return dmd.funcsem.functionSemantic3(fd); +} + +/*********************************************************** + * hdrgen.d + */ +void genhdrfile(Module m, bool doFuncBodies, ref OutBuffer buf) +{ + import dmd.hdrgen; + return dmd.hdrgen.genhdrfile(m, doFuncBodies, buf); +} + +const(char)* toChars(const Statement s) +{ + import dmd.hdrgen; + return dmd.hdrgen.toChars(s); +} + +const(char)* toChars(const Expression e) +{ + import dmd.hdrgen; + return dmd.hdrgen.toChars(e); +} + +const(char)* toChars(const Initializer i) +{ + import dmd.hdrgen; + return dmd.hdrgen.toChars(i); +} + +const(char)* toChars(const Type t) +{ + import dmd.hdrgen; + return dmd.hdrgen.toChars(t); +} + +void moduleToBuffer(ref OutBuffer buf, bool vcg_ast, Module m) +{ + import dmd.hdrgen; + return dmd.hdrgen.moduleToBuffer(buf, vcg_ast, m); +} + +const(char)* parametersTypeToChars(ParameterList pl) +{ + import dmd.hdrgen; + return dmd.hdrgen.parametersTypeToChars(pl); +} + +/*********************************************************** + * iasm.d + */ +Statement asmSemantic(AsmStatement s, Scope *sc) +{ + import dmd.iasm; + return dmd.iasm.asmSemantic(s, sc); +} + +void asmSemantic(CAsmDeclaration d, Scope *sc) +{ + import dmd.iasm; + return dmd.iasm.asmSemantic(d, sc); +} + +/*********************************************************** + * iasmgcc.d + */ +Statement gccAsmSemantic(GccAsmStatement s, Scope *sc) +{ + import dmd.iasmgcc; + return dmd.iasmgcc.gccAsmSemantic(s, sc); +} + +void gccAsmSemantic(CAsmDeclaration d, Scope *sc) +{ + import dmd.iasmgcc; + return dmd.iasmgcc.gccAsmSemantic(d, sc); +} + +/*********************************************************** + * initsem.d + */ +Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, + NeedInterpret needInterpret) +{ + import dmd.initsem; + return dmd.initsem.initializerSemantic(init, sc, tx, needInterpret); +} + +Expression initializerToExpression(Initializer init, Type itype = null, const + bool isCfile = false) +{ + import dmd.initsem; + return dmd.initsem.initializerToExpression(init, itype, isCfile); +} + +/*********************************************************** + * json.d + */ +void json_generate(ref Modules modules, ref OutBuffer buf) +{ + import dmd.json; + return dmd.json.json_generate(modules, buf); +} + +JsonFieldFlags tryParseJsonField(const(char)* fieldName) +{ + import dmd.json; + return dmd.json.tryParseJsonField(fieldName); +} + +/*********************************************************** + * mtype.d + */ +AggregateDeclaration isAggregate(Type t) +{ + return dmd.mtype.isAggregate(t); +} + +/*********************************************************** + * optimize.d + */ +Expression optimize(Expression e, int result, bool keepLvalue = false) +{ + import dmd.optimize; + return dmd.optimize.optimize(e, result, keepLvalue); +} + +/*********************************************************** + * semantic2.d + */ +void semantic2(Dsymbol dsym, Scope* sc) +{ + import dmd.semantic2; + return dmd.semantic2.semantic2(dsym, sc); +} + +/*********************************************************** + * semantic3.d + */ +void semantic3(Dsymbol dsym, Scope* sc) +{ + import dmd.semantic3; + return dmd.semantic3.semantic3(dsym, sc); +} + +void semanticTypeInfoMembers(StructDeclaration sd) +{ + import dmd.semantic3; + return dmd.semantic3.semanticTypeInfoMembers(sd); +} + +/*********************************************************** + * statementsem.d + */ +Statement statementSemantic(Statement s, Scope* sc) +{ + import dmd.statementsem; + return dmd.statementsem.statementSemantic(s, sc); +} + +/*********************************************************** + * templateparamsem.d + */ +bool tpsemantic(TemplateParameter tp, Scope* sc, TemplateParameters* parameters) +{ + import dmd.templateparamsem; + return dmd.templateparamsem.tpsemantic(tp, sc, parameters); +} + +/*********************************************************** + * typesem.d + */ +bool hasPointers(Type t) +{ + import dmd.typesem; + return dmd.typesem.hasPointers(t); +} + +Type typeSemantic(Type type, const ref Loc loc, Scope* sc) +{ + import dmd.typesem; + return dmd.typesem.typeSemantic(type, loc, sc); +} + +Type trySemantic(Type type, const ref Loc loc, Scope* sc) +{ + import dmd.typesem; + return dmd.typesem.trySemantic(type, loc, sc); +} + +Type merge(Type type) +{ + import dmd.typesem; + return dmd.typesem.merge(type); +} + +Type merge2(Type type) +{ + import dmd.typesem; + return dmd.typesem.merge2(type); +} + +Expression defaultInit(Type mt, const ref Loc loc, const bool isCfile = false) +{ + import dmd.typesem; + return dmd.typesem.defaultInit(mt, loc, isCfile); +} + +Dsymbol toDsymbol(Type type, Scope* sc) +{ + import dmd.typesem; + return dmd.typesem.toDsymbol(type, sc); +} + +Covariant covariant(Type src, Type t, StorageClass* pstc = null, bool + cppCovariant = false) +{ + import dmd.typesem; + return dmd.typesem.covariant(src, t, pstc, cppCovariant); +} + +bool isBaseOf(Type tthis, Type t, int* poffset) +{ + import dmd.typesem; + return dmd.typesem.isBaseOf(tthis, t, poffset); +} + +bool equivalent(Type src, Type t) +{ + import dmd.typesem; + return dmd.typesem.equivalent(src, t); +} + +Type constOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.constOf(type); +} + +Type immutableOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.immutableOf(type); +} + +Type mutableOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.mutableOf(type); +} + +Type sharedOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.sharedOf(type); +} + +Type sharedConstOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.sharedConstOf(type); +} + +Type unSharedOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.unSharedOf(type); +} + +Type wildOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.wildOf(type); +} + +Type wildConstOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.wildConstOf(type); +} + +Type sharedWildOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.sharedWildOf(type); +} + +Type sharedWildConstOf(Type type) +{ + import dmd.typesem; + return dmd.typesem.sharedWildConstOf(type); +} + +Type castMod(Type type, MOD mod) +{ + import dmd.typesem; + return dmd.typesem.castMod(type, mod); +} + +Type addMod(Type type, MOD mod) +{ + import dmd.typesem; + return dmd.typesem.addMod(type, mod); +} + +Type addStorageClass(Type type, StorageClass stc) +{ + import dmd.typesem; + return dmd.typesem.addStorageClass(type, stc); +} + +Type pointerTo(Type type) +{ + import dmd.typesem; + return dmd.typesem.pointerTo(type); +} + +Type referenceTo(Type type) +{ + import dmd.typesem; + return dmd.typesem.referenceTo(type); +} + +/*********************************************************** + * typinf.d + */ +bool genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc) +{ + import dmd.typinf; + return dmd.typinf.genTypeInfo(e, loc, torig, sc); +} + +bool isSpeculativeType(Type t) +{ + import dmd.typinf; + return dmd.typinf.isSpeculativeType(t); +} + +bool builtinTypeInfo(Type t) +{ + import dmd.typinf; + return dmd.typinf.builtinTypeInfo(t); +} + +version (IN_LLVM) +{ + /*********************************************************** + * argtypes_aarch64.d + */ + TypeTuple toArgTypes_aarch64(Type t) + { + import dmd.argtypes_aarch64; + return dmd.argtypes_aarch64.toArgTypes_aarch64(t); + } + + bool isHFVA(Type t, int maxNumElements = 4, Type* rewriteType = null) + { + import dmd.argtypes_aarch64; + return dmd.argtypes_aarch64.isHFVA(t, maxNumElements, rewriteType); + } + + /*********************************************************** + * argtypes_sysv_x64.d + */ + TypeTuple toArgTypes_sysv_x64(Type t) + { + import dmd.argtypes_sysv_x64; + return dmd.argtypes_sysv_x64.toArgTypes_sysv_x64(t); + } + + /*********************************************************** + * argtypes_x86.d + */ + TypeTuple toArgTypes_x86(Type t) + { + import dmd.argtypes_x86; + return dmd.argtypes_x86.toArgTypes_x86(t); + } +} diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index a393da8..998beba9 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -30,8 +30,11 @@ class StructDeclaration; struct IntRange; struct AttributeViolation; -bool functionSemantic(FuncDeclaration* fd); -bool functionSemantic3(FuncDeclaration* fd); +namespace dmd +{ + bool functionSemantic(FuncDeclaration* fd); + bool functionSemantic3(FuncDeclaration* fd); +} //enum STC : ulong from astenums.d: diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index c3395a5..467e29f 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -50,7 +50,7 @@ import dmd.rootobject; import dmd.root.utf; import dmd.statement; import dmd.tokens; -import dmd.typesem : mutableOf, equivalent; +import dmd.typesem : mutableOf, equivalent, pointerTo; import dmd.utils : arrayCastBigEndian; import dmd.visitor; @@ -63,7 +63,7 @@ import dmd.visitor; * functions and may invoke a function that contains `ErrorStatement` in its body. * If that, the "CTFE failed because of previous errors" error is raised. */ -extern(C++) public Expression ctfeInterpret(Expression e) +public Expression ctfeInterpret(Expression e) { switch (e.op) { diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d index 1d01647..33428de 100644 --- a/gcc/d/dmd/dmangle.d +++ b/gcc/d/dmd/dmangle.d @@ -18,7 +18,7 @@ module dmd.dmangle; /****************************************************************************** * Returns exact mangled name of function. */ -extern (C++) const(char)* mangleExact(FuncDeclaration fd) +const(char)* mangleExact(FuncDeclaration fd) { //printf("mangleExact()\n"); if (!fd.mangleString) @@ -32,7 +32,7 @@ extern (C++) const(char)* mangleExact(FuncDeclaration fd) return fd.mangleString; } -extern (C++) void mangleToBuffer(Type t, ref OutBuffer buf) +void mangleToBuffer(Type t, ref OutBuffer buf) { //printf("mangleToBuffer t()\n"); if (t.deco) @@ -45,7 +45,7 @@ extern (C++) void mangleToBuffer(Type t, ref OutBuffer buf) } } -extern (C++) void mangleToBuffer(Expression e, ref OutBuffer buf) +void mangleToBuffer(Expression e, ref OutBuffer buf) { //printf("mangleToBuffer e()\n"); auto backref = Backref(null); @@ -53,7 +53,7 @@ extern (C++) void mangleToBuffer(Expression e, ref OutBuffer buf) e.accept(v); } -extern (C++) void mangleToBuffer(Dsymbol s, ref OutBuffer buf) +void mangleToBuffer(Dsymbol s, ref OutBuffer buf) { //printf("mangleToBuffer s(%s)\n", s.toChars()); auto backref = Backref(null); @@ -61,7 +61,7 @@ extern (C++) void mangleToBuffer(Dsymbol s, ref OutBuffer buf) s.accept(v); } -extern (C++) void mangleToBuffer(TemplateInstance ti, ref OutBuffer buf) +void mangleToBuffer(TemplateInstance ti, ref OutBuffer buf) { //printf("mangleToBuffer ti()\n"); auto backref = Backref(null); diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 6167e2a..07d5077 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -1300,7 +1300,7 @@ extern (C++) struct ModuleDeclaration * aclasses = array to fill in * Returns: array of local classes */ -extern (C++) void getLocalClasses(Module mod, ref ClassDeclarations aclasses) +void getLocalClasses(Module mod, ref ClassDeclarations aclasses) { //printf("members.length = %d\n", mod.members.length); int pushAddClassDg(size_t n, Dsymbol sm) @@ -1565,7 +1565,7 @@ private const(char)[] processSource (const(ubyte)[] src, Module mod) * const(MemberInfo)[] getMembers(string); * Returns NULL if not found */ -extern(C++) FuncDeclaration findGetMembers(ScopeDsymbol dsym) +FuncDeclaration findGetMembers(ScopeDsymbol dsym) { import dmd.opover : search_function; Dsymbol s = search_function(dsym, Id.getmembers); diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d index bcf358c..c00c1cc 100644 --- a/gcc/d/dmd/doc.d +++ b/gcc/d/dmd/doc.d @@ -382,7 +382,7 @@ immutable ddoc_decl_dd_e = ")\n"; * outbuf = append the Ddoc text to this */ public -extern(C++) void gendocfile(Module m, const char* ddoctext_ptr, size_t ddoctext_length, const char* datetime, ErrorSink eSink, ref OutBuffer outbuf) +void gendocfile(Module m, const char* ddoctext_ptr, size_t ddoctext_length, const char* datetime, ErrorSink eSink, ref OutBuffer outbuf) { gendocfile(m, ddoctext_ptr[0 .. ddoctext_length], datetime, eSink, outbuf); } diff --git a/gcc/d/dmd/doc.h b/gcc/d/dmd/doc.h index 71a66b9..1775e35 100644 --- a/gcc/d/dmd/doc.h +++ b/gcc/d/dmd/doc.h @@ -15,5 +15,8 @@ class Module; class ErrorSink; -void gendocfile(Module *m, const char *ddoctext_ptr, d_size_t ddoctext_length, - const char *datetime, ErrorSink *eSink, OutBuffer &outbuf); +namespace dmd +{ + void gendocfile(Module *m, const char *ddoctext_ptr, d_size_t ddoctext_length, + const char *datetime, ErrorSink *eSink, OutBuffer &outbuf); +} diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d index e02ba9a..76a26a2 100644 --- a/gcc/d/dmd/dscope.d +++ b/gcc/d/dmd/dscope.d @@ -34,6 +34,7 @@ import dmd.func; import dmd.globals; import dmd.id; import dmd.identifier; +import dmd.importc; import dmd.location; import dmd.common.outbuffer; import dmd.root.rmem; diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index 7546fb6..df4d07a 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -48,7 +48,7 @@ import dmd.visitor; * Returns: * FuncDeclaration of `toString()` if found, `null` if not */ -extern (C++) FuncDeclaration search_toString(StructDeclaration sd) +FuncDeclaration search_toString(StructDeclaration sd) { Dsymbol s = search_function(sd, Id.tostring); FuncDeclaration fd = s ? s.isFuncDeclaration() : null; diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index 5e7922e..b831c32 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -1105,6 +1105,7 @@ extern (C++) class Dsymbol : ASTNode inout(MixinDeclaration) isMixinDeclaration() inout { return null; } inout(StaticAssert) isStaticAssert() inout { return null; } inout(StaticIfDeclaration) isStaticIfDeclaration() inout { return null; } + inout(CAsmDeclaration) isCAsmDeclaration() inout { return null; } } /*********************************************************** @@ -1700,275 +1701,25 @@ extern (C++) final class DsymbolTable : RootObject } } -/********************************************** - * ImportC tag symbols sit in a parallel symbol table, - * so that this C code works: - * --- - * struct S { a; }; - * int S; - * struct S s; - * --- - * But there are relatively few such tag symbols, so that would be - * a waste of memory and complexity. An additional problem is we'd like the D side - * to find the tag symbols with ordinary lookup, not lookup in both - * tables, if the tag symbol is not conflicting with an ordinary symbol. - * The solution is to put the tag symbols that conflict into an associative - * array, indexed by the address of the ordinary symbol that conflicts with it. - * C has no modules, so this associative array is tagSymTab[] in ModuleDeclaration. - * A side effect of our approach is that D code cannot access a tag symbol that is - * hidden by an ordinary symbol. This is more of a theoretical problem, as nobody - * has mentioned it when importing C headers. If someone wants to do it, - * too bad so sad. Change the C code. - * This function fixes up the symbol table when faced with adding a new symbol - * `s` when there is an existing symbol `s2` with the same name. - * C also allows forward and prototype declarations of tag symbols, - * this function merges those. - * Params: - * sc = context - * s = symbol to add to symbol table - * s2 = existing declaration - * sds = symbol table - * Returns: - * if s and s2 are successfully put in symbol table then return the merged symbol, - * null if they conflict - */ -Dsymbol handleTagSymbols(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds) -{ - enum log = false; - if (log) printf("handleTagSymbols('%s') add %p existing %p\n", s.toChars(), s, s2); - if (log) printf(" add %s %s, existing %s %s\n", s.kind(), s.toChars(), s2.kind(), s2.toChars()); - auto sd = s.isScopeDsymbol(); // new declaration - auto sd2 = s2.isScopeDsymbol(); // existing declaration - - static if (log) void print(EnumDeclaration sd) - { - printf("members: %p\n", sd.members); - printf("symtab: %p\n", sd.symtab); - printf("endlinnum: %d\n", sd.endlinnum); - printf("type: %s\n", sd.type.toChars()); - printf("memtype: %s\n", sd.memtype.toChars()); - } - - if (!sd2) - { - /* Look in tag table - */ - if (log) printf(" look in tag table\n"); - if (auto p = cast(void*)s2 in sc._module.tagSymTab) - { - Dsymbol s2tag = *p; - sd2 = s2tag.isScopeDsymbol(); - assert(sd2); // only tags allowed in tag symbol table - } - } - - if (sd && sd2) // `s` is a tag, `sd2` is the same tag - { - if (log) printf(" tag is already defined\n"); - - if (sd.kind() != sd2.kind()) // being enum/struct/union must match - return null; // conflict - - /* Not a redeclaration if one is a forward declaration. - * Move members to the first declared type, which is sd2. - */ - if (sd2.members) - { - if (!sd.members) - return sd2; // ignore the sd redeclaration - } - else if (sd.members) - { - sd2.members = sd.members; // transfer definition to sd2 - sd.members = null; - if (auto ed2 = sd2.isEnumDeclaration()) - { - auto ed = sd.isEnumDeclaration(); - if (ed.memtype != ed2.memtype) - return null; // conflict - - // transfer ed's members to sd2 - ed2.members.foreachDsymbol( (s) - { - if (auto em = s.isEnumMember()) - em.ed = ed2; - }); - - ed2.type = ed.type; - ed2.memtype = ed.memtype; - ed2.added = false; - } - return sd2; - } - else - return sd2; // ignore redeclaration - } - else if (sd) // `s` is a tag, `s2` is not - { - if (log) printf(" s is tag, s2 is not\n"); - /* add `s` as tag indexed by s2 - */ - sc._module.tagSymTab[cast(void*)s2] = s; - return s; - } - else if (s2 is sd2) // `s2` is a tag, `s` is not - { - if (log) printf(" s2 is tag, s is not\n"); - /* replace `s2` in symbol table with `s`, - * then add `s2` as tag indexed by `s` - */ - sds.symtab.update(s); - sc._module.tagSymTab[cast(void*)s] = s2; - return s; - } - // neither s2 nor s is a tag - if (log) printf(" collision\n"); - return null; -} - - -/********************************************** - * ImportC allows redeclarations of C variables, functions and typedefs. - * extern int x; - * int x = 3; - * and: - * extern void f(); - * void f() { } - * Attempt to merge them. - * Params: - * sc = context - * s = symbol to add to symbol table - * s2 = existing declaration - * sds = symbol table - * Returns: - * if s and s2 are successfully put in symbol table then return the merged symbol, - * null if they conflict +/** + * ImportC global `asm` definition. */ -Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds) +extern (C++) final class CAsmDeclaration : Dsymbol { - enum log = false; - if (log) printf("handleSymbolRedeclarations('%s')\n", s.toChars()); - if (log) printf(" add %s %s, existing %s %s\n", s.kind(), s.toChars(), s2.kind(), s2.toChars()); - - static Dsymbol collision() + Expression code; + extern (D) this(Expression e) nothrow @safe { - if (log) printf(" collision\n"); - return null; - } - /* - Handle merging declarations with asm("foo") and their definitions - */ - static void mangleWrangle(Declaration oldDecl, Declaration newDecl) - { - if (oldDecl && newDecl) - { - newDecl.mangleOverride = oldDecl.mangleOverride ? oldDecl.mangleOverride : null; - } + super(); + this.code = e; } - auto vd = s.isVarDeclaration(); // new declaration - auto vd2 = s2.isVarDeclaration(); // existing declaration - - if (vd && vd.isCmacro()) - return vd2; - - assert(!(vd2 && vd2.isCmacro())); - - if (vd && vd2) + override inout(CAsmDeclaration) isCAsmDeclaration() inout nothrow { - /* if one is `static` and the other isn't, the result is undefined - * behavior, C11 6.2.2.7 - */ - if ((vd.storage_class ^ vd2.storage_class) & STC.static_) - return collision(); - - const i1 = vd._init && ! vd._init.isVoidInitializer(); - const i2 = vd2._init && !vd2._init.isVoidInitializer(); - - if (i1 && i2) - return collision(); // can't both have initializers - - mangleWrangle(vd2, vd); - - if (i1) // vd is the definition - { - vd2.storage_class |= STC.extern_; // so toObjFile() won't emit it - sds.symtab.update(vd); // replace vd2 with the definition - return vd; - } - - /* BUG: the types should match, which needs semantic() to be run on it - * extern int x; - * int x; // match - * typedef int INT; - * INT x; // match - * long x; // collision - * We incorrectly ignore these collisions - */ - return vd2; - } - - auto fd = s.isFuncDeclaration(); // new declaration - auto fd2 = s2.isFuncDeclaration(); // existing declaration - if (fd && fd2) - { - /* if one is `static` and the other isn't, the result is undefined - * behavior, C11 6.2.2.7 - * However, match what gcc allows: - * static int sun1(); int sun1() { return 0; } - * and: - * static int sun2() { return 0; } int sun2(); - * Both produce a static function. - * - * Both of these should fail: - * int sun3(); static int sun3() { return 0; } - * and: - * int sun4() { return 0; } static int sun4(); - */ - // if adding `static` - if ( fd.storage_class & STC.static_ && - !(fd2.storage_class & STC.static_)) - { - return collision(); - } - - if (fd.fbody && fd2.fbody) - return collision(); // can't both have bodies - - mangleWrangle(fd2, fd); - - if (fd.fbody) // fd is the definition - { - if (log) printf(" replace existing with new\n"); - sds.symtab.update(fd); // replace fd2 in symbol table with fd - fd.overnext = fd2; - - /* If fd2 is covering a tag symbol, then fd has to cover the same one - */ - auto ps = cast(void*)fd2 in sc._module.tagSymTab; - if (ps) - sc._module.tagSymTab[cast(void*)fd] = *ps; - - return fd; - } - - /* Just like with VarDeclaration, the types should match, which needs semantic() to be run on it. - * FuncDeclaration::semantic() detects this, but it relies on .overnext being set. - */ - fd2.overloadInsert(fd); - - return fd2; + return this; } - auto td = s.isAliasDeclaration(); // new declaration - auto td2 = s2.isAliasDeclaration(); // existing declaration - if (td && td2) + override void accept(Visitor v) { - /* BUG: just like with variables and functions, the types should match, which needs semantic() to be run on it. - * FuncDeclaration::semantic2() can detect this, but it relies overnext being set. - */ - return td2; + v.visit(this); } - - return collision(); } diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h index db23627..f845435 100644 --- a/gcc/d/dmd/dsymbol.h +++ b/gcc/d/dmd/dsymbol.h @@ -73,6 +73,7 @@ class AliasAssign; class OverloadSet; class StaticAssert; class StaticIfDeclaration; +class CAsmDeclaration; struct AA; #ifdef IN_GCC typedef union tree_node Symbol; @@ -95,9 +96,16 @@ enum class ThreeState : uint8_t yes, // value is true }; -void dsymbolSemantic(Dsymbol *dsym, Scope *sc); -void semantic2(Dsymbol *dsym, Scope *sc); -void semantic3(Dsymbol *dsym, Scope* sc); +namespace dmd +{ + void dsymbolSemantic(Dsymbol *dsym, Scope *sc); + void semantic2(Dsymbol *dsym, Scope *sc); + void semantic3(Dsymbol *dsym, Scope* sc); + // in iasm.d + void asmSemantic(CAsmDeclaration *ad, Scope *sc); + // in iasmgcc.d + void gccAsmSemantic(CAsmDeclaration *ad, Scope *sc); +} struct Visibility { @@ -315,6 +323,7 @@ public: virtual MixinDeclaration *isMixinDeclaration() { return NULL; } virtual StaticAssert *isStaticAssert() { return NULL; } virtual StaticIfDeclaration *isStaticIfDeclaration() { return NULL; } + virtual CAsmDeclaration *isCAsmDeclaration() { return NULL; } void accept(Visitor *v) override { v->visit(this); } }; @@ -404,6 +413,15 @@ public: ExpressionDsymbol *isExpressionDsymbol() override { return this; } }; +class CAsmDeclaration final : public Dsymbol +{ +public: + Expression *code; // string expression + + CAsmDeclaration *isCAsmDeclaration() override { return this; } + void accept(Visitor *v) override { v->visit(this); } +}; + // Table of Dsymbol's class DsymbolTable final : public RootObject @@ -425,7 +443,10 @@ public: size_t length() const; }; -void addMember(Dsymbol *dsym, Scope *sc, ScopeDsymbol *sds); -Dsymbol *search(Dsymbol *d, const Loc &loc, Identifier *ident, SearchOptFlags flags = (SearchOptFlags)SearchOpt::localsOnly); -void setScope(Dsymbol *d, Scope *sc); -void importAll(Dsymbol *d, Scope *sc); +namespace dmd +{ + void addMember(Dsymbol *dsym, Scope *sc, ScopeDsymbol *sds); + Dsymbol *search(Dsymbol *d, const Loc &loc, Identifier *ident, SearchOptFlags flags = (SearchOptFlags)SearchOpt::localsOnly); + void setScope(Dsymbol *d, Scope *sc); + void importAll(Dsymbol *d, Scope *sc); +} diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 4a4d82f..c15d925 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -85,7 +85,7 @@ enum LOG = false; /************************************* * Does semantic analysis on the public face of declarations. */ -extern(C++) void dsymbolSemantic(Dsymbol dsym, Scope* sc) +void dsymbolSemantic(Dsymbol dsym, Scope* sc) { scope v = new DsymbolSemanticVisitor(sc); dsym.accept(v); @@ -1440,6 +1440,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor assert(dsym._linkage == LINK.c); } + override void visit(CAsmDeclaration dsym) + { + if (dsym.semanticRun >= PASS.semanticdone) + return; + import dmd.iasm : asmSemantic; + asmSemantic(dsym, sc); + dsym.semanticRun = PASS.semanticdone; + } + override void visit(BitFieldDeclaration dsym) { //printf("BitField::semantic('%s')\n", dsym.toChars()); @@ -4059,7 +4068,7 @@ Params: sc = scope where the dsymbol is declared sds = ScopeDsymbol where dsym is inserted */ -extern(C++) void addMember(Dsymbol dsym, Scope* sc, ScopeDsymbol sds) +void addMember(Dsymbol dsym, Scope* sc, ScopeDsymbol sds) { auto addMemberVisitor = new AddMemberVisitor(sc, sds); dsym.accept(addMemberVisitor); @@ -5979,7 +5988,7 @@ void checkPrintfScanfSignature(FuncDeclaration funcdecl, TypeFunction f, Scope* * Returns: * null if not found */ -extern(C++) Dsymbol search(Dsymbol d, const ref Loc loc, Identifier ident, SearchOptFlags flags = SearchOpt.all) +Dsymbol search(Dsymbol d, const ref Loc loc, Identifier ident, SearchOptFlags flags = SearchOpt.all) { scope v = new SearchVisitor(loc, ident, flags); d.accept(v); @@ -6621,7 +6630,7 @@ private extern(C++) class SearchVisitor : Visitor * 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) +void setScope(Dsymbol d, Scope* sc) { scope setScopeVisitor = new SetScopeVisitor(sc); d.accept(setScopeVisitor); @@ -6764,7 +6773,7 @@ private extern(C++) class SetScopeVisitor : Visitor } } -extern(C++) void importAll(Dsymbol d, Scope* sc) +void importAll(Dsymbol d, Scope* sc) { scope iav = new ImportAllVisitor(sc); d.accept(iav); diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index 4a195e3..165a010 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -96,7 +96,7 @@ pure nothrow @nogc @safe * These functions substitute for dynamic_cast. dynamic_cast does not work * on earlier versions of gcc. */ -extern (C++) inout(Expression) isExpression(inout RootObject o) +inout(Expression) isExpression(inout RootObject o) { //return dynamic_cast<Expression *>(o); if (!o || o.dyncast() != DYNCAST.expression) @@ -104,7 +104,7 @@ extern (C++) inout(Expression) isExpression(inout RootObject o) return cast(inout(Expression))o; } -extern (C++) inout(Dsymbol) isDsymbol(inout RootObject o) +inout(Dsymbol) isDsymbol(inout RootObject o) { //return dynamic_cast<Dsymbol *>(o); if (!o || o.dyncast() != DYNCAST.dsymbol) @@ -112,7 +112,7 @@ extern (C++) inout(Dsymbol) isDsymbol(inout RootObject o) return cast(inout(Dsymbol))o; } -extern (C++) inout(Type) isType(inout RootObject o) +inout(Type) isType(inout RootObject o) { //return dynamic_cast<Type *>(o); if (!o || o.dyncast() != DYNCAST.type) @@ -120,7 +120,7 @@ extern (C++) inout(Type) isType(inout RootObject o) return cast(inout(Type))o; } -extern (C++) inout(Tuple) isTuple(inout RootObject o) +inout(Tuple) isTuple(inout RootObject o) { //return dynamic_cast<Tuple *>(o); if (!o || o.dyncast() != DYNCAST.tuple) @@ -128,7 +128,7 @@ extern (C++) inout(Tuple) isTuple(inout RootObject o) return cast(inout(Tuple))o; } -extern (C++) inout(Parameter) isParameter(inout RootObject o) +inout(Parameter) isParameter(inout RootObject o) { //return dynamic_cast<Parameter *>(o); if (!o || o.dyncast() != DYNCAST.parameter) @@ -136,7 +136,7 @@ extern (C++) inout(Parameter) isParameter(inout RootObject o) return cast(inout(Parameter))o; } -extern (C++) inout(TemplateParameter) isTemplateParameter(inout RootObject o) +inout(TemplateParameter) isTemplateParameter(inout RootObject o) { if (!o || o.dyncast() != DYNCAST.templateparameter) return null; @@ -146,7 +146,7 @@ extern (C++) inout(TemplateParameter) isTemplateParameter(inout RootObject o) /************************************** * Is this Object an error? */ -extern (C++) bool isError(const RootObject o) +bool isError(const RootObject o) { if (const t = isType(o)) return (t.ty == Terror); @@ -6311,7 +6311,7 @@ struct TemplateStats * listInstances = list instances of templates * eSink = where the print is sent */ -extern (C++) void printTemplateStats(bool listInstances, ErrorSink eSink) +void printTemplateStats(bool listInstances, ErrorSink eSink) { static struct TemplateDeclarationStats { diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d index 4a1ff05..2e2ced4 100644 --- a/gcc/d/dmd/dtoh.d +++ b/gcc/d/dmd/dtoh.d @@ -54,7 +54,7 @@ import dmd.utils; * - ignored declarations are mentioned in a comment if `global.params.doCxxHdrGeneration` * is set to `CxxHeaderMode.verbose` */ -extern(C++) void genCppHdrFiles(ref Modules ms) +void genCppHdrFiles(ref Modules ms) { initialize(); diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 82de837..bc907cf 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -108,7 +108,7 @@ inout(Expression) lastComma(inout Expression e) * exps = array of Expressions * names = optional array of names corresponding to Expressions */ -extern (C++) void expandTuples(Expressions* exps, Identifiers* names = null) +void expandTuples(Expressions* exps, Identifiers* names = null) { //printf("expandTuples()\n"); if (exps is null) diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index 8dbb4a6..3bd8ca7 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -46,16 +46,19 @@ typedef union tree_node Symbol; struct Symbol; // back end symbol #endif -// in expressionsem.d -Expression *expressionSemantic(Expression *e, Scope *sc); -// in typesem.d -Expression *defaultInit(Type *mt, const Loc &loc, const bool isCfile = false); - -// Entry point for CTFE. -// A compile-time result is required. Give an error if not possible -Expression *ctfeInterpret(Expression *e); -void expandTuples(Expressions *exps, Identifiers *names = nullptr); -Expression *optimize(Expression *exp, int result, bool keepLvalue = false); +namespace dmd +{ + // in expressionsem.d + Expression *expressionSemantic(Expression *e, Scope *sc); + // in typesem.d + Expression *defaultInit(Type *mt, const Loc &loc, const bool isCfile = false); + + // Entry point for CTFE. + // A compile-time result is required. Give an error if not possible + Expression *ctfeInterpret(Expression *e); + void expandTuples(Expressions *exps, Identifiers *names = nullptr); + Expression *optimize(Expression *exp, int result, bool keepLvalue = false); +} typedef unsigned char OwnedBy; enum diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 9028ba1..cc589b9 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -5023,7 +5023,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); checkFunctionAttributes(exp, sc, f); - checkAccess(cd, exp.loc, sc, f); + if (!checkSymbolAccess(sc, f)) + { + error(exp.loc, "%s `%s` is not accessible from module `%s`", + f.kind(), f.toPrettyChars(), sc._module.toChars); + return setError(); + } TypeFunction tf = f.type.isTypeFunction(); if (!exp.arguments) @@ -6463,7 +6468,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); checkFunctionAttributes(exp, sc, exp.f); - checkAccess(exp.loc, sc, null, exp.f); + if (!checkSymbolAccess(sc, exp.f)) + { + error(exp.loc, "%s `%s` is not accessible from module `%s`", + exp.f.kind(), exp.f.toPrettyChars(), sc._module.toChars); + return setError(); + } exp.e1 = new DotVarExp(exp.e1.loc, exp.e1, exp.f, false); exp.e1 = exp.e1.expressionSemantic(sc); @@ -6649,7 +6659,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor assert(exp.f); tiargs = null; - if (exp.f.overnext) + if (ve.hasOverloads && exp.f.overnext) exp.f = resolveFuncCall(exp.loc, sc, exp.f, tiargs, null, exp.argumentList, FuncResolveFlag.overloadOnly); else { @@ -14193,7 +14203,7 @@ Expression binSemanticProp(BinExp e, Scope* sc) } // entrypoint for semantic ExpressionSemanticVisitor -extern (C++) Expression expressionSemantic(Expression e, Scope* sc) +Expression expressionSemantic(Expression e, Scope* sc) { scope v = new ExpressionSemanticVisitor(sc); e.accept(v); @@ -14211,8 +14221,10 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) // symbol.mangleof // return mangleof as an Expression - static Expression dotMangleof(const ref Loc loc, Scope* sc, Dsymbol ds) + static Expression dotMangleof(const ref Loc loc, Scope* sc, Dsymbol ds, bool hasOverloads) { + Expression e; + assert(ds); if (auto f = ds.isFuncDeclaration()) { @@ -14224,24 +14236,40 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) error(loc, "%s `%s` cannot retrieve its `.mangleof` while inferring attributes", f.kind, f.toPrettyChars); return ErrorExp.get(); } + + if (!hasOverloads) + e = StringExp.create(loc, mangleExact(f)); } - OutBuffer buf; - mangleToBuffer(ds, buf); - Expression e = new StringExp(loc, buf.extractSlice()); + + if (!e) + { + OutBuffer buf; + mangleToBuffer(ds, buf); + e = new StringExp(loc, buf.extractSlice()); + } + return e.expressionSemantic(sc); } Dsymbol ds; switch (exp.e1.op) { - case EXP.scope_: return dotMangleof(exp.loc, sc, exp.e1.isScopeExp().sds); - case EXP.variable: return dotMangleof(exp.loc, sc, exp.e1.isVarExp().var); - case EXP.dotVariable: return dotMangleof(exp.loc, sc, exp.e1.isDotVarExp().var); - case EXP.overloadSet: return dotMangleof(exp.loc, sc, exp.e1.isOverExp().vars); + case EXP.scope_: return dotMangleof(exp.loc, sc, exp.e1.isScopeExp().sds, false); + case EXP.overloadSet: return dotMangleof(exp.loc, sc, exp.e1.isOverExp().vars, false); + case EXP.variable: + { + VarExp ve = exp.e1.isVarExp(); + return dotMangleof(exp.loc, sc, ve.var, ve.hasOverloads); + } + case EXP.dotVariable: + { + DotVarExp dve = exp.e1.isDotVarExp(); + return dotMangleof(exp.loc, sc, dve.var, dve.hasOverloads); + } case EXP.template_: { TemplateExp te = exp.e1.isTemplateExp(); - return dotMangleof(exp.loc, sc, ds = te.fd ? te.fd.isDsymbol() : te.td); + return dotMangleof(exp.loc, sc, ds = te.fd ? te.fd.isDsymbol() : te.td, false); } default: diff --git a/gcc/d/dmd/funcsem.d b/gcc/d/dmd/funcsem.d index 9e706ee..49da6b2 100644 --- a/gcc/d/dmd/funcsem.d +++ b/gcc/d/dmd/funcsem.d @@ -1042,7 +1042,6 @@ Ldone: * false if any errors exist in the signature. */ public -extern (C++) bool functionSemantic(FuncDeclaration fd) { //printf("functionSemantic() %p %s\n", this, toChars()); @@ -1101,7 +1100,6 @@ bool functionSemantic(FuncDeclaration fd) * Returns false if any errors exist in the body. */ public -extern (C++) bool functionSemantic3(FuncDeclaration fd) { if (fd.semanticRun < PASS.semantic3 && fd._scope) diff --git a/gcc/d/dmd/gluelayer.d b/gcc/d/dmd/gluelayer.d index b3980eb..a3a3bd0 100644 --- a/gcc/d/dmd/gluelayer.d +++ b/gcc/d/dmd/gluelayer.d @@ -30,19 +30,9 @@ version (NoBackend) struct TYPE; alias type = TYPE; - extern (C++) + extern(C++) abstract class ObjcGlue { - // iasm - Statement asmSemantic(AsmStatement s, Scope* sc) - { - sc.func.hasReturnExp = 8; - return null; - } - - extern(C++) abstract class ObjcGlue - { - static void initialize() {} - } + static void initialize() {} } } else version (IN_GCC) @@ -53,11 +43,6 @@ else version (IN_GCC) alias code = tree_node; alias type = tree_node; - extern (C++) - { - Statement asmSemantic(AsmStatement s, Scope* sc); - } - // stubs extern(C++) abstract class ObjcGlue { @@ -70,6 +55,5 @@ else public import dmd.backend.type : type; public import dmd.backend.el : elem; public import dmd.backend.code_x86 : code; - public import dmd.iasm : asmSemantic; public import dmd.objc_glue : ObjcGlue; } diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index e4cbcc5..8eef799 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -83,7 +83,7 @@ enum TEST_EMIT_ALL = 0; * doFuncBodies = generate function definitions rather than just declarations * buf = buffer to write the data to */ -extern (C++) void genhdrfile(Module m, bool doFuncBodies, ref OutBuffer buf) +void genhdrfile(Module m, bool doFuncBodies, ref OutBuffer buf) { buf.doindent = 1; buf.printf("// D import file generated from '%s'", m.srcfile.toChars()); @@ -103,7 +103,7 @@ extern (C++) void genhdrfile(Module m, bool doFuncBodies, ref OutBuffer buf) * Returns: * 0-terminated string */ -public extern (C++) const(char)* toChars(const Statement s) +public const(char)* toChars(const Statement s) { HdrGenState hgs; OutBuffer buf; @@ -112,7 +112,7 @@ public extern (C++) const(char)* toChars(const Statement s) return buf.extractSlice().ptr; } -public extern (C++) const(char)* toChars(const Expression e) +public const(char)* toChars(const Expression e) { HdrGenState hgs; OutBuffer buf; @@ -120,7 +120,7 @@ public extern (C++) const(char)* toChars(const Expression e) return buf.extractChars(); } -public extern (C++) const(char)* toChars(const Initializer i) +public const(char)* toChars(const Initializer i) { OutBuffer buf; HdrGenState hgs; @@ -128,7 +128,7 @@ public extern (C++) const(char)* toChars(const Initializer i) return buf.extractChars(); } -public extern (C++) const(char)* toChars(const Type t) +public const(char)* toChars(const Type t) { OutBuffer buf; buf.reserve(16); @@ -154,7 +154,7 @@ public const(char)[] toString(const Initializer i) * vcg_ast = write out codegen ast * m = module to visit all members of. */ -extern (C++) void moduleToBuffer(ref OutBuffer buf, bool vcg_ast, Module m) +void moduleToBuffer(ref OutBuffer buf, bool vcg_ast, Module m) { HdrGenState hgs; hgs.fullDump = true; @@ -3418,7 +3418,7 @@ void arrayObjectsToBuffer(ref OutBuffer buf, Objects* objects) * pl = parameter list to print * Returns: Null-terminated string representing parameters. */ -extern (C++) const(char)* parametersTypeToChars(ParameterList pl) +const(char)* parametersTypeToChars(ParameterList pl) { OutBuffer buf; HdrGenState hgs; diff --git a/gcc/d/dmd/hdrgen.h b/gcc/d/dmd/hdrgen.h index e0a2046..14793ad 100644 --- a/gcc/d/dmd/hdrgen.h +++ b/gcc/d/dmd/hdrgen.h @@ -18,12 +18,15 @@ class Initializer; class Module; class Statement; -void genhdrfile(Module *m, bool doFuncBodies, OutBuffer &buf); -void genCppHdrFiles(Modules &ms); -void moduleToBuffer(OutBuffer& buf, bool vcg_ast, Module *m); -const char *parametersTypeToChars(ParameterList pl); +namespace dmd +{ + void genhdrfile(Module *m, bool doFuncBodies, OutBuffer &buf); + void genCppHdrFiles(Modules &ms); + void moduleToBuffer(OutBuffer& buf, bool vcg_ast, Module *m); + const char *parametersTypeToChars(ParameterList pl); -const char* toChars(const Expression* const e); -const char* toChars(const Initializer* const i); -const char* toChars(const Statement* const s); -const char* toChars(const Type* const t); + const char* toChars(const Expression* const e); + const char* toChars(const Initializer* const i); + const char* toChars(const Statement* const s); + const char* toChars(const Type* const t); +} diff --git a/gcc/d/dmd/iasm.d b/gcc/d/dmd/iasm.d index 24a4513..1399ac2 100644 --- a/gcc/d/dmd/iasm.d +++ b/gcc/d/dmd/iasm.d @@ -16,6 +16,7 @@ module dmd.iasm; import core.stdc.stdio; import dmd.dscope; +import dmd.dsymbol; import dmd.expression; import dmd.func; import dmd.mtype; @@ -23,7 +24,10 @@ import dmd.tokens; import dmd.statement; import dmd.statementsem; -version (IN_GCC) +version (NoBackend) +{ +} +else version (IN_GCC) { import dmd.iasmgcc; } @@ -35,7 +39,7 @@ else /************************ AsmStatement ***************************************/ -extern(C++) Statement asmSemantic(AsmStatement s, Scope *sc) +Statement asmSemantic(AsmStatement s, Scope *sc) { //printf("AsmStatement.semantic()\n"); @@ -48,7 +52,11 @@ extern(C++) Statement asmSemantic(AsmStatement s, Scope *sc) // Assume assembler code takes care of setting the return value sc.func.hasReturnExp |= 8; - version (MARS) + version (NoBackend) + { + return null; + } + else version (MARS) { /* If it starts with a string literal, it's gcc inline asm */ @@ -78,3 +86,21 @@ extern(C++) Statement asmSemantic(AsmStatement s, Scope *sc) return new ErrorStatement(); } } + +/************************ CAsmDeclaration ************************************/ + +void asmSemantic(CAsmDeclaration ad, Scope *sc) +{ + version (NoBackend) + { + } + else version (IN_GCC) + { + return gccAsmSemantic(ad, sc); + } + else + { + import dmd.errors : error; + error(ad.code.loc, "Gnu Asm not supported - compile this file with gcc or clang"); + } +} diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d index db51e73..4b1b2e7 100644 --- a/gcc/d/dmd/iasmgcc.d +++ b/gcc/d/dmd/iasmgcc.d @@ -16,6 +16,7 @@ import core.stdc.string; import dmd.arraytypes; import dmd.astcodegen; import dmd.dscope; +import dmd.dsymbol; import dmd.errors; import dmd.errorsink; import dmd.expression; @@ -299,7 +300,7 @@ Ldone: * Returns: * the completed gcc asm statement, or null if errors occurred */ -extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc) +public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc) { //printf("GccAsmStatement.semantic()\n"); const bool doUnittests = global.params.parsingUnittestsRequired(); @@ -382,6 +383,26 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc) return s; } +/*********************************** + * Run semantic analysis on an CAsmDeclaration. + * Params: + * ad = asm declaration + * sc = the scope where the asm declaration is located + */ +public void gccAsmSemantic(CAsmDeclaration ad, Scope *sc) +{ + import dmd.typesem : pointerTo; + ad.code = semanticString(sc, ad.code, "asm definition"); + ad.code.type = ad.code.type.nextOf().pointerTo(); + + // Asm definition always needs emitting into the root module. + import dmd.dmodule : Module; + if (sc._module && sc._module.isRoot()) + return; + if (Module m = Module.rootModule) + m.members.push(ad); +} + unittest { import dmd.mtype : TypeBasic; diff --git a/gcc/d/dmd/importc.d b/gcc/d/dmd/importc.d index 69a85ce..e4d5aa2 100644 --- a/gcc/d/dmd/importc.d +++ b/gcc/d/dmd/importc.d @@ -366,3 +366,276 @@ bool cTypeEquivalence(Type t1, Type t2) return false; } + +/********************************************** + * ImportC tag symbols sit in a parallel symbol table, + * so that this C code works: + * --- + * struct S { a; }; + * int S; + * struct S s; + * --- + * But there are relatively few such tag symbols, so that would be + * a waste of memory and complexity. An additional problem is we'd like the D side + * to find the tag symbols with ordinary lookup, not lookup in both + * tables, if the tag symbol is not conflicting with an ordinary symbol. + * The solution is to put the tag symbols that conflict into an associative + * array, indexed by the address of the ordinary symbol that conflicts with it. + * C has no modules, so this associative array is tagSymTab[] in ModuleDeclaration. + * A side effect of our approach is that D code cannot access a tag symbol that is + * hidden by an ordinary symbol. This is more of a theoretical problem, as nobody + * has mentioned it when importing C headers. If someone wants to do it, + * too bad so sad. Change the C code. + * This function fixes up the symbol table when faced with adding a new symbol + * `s` when there is an existing symbol `s2` with the same name. + * C also allows forward and prototype declarations of tag symbols, + * this function merges those. + * Params: + * sc = context + * s = symbol to add to symbol table + * s2 = existing declaration + * sds = symbol table + * Returns: + * if s and s2 are successfully put in symbol table then return the merged symbol, + * null if they conflict + */ +Dsymbol handleTagSymbols(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds) +{ + enum log = false; + if (log) printf("handleTagSymbols('%s') add %p existing %p\n", s.toChars(), s, s2); + if (log) printf(" add %s %s, existing %s %s\n", s.kind(), s.toChars(), s2.kind(), s2.toChars()); + auto sd = s.isScopeDsymbol(); // new declaration + auto sd2 = s2.isScopeDsymbol(); // existing declaration + + static if (log) void print(EnumDeclaration sd) + { + printf("members: %p\n", sd.members); + printf("symtab: %p\n", sd.symtab); + printf("endlinnum: %d\n", sd.endlinnum); + printf("type: %s\n", sd.type.toChars()); + printf("memtype: %s\n", sd.memtype.toChars()); + } + + if (!sd2) + { + /* Look in tag table + */ + if (log) printf(" look in tag table\n"); + if (auto p = cast(void*)s2 in sc._module.tagSymTab) + { + Dsymbol s2tag = *p; + sd2 = s2tag.isScopeDsymbol(); + assert(sd2); // only tags allowed in tag symbol table + } + } + + if (sd && sd2) // `s` is a tag, `sd2` is the same tag + { + if (log) printf(" tag is already defined\n"); + + if (sd.kind() != sd2.kind()) // being enum/struct/union must match + return null; // conflict + + /* Not a redeclaration if one is a forward declaration. + * Move members to the first declared type, which is sd2. + */ + if (sd2.members) + { + if (!sd.members) + return sd2; // ignore the sd redeclaration + } + else if (sd.members) + { + sd2.members = sd.members; // transfer definition to sd2 + sd.members = null; + if (auto ed2 = sd2.isEnumDeclaration()) + { + auto ed = sd.isEnumDeclaration(); + if (ed.memtype != ed2.memtype) + return null; // conflict + + // transfer ed's members to sd2 + ed2.members.foreachDsymbol( (s) + { + if (auto em = s.isEnumMember()) + em.ed = ed2; + }); + + ed2.type = ed.type; + ed2.memtype = ed.memtype; + ed2.added = false; + } + return sd2; + } + else + return sd2; // ignore redeclaration + } + else if (sd) // `s` is a tag, `s2` is not + { + if (log) printf(" s is tag, s2 is not\n"); + /* add `s` as tag indexed by s2 + */ + sc._module.tagSymTab[cast(void*)s2] = s; + return s; + } + else if (s2 is sd2) // `s2` is a tag, `s` is not + { + if (log) printf(" s2 is tag, s is not\n"); + /* replace `s2` in symbol table with `s`, + * then add `s2` as tag indexed by `s` + */ + sds.symtab.update(s); + sc._module.tagSymTab[cast(void*)s] = s2; + return s; + } + // neither s2 nor s is a tag + if (log) printf(" collision\n"); + return null; +} + + +/********************************************** + * ImportC allows redeclarations of C variables, functions and typedefs. + * extern int x; + * int x = 3; + * and: + * extern void f(); + * void f() { } + * Attempt to merge them. + * Params: + * sc = context + * s = symbol to add to symbol table + * s2 = existing declaration + * sds = symbol table + * Returns: + * if s and s2 are successfully put in symbol table then return the merged symbol, + * null if they conflict + */ +Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsymbol sds) +{ + enum log = false; + if (log) printf("handleSymbolRedeclarations('%s')\n", s.toChars()); + if (log) printf(" add %s %s, existing %s %s\n", s.kind(), s.toChars(), s2.kind(), s2.toChars()); + + static Dsymbol collision() + { + if (log) printf(" collision\n"); + return null; + } + /* + Handle merging declarations with asm("foo") and their definitions + */ + static void mangleWrangle(Declaration oldDecl, Declaration newDecl) + { + if (oldDecl && newDecl) + { + newDecl.mangleOverride = oldDecl.mangleOverride ? oldDecl.mangleOverride : null; + } + } + + auto vd = s.isVarDeclaration(); // new declaration + auto vd2 = s2.isVarDeclaration(); // existing declaration + + if (vd && vd.isCmacro()) + return vd2; + + assert(!(vd2 && vd2.isCmacro())); + + if (vd && vd2) + { + /* if one is `static` and the other isn't, the result is undefined + * behavior, C11 6.2.2.7 + */ + if ((vd.storage_class ^ vd2.storage_class) & STC.static_) + return collision(); + + const i1 = vd._init && ! vd._init.isVoidInitializer(); + const i2 = vd2._init && !vd2._init.isVoidInitializer(); + + if (i1 && i2) + return collision(); // can't both have initializers + + mangleWrangle(vd2, vd); + + if (i1) // vd is the definition + { + vd2.storage_class |= STC.extern_; // so toObjFile() won't emit it + sds.symtab.update(vd); // replace vd2 with the definition + return vd; + } + + /* BUG: the types should match, which needs semantic() to be run on it + * extern int x; + * int x; // match + * typedef int INT; + * INT x; // match + * long x; // collision + * We incorrectly ignore these collisions + */ + return vd2; + } + + auto fd = s.isFuncDeclaration(); // new declaration + auto fd2 = s2.isFuncDeclaration(); // existing declaration + if (fd && fd2) + { + /* if one is `static` and the other isn't, the result is undefined + * behavior, C11 6.2.2.7 + * However, match what gcc allows: + * static int sun1(); int sun1() { return 0; } + * and: + * static int sun2() { return 0; } int sun2(); + * Both produce a static function. + * + * Both of these should fail: + * int sun3(); static int sun3() { return 0; } + * and: + * int sun4() { return 0; } static int sun4(); + */ + // if adding `static` + if ( fd.storage_class & STC.static_ && + !(fd2.storage_class & STC.static_)) + { + return collision(); + } + + if (fd.fbody && fd2.fbody) + return collision(); // can't both have bodies + + mangleWrangle(fd2, fd); + + if (fd.fbody) // fd is the definition + { + if (log) printf(" replace existing with new\n"); + sds.symtab.update(fd); // replace fd2 in symbol table with fd + fd.overnext = fd2; + + /* If fd2 is covering a tag symbol, then fd has to cover the same one + */ + auto ps = cast(void*)fd2 in sc._module.tagSymTab; + if (ps) + sc._module.tagSymTab[cast(void*)fd] = *ps; + + return fd; + } + + /* Just like with VarDeclaration, the types should match, which needs semantic() to be run on it. + * FuncDeclaration::semantic() detects this, but it relies on .overnext being set. + */ + fd2.overloadInsert(fd); + + return fd2; + } + + auto td = s.isAliasDeclaration(); // new declaration + auto td2 = s2.isAliasDeclaration(); // existing declaration + if (td && td2) + { + /* BUG: just like with variables and functions, the types should match, which needs semantic() to be run on it. + * FuncDeclaration::semantic2() can detect this, but it relies overnext being set. + */ + return td2; + } + + return collision(); +} diff --git a/gcc/d/dmd/init.h b/gcc/d/dmd/init.h index cccd3c9..2485d78 100644 --- a/gcc/d/dmd/init.h +++ b/gcc/d/dmd/init.h @@ -124,5 +124,8 @@ public: void accept(Visitor *v) override { v->visit(this); } }; -Expression *initializerToExpression(Initializer *init, Type *t = NULL, const bool isCfile = false); -Initializer *initializerSemantic(Initializer *init, Scope *sc, Type *&tx, NeedInterpret needInterpret); +namespace dmd +{ + Expression *initializerToExpression(Initializer *init, Type *t = NULL, const bool isCfile = false); + Initializer *initializerSemantic(Initializer *init, Scope *sc, Type *&tx, NeedInterpret needInterpret); +} diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index 79d7902..b07699e 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -103,7 +103,7 @@ Expression toAssocArrayLiteral(ArrayInitializer ai) * `Initializer` with completed semantic analysis, `ErrorInitializer` if errors * were encountered */ -extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedInterpret needInterpret) +Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedInterpret needInterpret) { //printf("initializerSemantic() tx: %p %s\n", tx, tx.toChars()); Type t = tx; @@ -1224,7 +1224,7 @@ Initializer inferType(Initializer init, Scope* sc) * Returns: * `Expression` created, `null` if cannot, `ErrorExp` for other errors */ -extern (C++) Expression initializerToExpression(Initializer init, Type itype = null, const bool isCfile = false) +Expression initializerToExpression(Initializer init, Type itype = null, const bool isCfile = false) { //printf("initializerToExpression() isCfile: %d\n", isCfile); diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d index 7c65067..f20b3d4 100644 --- a/gcc/d/dmd/json.d +++ b/gcc/d/dmd/json.d @@ -978,7 +978,7 @@ public: * modules = array of Modules * buf = write json output to buf */ -extern (C++) void json_generate(ref Modules modules, ref OutBuffer buf) +void json_generate(ref Modules modules, ref OutBuffer buf) { scope ToJsonVisitor json = new ToJsonVisitor(&buf); // write trailing newline @@ -1047,7 +1047,7 @@ Params: Returns: JsonFieldFlags.none on error, otherwise the JsonFieldFlags value corresponding to the given fieldName. */ -extern (C++) JsonFieldFlags tryParseJsonField(const(char)* fieldName) +JsonFieldFlags tryParseJsonField(const(char)* fieldName) { auto fieldNameString = fieldName.toDString(); foreach (idx, enumName; __traits(allMembers, JsonFieldFlags)) diff --git a/gcc/d/dmd/json.h b/gcc/d/dmd/json.h index 8a94911..b119c9e 100644 --- a/gcc/d/dmd/json.h +++ b/gcc/d/dmd/json.h @@ -15,5 +15,8 @@ struct OutBuffer; -void json_generate(Modules &, OutBuffer &); -JsonFieldFlags tryParseJsonField(const char *fieldName); +namespace dmd +{ + void json_generate(Modules &, OutBuffer &); + JsonFieldFlags tryParseJsonField(const char *fieldName); +} diff --git a/gcc/d/dmd/mangle.h b/gcc/d/dmd/mangle.h index 68064a9..de6fa55 100644 --- a/gcc/d/dmd/mangle.h +++ b/gcc/d/dmd/mangle.h @@ -17,18 +17,21 @@ class TemplateInstance; class Type; struct OutBuffer; -// In cppmangle.d -const char *toCppMangleItanium(Dsymbol *s); -const char *cppTypeInfoMangleItanium(Dsymbol *s); -const char *cppThunkMangleItanium(FuncDeclaration *fd, int offset); +namespace dmd +{ + // In cppmangle.d + const char *toCppMangleItanium(Dsymbol *s); + const char *cppTypeInfoMangleItanium(Dsymbol *s); + const char *cppThunkMangleItanium(FuncDeclaration *fd, int offset); -// In cppmanglewin.d -const char *toCppMangleMSVC(Dsymbol *s); -const char *cppTypeInfoMangleMSVC(Dsymbol *s); + // In cppmanglewin.d + const char *toCppMangleMSVC(Dsymbol *s); + const char *cppTypeInfoMangleMSVC(Dsymbol *s); -// In dmangle.d -const char *mangleExact(FuncDeclaration *fd); -void mangleToBuffer(Type *s, OutBuffer& buf); -void mangleToBuffer(Expression *s, OutBuffer& buf); -void mangleToBuffer(Dsymbol *s, OutBuffer& buf); -void mangleToBuffer(TemplateInstance *s, OutBuffer& buf); + // In dmangle.d + const char *mangleExact(FuncDeclaration *fd); + void mangleToBuffer(Type *s, OutBuffer& buf); + void mangleToBuffer(Expression *s, OutBuffer& buf); + void mangleToBuffer(Dsymbol *s, OutBuffer& buf); + void mangleToBuffer(TemplateInstance *s, OutBuffer& buf); +} diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h index d09e873..379e8e6 100644 --- a/gcc/d/dmd/module.h +++ b/gcc/d/dmd/module.h @@ -167,5 +167,8 @@ struct ModuleDeclaration const char *toChars() const; }; -extern void getLocalClasses(Module* mod, Array<ClassDeclaration* >& aclasses); -FuncDeclaration *findGetMembers(ScopeDsymbol *dsym); +namespace dmd +{ + void getLocalClasses(Module* mod, Array<ClassDeclaration* >& aclasses); + FuncDeclaration *findGetMembers(ScopeDsymbol *dsym); +} diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 4f8ed75..09ed630 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -1186,58 +1186,6 @@ extern (C++) abstract class Type : ASTNode return t; } - /************************************ - * Add storage class modifiers to type. - */ - Type addStorageClass(StorageClass stc) - { - /* Just translate to MOD bits and let addMod() do the work - */ - MOD mod = 0; - if (stc & STC.immutable_) - mod = MODFlags.immutable_; - else - { - if (stc & (STC.const_ | STC.in_)) - mod |= MODFlags.const_; - if (stc & STC.wild) - mod |= MODFlags.wild; - if (stc & STC.shared_) - mod |= MODFlags.shared_; - } - return this.addMod(mod); - } - - final Type pointerTo() - { - if (ty == Terror) - return this; - if (!pto) - { - Type t = new TypePointer(this); - if (ty == Tfunction) - { - t.deco = t.merge().deco; - pto = t; - } - else - pto = t.merge(); - } - return pto; - } - - final Type referenceTo() - { - if (ty == Terror) - return this; - if (!rto) - { - Type t = new TypeReference(this); - rto = t.merge(); - } - return rto; - } - final Type arrayOf() { if (ty == Terror) @@ -3449,56 +3397,6 @@ extern (C++) final class TypeFunction : TypeNext return linkage == LINK.d && parameterList.varargs == VarArg.variadic; } - override Type addStorageClass(StorageClass stc) - { - //printf("addStorageClass(%llx) %d\n", stc, (stc & STC.scope_) != 0); - TypeFunction t = Type.addStorageClass(stc).toTypeFunction(); - if ((stc & STC.pure_ && !t.purity) || - (stc & STC.nothrow_ && !t.isnothrow) || - (stc & STC.nogc && !t.isnogc) || - (stc & STC.scope_ && !t.isScopeQual) || - (stc & STC.safe && t.trust < TRUST.trusted)) - { - // Klunky to change these - auto tf = new TypeFunction(t.parameterList, t.next, t.linkage, 0); - tf.mod = t.mod; - tf.fargs = fargs; - tf.purity = t.purity; - tf.isnothrow = t.isnothrow; - tf.isnogc = t.isnogc; - tf.isproperty = t.isproperty; - tf.isref = t.isref; - tf.isreturn = t.isreturn; - tf.isreturnscope = t.isreturnscope; - tf.isScopeQual = t.isScopeQual; - tf.isreturninferred = t.isreturninferred; - tf.isscopeinferred = t.isscopeinferred; - tf.trust = t.trust; - tf.isInOutParam = t.isInOutParam; - tf.isInOutQual = t.isInOutQual; - tf.isctor = t.isctor; - - if (stc & STC.pure_) - tf.purity = PURE.fwdref; - if (stc & STC.nothrow_) - tf.isnothrow = true; - if (stc & STC.nogc) - tf.isnogc = true; - if (stc & STC.safe) - tf.trust = TRUST.safe; - if (stc & STC.scope_) - { - tf.isScopeQual = true; - if (stc & STC.scopeinferred) - tf.isscopeinferred = true; - } - - tf.deco = tf.merge().deco; - t = tf; - } - return t; - } - override Type substWildTo(uint) { if (!iswild && !(mod & MODFlags.wild)) @@ -3800,12 +3698,6 @@ extern (C++) final class TypeDelegate : TypeNext return result; } - override Type addStorageClass(StorageClass stc) - { - TypeDelegate t = cast(TypeDelegate)Type.addStorageClass(stc); - return t; - } - override uinteger_t size(const ref Loc loc) { return target.ptrsize * 2; @@ -5673,7 +5565,7 @@ void attributesApply(const TypeFunction tf, void delegate(string) dg, TRUSTforma * If the type is a class or struct, returns the symbol for it, * else null. */ -extern (C++) AggregateDeclaration isAggregate(Type t) +AggregateDeclaration isAggregate(Type t) { t = t.toBasetype(); if (t.ty == Tclass) diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h index df8cc4d..57f4ec6 100644 --- a/gcc/d/dmd/mtype.h +++ b/gcc/d/dmd/mtype.h @@ -39,8 +39,11 @@ typedef union tree_node type; typedef struct TYPE type; #endif -Type *typeSemantic(Type *t, const Loc &loc, Scope *sc); -Type *merge(Type *type); +namespace dmd +{ + Type *typeSemantic(Type *t, const Loc &loc, Scope *sc); + Type *merge(Type *type); +} enum class TY : uint8_t { @@ -251,9 +254,6 @@ public: bool isSharedWild() const { return (mod & (MODshared | MODwild)) == (MODshared | MODwild); } bool isNaked() const { return mod == 0; } Type *nullAttributes() const; - virtual Type *addStorageClass(StorageClass stc); - Type *pointerTo(); - Type *referenceTo(); Type *arrayOf(); Type *sarrayOf(dinteger_t dim); bool hasDeprecatedAliasThis(); @@ -579,7 +579,6 @@ public: TypeFunction *syntaxCopy() override; bool hasLazyParameters(); bool isDstyleVariadic() const; - Type *addStorageClass(StorageClass stc) override; Type *substWildTo(unsigned mod) override; MATCH constConv(Type *to) override; @@ -623,7 +622,6 @@ public: static TypeDelegate *create(TypeFunction *t); const char *kind() override; TypeDelegate *syntaxCopy() override; - Type *addStorageClass(StorageClass stc) override; uinteger_t size(const Loc &loc) override; unsigned alignsize() override; MATCH implicitConvTo(Type *to) override; @@ -880,26 +878,31 @@ public: /**************************************************************/ - -// If the type is a class or struct, returns the symbol for it, else null. -AggregateDeclaration *isAggregate(Type *t); -bool hasPointers(Type *t); -// return the symbol to which type t resolves -Dsymbol *toDsymbol(Type *t, Scope *sc); -bool equivalent(Type *src, Type *t); -Covariant covariant(Type *, Type *, StorageClass * = NULL, bool = false); -bool isBaseOf(Type *tthis, Type *t, int *poffset); -Type *trySemantic(Type *type, const Loc &loc, Scope *sc); -Type *merge2(Type *type); -Type *constOf(Type *type); -Type *immutableOf(Type *type); -Type *mutableOf(Type *type); -Type *sharedOf(Type *type); -Type *sharedConstOf(Type *type); -Type *unSharedOf(Type *type); -Type *wildOf(Type *type); -Type *wildConstOf(Type *type); -Type *sharedWildOf(Type *type); -Type *sharedWildConstOf(Type *type); -Type *castMod(Type *type, MOD mod); -Type *addMod(Type *type, MOD mod); +namespace dmd +{ + // If the type is a class or struct, returns the symbol for it, else null. + AggregateDeclaration *isAggregate(Type *t); + bool hasPointers(Type *t); + // return the symbol to which type t resolves + Dsymbol *toDsymbol(Type *t, Scope *sc); + bool equivalent(Type *src, Type *t); + Covariant covariant(Type *, Type *, StorageClass * = NULL, bool = false); + bool isBaseOf(Type *tthis, Type *t, int *poffset); + Type *trySemantic(Type *type, const Loc &loc, Scope *sc); + Type *pointerTo(Type *type); + Type *referenceTo(Type *type); + Type *merge2(Type *type); + Type *constOf(Type *type); + Type *immutableOf(Type *type); + Type *mutableOf(Type *type); + Type *sharedOf(Type *type); + Type *sharedConstOf(Type *type); + Type *unSharedOf(Type *type); + Type *wildOf(Type *type); + Type *wildConstOf(Type *type); + Type *sharedWildOf(Type *type); + Type *sharedWildConstOf(Type *type); + Type *castMod(Type *type, MOD mod); + Type *addMod(Type *type, MOD mod); + Type *addStorageClass(Type *type, StorageClass stc); +} diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index 5c0ef67..dd6b117 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -273,7 +273,7 @@ package void setLengthVarIfKnown(VarDeclaration lengthVar, Type type) * Returns: * Constant folded version of `e` */ -extern (C++) Expression optimize(Expression e, int result, bool keepLvalue = false) +Expression optimize(Expression e, int result, bool keepLvalue = false) { //printf("optimize() e: %s result: %d keepLvalue %d\n", e.toChars(), result, keepLvalue); Expression ret = e; diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index 2d2e6fd..9c446eb 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -7180,6 +7180,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } if (!isDeclarator(&t, &haveId, &haveTpl, endtok, needId != NeedDeclaratorId.mustIfDstyle)) goto Lisnot; + // needed for `__traits(compiles, arr[0] = 0)` + if (!haveId && t.value == TOK.assign) + goto Lisnot; if ((needId == NeedDeclaratorId.no && !haveId) || (needId == NeedDeclaratorId.opt) || (needId == NeedDeclaratorId.must && haveId) || diff --git a/gcc/d/dmd/parsetimevisitor.d b/gcc/d/dmd/parsetimevisitor.d index 422c1c8..c03f78d 100644 --- a/gcc/d/dmd/parsetimevisitor.d +++ b/gcc/d/dmd/parsetimevisitor.d @@ -36,6 +36,7 @@ public: void visit(AST.DebugSymbol s) { visit(cast(AST.Dsymbol)s); } void visit(AST.VersionSymbol s) { visit(cast(AST.Dsymbol)s); } void visit(AST.AliasAssign s) { visit(cast(AST.Dsymbol)s); } + void visit(AST.CAsmDeclaration s) { visit(cast(AST.Dsymbol)s); } // ScopeDsymbols void visit(AST.Package s) { visit(cast(AST.ScopeDsymbol)s); } diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d index b4f91ac..f5ce0c0 100644 --- a/gcc/d/dmd/semantic2.d +++ b/gcc/d/dmd/semantic2.d @@ -73,7 +73,7 @@ enum LOG = false; /************************************* * Does semantic analysis on initializers and members of aggregates. */ -extern(C++) void semantic2(Dsymbol dsym, Scope* sc) +void semantic2(Dsymbol dsym, Scope* sc) { scope v = new Semantic2Visitor(sc); dsym.accept(v); @@ -876,7 +876,7 @@ private extern(C++) final class StaticAAVisitor : SemanticTimeTransitiveVisitor hookFunc = new DotIdExp(aaExp.loc, hookFunc, Id.object); hookFunc = new DotIdExp(aaExp.loc, hookFunc, Id._aaAsStruct); auto arguments = new Expressions(); - arguments.push(aaExp.syntaxCopy()); + arguments.push(aaExp); Expression loweredExp = new CallExp(aaExp.loc, hookFunc, arguments); sc = sc.startCTFE(); diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index 125a39d..882d1a9 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -79,7 +79,7 @@ enum LOG = false; /************************************* * Does semantic analysis on function bodies. */ -extern(C++) void semantic3(Dsymbol dsym, Scope* sc) +void semantic3(Dsymbol dsym, Scope* sc) { scope v = new Semantic3Visitor(sc); dsym.accept(v); @@ -1636,7 +1636,7 @@ private struct FuncDeclSem3 } } -extern (C++) void semanticTypeInfoMembers(StructDeclaration sd) +void semanticTypeInfoMembers(StructDeclaration sd) { if (sd.xeq && sd.xeq._scope && diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h index 8a6bf3d..ea80e51 100644 --- a/gcc/d/dmd/statement.h +++ b/gcc/d/dmd/statement.h @@ -701,12 +701,15 @@ public: void accept(Visitor *v) override { v->visit(this); } }; -// in statementsem.d -Statement* statementSemantic(Statement *s, Scope *sc); -// in iasm.d -Statement* asmSemantic(AsmStatement *s, Scope *sc); -// in iasmgcc.d -Statement *gccAsmSemantic(GccAsmStatement *s, Scope *sc); +namespace dmd +{ + // in statementsem.d + Statement* statementSemantic(Statement *s, Scope *sc); + // in iasm.d + Statement* asmSemantic(AsmStatement *s, Scope *sc); + // in iasmgcc.d + Statement *gccAsmSemantic(GccAsmStatement *s, Scope *sc); +} class AsmStatement : public Statement { diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index a431d5c..5013c56 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -41,8 +41,8 @@ import dmd.expressionsem; import dmd.func; import dmd.funcsem; import dmd.globals; -import dmd.gluelayer; import dmd.hdrgen; +import dmd.iasm; import dmd.id; import dmd.identifier; import dmd.importc; @@ -135,7 +135,7 @@ private Expression checkAssignmentAsCondition(Expression e, Scope* sc) } // Performs semantic analysis in Statement AST nodes -extern(C++) Statement statementSemantic(Statement s, Scope* sc) +Statement statementSemantic(Statement s, Scope* sc) { import dmd.compiler; diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d index e63bf17..cff1d2e 100644 --- a/gcc/d/dmd/target.d +++ b/gcc/d/dmd/target.d @@ -110,7 +110,7 @@ extern (C++) struct Target /// Architecture name const(char)[] architectureName; - CPU cpu = CPU.baseline; // CPU instruction set to target + CPU cpu; // CPU instruction set to target bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd bool isLP64; // pointers are 64 bits @@ -119,7 +119,7 @@ extern (C++) struct Target const(char)[] lib_ext; /// extension for static library files const(char)[] dll_ext; /// extension for dynamic library files bool run_noext; /// allow -run sources without extensions - bool omfobj = false; // for Win32: write OMF object files instead of MsCoff + bool omfobj; // for Win32: write OMF object files instead of MsCoff /** * Values representing all properties for floating point types */ diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h index c80f28b..6f12ac3 100644 --- a/gcc/d/dmd/template.h +++ b/gcc/d/dmd/template.h @@ -317,14 +317,17 @@ public: void accept(Visitor *v) override { v->visit(this); } }; -// in templateparamsem.d -bool tpsemantic(TemplateParameter *tp, Scope *sc, TemplateParameters *parameters); - -Expression *isExpression(RootObject *o); -Dsymbol *isDsymbol(RootObject *o); -Type *isType(RootObject *o); -Tuple *isTuple(RootObject *o); -Parameter *isParameter(RootObject *o); -TemplateParameter *isTemplateParameter(RootObject *o); -bool isError(const RootObject *const o); -void printTemplateStats(bool listInstances, ErrorSink* eSink); +namespace dmd +{ + // in templateparamsem.d + bool tpsemantic(TemplateParameter *tp, Scope *sc, TemplateParameters *parameters); + + Expression *isExpression(RootObject *o); + Dsymbol *isDsymbol(RootObject *o); + Type *isType(RootObject *o); + Tuple *isTuple(RootObject *o); + Parameter *isParameter(RootObject *o); + TemplateParameter *isTemplateParameter(RootObject *o); + bool isError(const RootObject *const o); + void printTemplateStats(bool listInstances, ErrorSink* eSink); +} diff --git a/gcc/d/dmd/templateparamsem.d b/gcc/d/dmd/templateparamsem.d index 89749d6..f2dc50e 100644 --- a/gcc/d/dmd/templateparamsem.d +++ b/gcc/d/dmd/templateparamsem.d @@ -35,7 +35,7 @@ import dmd.visitor; * Returns: * `true` if no errors */ -extern(C++) bool tpsemantic(TemplateParameter tp, Scope* sc, TemplateParameters* parameters) +bool tpsemantic(TemplateParameter tp, Scope* sc, TemplateParameters* parameters) { scope v = new TemplateParameterSemanticVisitor(sc, parameters); tp.accept(v); diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index 19c6912..61272ea 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -1222,7 +1222,7 @@ private extern(D) MATCH matchTypeSafeVarArgs(TypeFunction tf, Parameter p, * Return !=0 if type has pointers that need to * be scanned by the GC during a collection cycle. */ -extern(C++) bool hasPointers(Type t) +bool hasPointers(Type t) { bool visitType(Type _) { return false; } bool visitDArray(TypeDArray _) { return true; } @@ -1292,7 +1292,7 @@ extern(C++) bool hasPointers(Type t) * `Type` with completed semantic analysis, `Terror` if errors * were encountered */ -extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) +Type typeSemantic(Type type, const ref Loc loc, Scope* sc) { static Type error() { @@ -2821,7 +2821,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) } } -extern(C++) Type trySemantic(Type type, const ref Loc loc, Scope* sc) +Type trySemantic(Type type, const ref Loc loc, Scope* sc) { //printf("+trySemantic(%s) %d\n", toChars(), global.errors); @@ -2855,7 +2855,7 @@ extern(C++) Type trySemantic(Type type, const ref Loc loc, Scope* sc) * Returns: * the type that was merged */ -extern (C++) Type merge(Type type) +Type merge(Type type) { switch (type.ty) { @@ -2925,7 +2925,7 @@ extern (C++) Type merge(Type type) * This version does a merge even if the deco is already computed. * Necessary for types that have a deco, but are not merged. */ -extern(C++) Type merge2(Type type) +Type merge2(Type type) { //printf("merge2(%s)\n", toChars()); Type t = type; @@ -5365,7 +5365,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag * Returns: * The initialization expression for the type. */ -extern (C++) Expression defaultInit(Type mt, const ref Loc loc, const bool isCfile = false) +Expression defaultInit(Type mt, const ref Loc loc, const bool isCfile = false) { Expression visitBasic(TypeBasic mt) { @@ -5545,7 +5545,7 @@ Returns: if the type does resolve to any symbol (for example, in the case of basic types). */ -extern(C++) Dsymbol toDsymbol(Type type, Scope* sc) +Dsymbol toDsymbol(Type type, Scope* sc) { Dsymbol visitType(Type _) { return null; } Dsymbol visitStruct(TypeStruct type) { return type.sym; } @@ -5644,6 +5644,94 @@ extern(C++) Dsymbol toDsymbol(Type type, Scope* sc) } } +/************************************ + * Add storage class modifiers to type. + */ +Type addStorageClass(Type type, StorageClass stc) +{ + Type visitType(Type t) + { + /* Just translate to MOD bits and let addMod() do the work + */ + MOD mod = 0; + if (stc & STC.immutable_) + mod = MODFlags.immutable_; + else + { + if (stc & (STC.const_ | STC.in_)) + mod |= MODFlags.const_; + if (stc & STC.wild) + mod |= MODFlags.wild; + if (stc & STC.shared_) + mod |= MODFlags.shared_; + } + return t.addMod(mod); + } + + Type visitFunction(TypeFunction tf_src) + { + //printf("addStorageClass(%llx) %d\n", stc, (stc & STC.scope_) != 0); + TypeFunction t = visitType(tf_src).toTypeFunction(); + if ((stc & STC.pure_ && !t.purity) || + (stc & STC.nothrow_ && !t.isnothrow) || + (stc & STC.nogc && !t.isnogc) || + (stc & STC.scope_ && !t.isScopeQual) || + (stc & STC.safe && t.trust < TRUST.trusted)) + { + // Klunky to change these + auto tf = new TypeFunction(t.parameterList, t.next, t.linkage, 0); + tf.mod = t.mod; + tf.fargs = tf_src.fargs; + tf.purity = t.purity; + tf.isnothrow = t.isnothrow; + tf.isnogc = t.isnogc; + tf.isproperty = t.isproperty; + tf.isref = t.isref; + tf.isreturn = t.isreturn; + tf.isreturnscope = t.isreturnscope; + tf.isScopeQual = t.isScopeQual; + tf.isreturninferred = t.isreturninferred; + tf.isscopeinferred = t.isscopeinferred; + tf.trust = t.trust; + tf.isInOutParam = t.isInOutParam; + tf.isInOutQual = t.isInOutQual; + tf.isctor = t.isctor; + + if (stc & STC.pure_) + tf.purity = PURE.fwdref; + if (stc & STC.nothrow_) + tf.isnothrow = true; + if (stc & STC.nogc) + tf.isnogc = true; + if (stc & STC.safe) + tf.trust = TRUST.safe; + if (stc & STC.scope_) + { + tf.isScopeQual = true; + if (stc & STC.scopeinferred) + tf.isscopeinferred = true; + } + + tf.deco = tf.merge().deco; + t = tf; + } + return t; + } + + Type visitDelegate(TypeDelegate tdg) + { + TypeDelegate t = visitType(tdg).isTypeDelegate(); + return t; + } + + switch(type.ty) + { + default: return visitType(type); + case Tfunction: return visitFunction(type.isTypeFunction()); + case Tdelegate: return visitDelegate(type.isTypeDelegate()); + } +} + /********************************************** * Extract complex type from core.stdc.config * Params: @@ -5722,7 +5810,7 @@ Type getComplexLibraryType(const ref Loc loc, Scope* sc, TY ty) * Returns: * An enum value of either `Covariant.yes` or a reason it's not covariant. */ -extern(C++) Covariant covariant(Type src, Type t, StorageClass* pstc = null, bool cppCovariant = false) +Covariant covariant(Type src, Type t, StorageClass* pstc = null, bool cppCovariant = false) { version (none) { @@ -6085,7 +6173,7 @@ StorageClass parameterStorageClass(TypeFunction tf, Type tthis, Parameter p, Var return stc | STC.scope_; } -extern(C++) bool isBaseOf(Type tthis, Type t, int* poffset) +bool isBaseOf(Type tthis, Type t, int* poffset) { auto tc = tthis.isTypeClass(); if (!tc) @@ -6106,15 +6194,45 @@ extern(C++) bool isBaseOf(Type tthis, Type t, int* poffset) return false; } -extern(C++) bool equivalent(Type src, Type t) +bool equivalent(Type src, Type t) { return immutableOf(src).equals(t.immutableOf()); } +Type pointerTo(Type type) +{ + if (type.ty == Terror) + return type; + if (!type.pto) + { + Type t = new TypePointer(type); + if (type.ty == Tfunction) + { + t.deco = t.merge().deco; + type.pto = t; + } + else + type.pto = t.merge(); + } + return type.pto; +} + +Type referenceTo(Type type) +{ + if (type.ty == Terror) + return type; + if (!type.rto) + { + Type t = new TypeReference(type); + type.rto = t.merge(); + } + return type.rto; +} + /******************************** * Convert to 'const'. */ -extern(C++) Type constOf(Type type) +Type constOf(Type type) { //printf("Type::constOf() %p %s\n", type, type.toChars()); if (type.mod == MODFlags.const_) @@ -6134,7 +6252,7 @@ extern(C++) Type constOf(Type type) /******************************** * Convert to 'immutable'. */ -extern(C++) Type immutableOf(Type type) +Type immutableOf(Type type) { //printf("Type::immutableOf() %p %s\n", this, toChars()); if (type.isImmutable()) @@ -6154,7 +6272,7 @@ extern(C++) Type immutableOf(Type type) /******************************** * Make type mutable. */ -extern(C++) Type mutableOf(Type type) +Type mutableOf(Type type) { //printf("Type::mutableOf() %p, %s\n", type, type.toChars()); Type t = type; @@ -6204,7 +6322,7 @@ extern(C++) Type mutableOf(Type type) return t; } -extern(C++) Type sharedOf(Type type) +Type sharedOf(Type type) { //printf("Type::sharedOf() %p, %s\n", type, type.toChars()); if (type.mod == MODFlags.shared_) @@ -6221,7 +6339,7 @@ extern(C++) Type sharedOf(Type type) return t; } -extern(C++) Type sharedConstOf(Type type) +Type sharedConstOf(Type type) { //printf("Type::sharedConstOf() %p, %s\n", type, type.toChars()); if (type.mod == (MODFlags.shared_ | MODFlags.const_)) @@ -6250,7 +6368,7 @@ extern(C++) Type sharedConstOf(Type type) * shared wild => wild * shared wild const => wild const */ -extern(C++) Type unSharedOf(Type type) +Type unSharedOf(Type type) { //printf("Type::unSharedOf() %p, %s\n", type, type.toChars()); Type t = type; @@ -6292,7 +6410,7 @@ extern(C++) Type unSharedOf(Type type) /******************************** * Convert to 'wild'. */ -extern(C++) Type wildOf(Type type) +Type wildOf(Type type) { //printf("Type::wildOf() %p %s\n", type, type.toChars()); if (type.mod == MODFlags.wild) @@ -6309,7 +6427,7 @@ extern(C++) Type wildOf(Type type) return t; } -extern(C++) Type wildConstOf(Type type) +Type wildConstOf(Type type) { //printf("Type::wildConstOf() %p %s\n", type, type.toChars()); if (type.mod == MODFlags.wildconst) @@ -6326,7 +6444,7 @@ extern(C++) Type wildConstOf(Type type) return t; } -extern(C++) Type sharedWildOf(Type type) +Type sharedWildOf(Type type) { //printf("Type::sharedWildOf() %p, %s\n", type, type.toChars()); if (type.mod == (MODFlags.shared_ | MODFlags.wild)) @@ -6343,7 +6461,7 @@ extern(C++) Type sharedWildOf(Type type) return t; } -extern(C++) Type sharedWildConstOf(Type type) +Type sharedWildConstOf(Type type) { //printf("Type::sharedWildConstOf() %p, %s\n", type, type.toChars()); if (type.mod == (MODFlags.shared_ | MODFlags.wildconst)) @@ -6363,7 +6481,7 @@ extern(C++) Type sharedWildConstOf(Type type) /************************************ * Apply MODxxxx bits to existing type. */ -extern(C++) Type castMod(Type type, MOD mod) +Type castMod(Type type, MOD mod) { Type t; switch (mod) @@ -6415,7 +6533,7 @@ extern(C++) Type castMod(Type type, MOD mod) * We're adding, not replacing, so adding const to * a shared type => "shared const" */ -extern(C++) Type addMod(Type type, MOD mod) +Type addMod(Type type, MOD mod) { /* Add anything to immutable, and it remains immutable */ diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d index 6ae6df0..a319832 100644 --- a/gcc/d/dmd/typinf.d +++ b/gcc/d/dmd/typinf.d @@ -35,7 +35,7 @@ import core.stdc.stdio; * Returns: * true if `TypeInfo` was generated and needs compiling to object file */ -extern (C++) bool genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc) +bool genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc) { // printf("genTypeInfo() %s\n", torig.toChars()); @@ -147,7 +147,7 @@ private TypeInfoDeclaration getTypeInfoDeclaration(Type t) * true if any part of type t is speculative. * if t is null, returns false. */ -extern (C++) bool isSpeculativeType(Type t) +bool isSpeculativeType(Type t) { static bool visitVector(TypeVector t) { @@ -244,7 +244,7 @@ extern (C++) bool isSpeculativeType(Type t) /* Indicates whether druntime already contains an appropriate TypeInfo instance * for the specified type (in module rt.util.typeinfo). */ -extern (C++) bool builtinTypeInfo(Type t) +bool builtinTypeInfo(Type t) { if (!t.mod) // unqualified types only { diff --git a/gcc/d/dmd/typinf.h b/gcc/d/dmd/typinf.h index fe80b94..dd9572a 100644 --- a/gcc/d/dmd/typinf.h +++ b/gcc/d/dmd/typinf.h @@ -16,7 +16,10 @@ class Expression; class Type; struct Scope; -bool genTypeInfo(Expression *e, const Loc &loc, Type *torig, Scope *sc); +namespace dmd +{ + bool genTypeInfo(Expression *e, const Loc &loc, Type *torig, Scope *sc); + bool isSpeculativeType(Type *t); + bool builtinTypeInfo(Type *t); +} Type *getTypeInfoType(const Loc &loc, Type *t, Scope *sc, bool genObjCode = true); -bool isSpeculativeType(Type *t); -bool builtinTypeInfo(Type *t); diff --git a/gcc/d/dmd/visitor.h b/gcc/d/dmd/visitor.h index 6e3d315..ab5cba6 100644 --- a/gcc/d/dmd/visitor.h +++ b/gcc/d/dmd/visitor.h @@ -126,6 +126,7 @@ class WithScopeSymbol; class ArrayScopeSymbol; class Nspace; class AliasAssign; +class CAsmDeclaration; class AggregateDeclaration; class StructDeclaration; @@ -339,6 +340,7 @@ public: virtual void visit(DebugSymbol *s) { visit((Dsymbol *)s); } virtual void visit(VersionSymbol *s) { visit((Dsymbol *)s); } virtual void visit(AliasAssign *s) { visit((Dsymbol *)s); } + virtual void visit(CAsmDeclaration *s) { visit((Dsymbol *)s); } // ScopeDsymbols virtual void visit(Package *s) { visit((ScopeDsymbol *)s); } diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index a050588..7fbabbe 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -1178,7 +1178,7 @@ public: { libcall = LIBCALL_AAGETY; ptr = build_address (build_expr (e->e1)); - tinfo = build_typeinfo (e, mutableOf (unSharedOf (tb1))); + tinfo = build_typeinfo (e, dmd::mutableOf (dmd::unSharedOf (tb1))); } else { @@ -1188,7 +1188,7 @@ public: } /* Index the associative array. */ - tree result = build_libcall (libcall, e->type->pointerTo (), 4, + tree result = build_libcall (libcall, dmd::pointerTo (e->type), 4, ptr, tinfo, size_int (tb1->nextOf ()->size ()), build_address (key)); @@ -1253,7 +1253,8 @@ public: else { /* Generate `array.ptr[index]'. */ - tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ()); + tree ptr = convert_expr (array, tb1, + dmd::pointerTo (tb1->nextOf ())); ptr = void_okay_p (ptr); this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)), build_pointer_index (ptr, index)); @@ -1328,7 +1329,7 @@ public: /* Get the data pointer and length for static and dynamic arrays. */ tree array = d_save_expr (build_expr (e->e1)); - tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ()); + tree ptr = convert_expr (array, tb1, dmd::pointerTo (tb1->nextOf ())); tree length = NULL_TREE; /* Our array is already a SAVE_EXPR if necessary, so we don't make length @@ -1994,7 +1995,7 @@ public: void visit (TypeidExp *e) final override { - if (Type *tid = isType (e->obj)) + if (Type *tid = dmd::isType (e->obj)) { tree ti = build_typeinfo (e, tid); @@ -2004,7 +2005,7 @@ public: this->result_ = build_nop (build_ctype (e->type), ti); } - else if (Expression *tid = isExpression (e->obj)) + else if (Expression *tid = dmd::isExpression (e->obj)) { Type *type = tid->type->toBasetype (); assert (type->ty == TY::Tclass); @@ -2136,7 +2137,8 @@ public: else { var->inuse++; - init = build_expr (initializerToExpression (var->_init), true); + Expression *vinit = dmd::initializerToExpression (var->_init); + init = build_expr (vinit, true); var->inuse--; } } @@ -2170,7 +2172,7 @@ public: { /* Generate a slice for non-zero initialized aggregates, otherwise create an empty array. */ - gcc_assert (e->type == constOf (Type::tvoid->arrayOf ())); + gcc_assert (e->type == dmd::constOf (Type::tvoid->arrayOf ())); tree type = build_ctype (e->type); tree length = size_int (sd->dsym->structsize); @@ -2682,7 +2684,7 @@ public: { /* Allocate space on the memory managed heap. */ tree mem = build_libcall (LIBCALL_ARRAYLITERALTX, - etype->pointerTo (), 2, + dmd::pointerTo (etype), 2, build_typeinfo (e, etype->arrayOf ()), size_int (e->elements->length)); mem = d_save_expr (mem); @@ -2718,7 +2720,7 @@ public: } /* Want the mutable type for typeinfo reference. */ - Type *tb = mutableOf (e->type->toBasetype ()); + Type *tb = dmd::mutableOf (e->type->toBasetype ()); /* Handle empty assoc array literals. */ TypeAArray *ta = tb->isTypeAArray (); diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc index 8adbbee..8bbcdc1 100644 --- a/gcc/d/intrinsics.cc +++ b/gcc/d/intrinsics.cc @@ -126,7 +126,7 @@ maybe_set_intrinsic (FuncDeclaration *decl) return; OutBuffer buf; - mangleToBuffer (fd->type, buf); + dmd::mangleToBuffer (fd->type, buf); tdeco = buf.extractChars (); } @@ -719,7 +719,7 @@ expand_intrinsic_rotate (intrinsic_code intrinsic, tree callexp) TemplateInstance *ti = DECL_LANG_FRONTEND (callee)->isInstantiated (); gcc_assert (ti && ti->tiargs && ti->tiargs->length == 2); - Expression *e = isExpression ((*ti->tiargs)[0]); + Expression *e = dmd::isExpression ((*ti->tiargs)[0]); gcc_assert (e && e->op == EXP::int64); count = build_expr (e, true); } diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc index 58b15be..b111ee9 100644 --- a/gcc/d/modules.cc +++ b/gcc/d/modules.cc @@ -504,7 +504,7 @@ layout_moduleinfo_fields (Module *decl, tree type) if (decl->sshareddtor) layout_moduleinfo_field (ptr_type_node, type, offset); - if (findGetMembers (decl)) + if (dmd::findGetMembers (decl)) layout_moduleinfo_field (ptr_type_node, type, offset); if (decl->sictor) @@ -532,7 +532,7 @@ layout_moduleinfo_fields (Module *decl, tree type) /* Array of local ClassInfo decls are laid out in the same way. */ ClassDeclarations aclasses; - getLocalClasses (decl, aclasses); + dmd::getLocalClasses (decl, aclasses); if (aclasses.length) { @@ -562,7 +562,7 @@ layout_moduleinfo (Module *decl) ClassDeclarations aclasses; FuncDeclaration *sgetmembers; - getLocalClasses (decl, aclasses); + dmd::getLocalClasses (decl, aclasses); size_t aimports_dim = decl->aimports.length; for (size_t i = 0; i < decl->aimports.length; i++) @@ -572,7 +572,7 @@ layout_moduleinfo (Module *decl) aimports_dim--; } - sgetmembers = findGetMembers (decl); + sgetmembers = dmd::findGetMembers (decl); size_t flags = 0; if (decl->sctor) diff --git a/gcc/d/runtime.cc b/gcc/d/runtime.cc index 9d11e7e..e5988c7 100644 --- a/gcc/d/runtime.cc +++ b/gcc/d/runtime.cc @@ -150,11 +150,11 @@ get_libcall_type (d_libcall_type type) break; case LCT_CONST_TYPEINFO: - libcall_types[type] = constOf (Type::dtypeinfo->type); + libcall_types[type] = dmd::constOf (Type::dtypeinfo->type); break; case LCT_CONST_CLASSINFO: - libcall_types[type] = constOf (Type::typeinfoclass->type); + libcall_types[type] = dmd::constOf (Type::typeinfoclass->type); break; case LCT_ARRAY_VOID: @@ -186,7 +186,7 @@ get_libcall_type (d_libcall_type type) break; case LCT_POINTER_ASSOCARRAY: - libcall_types[type] = get_libcall_type (LCT_ASSOCARRAY)->pointerTo (); + libcall_types[type] = dmd::pointerTo (get_libcall_type (LCT_ASSOCARRAY)); break; case LCT_POINTER_VOIDPTR: @@ -194,15 +194,15 @@ get_libcall_type (d_libcall_type type) break; case LCT_ARRAYPTR_VOID: - libcall_types[type] = Type::tvoid->arrayOf ()->pointerTo (); + libcall_types[type] = dmd::pointerTo (Type::tvoid->arrayOf ()); break; case LCT_ARRAYPTR_BYTE: - libcall_types[type] = Type::tint8->arrayOf ()->pointerTo (); + libcall_types[type] = dmd::pointerTo (Type::tint8->arrayOf ()); break; case LCT_IMMUTABLE_CHARPTR: - libcall_types[type] = immutableOf (Type::tchar->pointerTo ()); + libcall_types[type] = dmd::immutableOf (dmd::pointerTo (Type::tchar)); break; default: diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index 3dbda55..794737b 100644 --- a/gcc/d/typeinfo.cc +++ b/gcc/d/typeinfo.cc @@ -206,7 +206,7 @@ make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL) /* Create object module in order to complete the semantic. */ if (!object_module->_scope) - importAll (object_module, NULL); + dmd::importAll (object_module, NULL); /* Object class doesn't exist, create a stub one that will cause an error if used. */ @@ -232,7 +232,7 @@ make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL) true); tinfo->parent = object_module; tinfo->members = d_gc_malloc<Dsymbols> (); - dsymbolSemantic (tinfo, object_module->_scope); + dmd::dsymbolSemantic (tinfo, object_module->_scope); tinfo->baseClass = base; /* This is a compiler generated class, and shouldn't be mistaken for being the type declared in the runtime library. */ @@ -577,8 +577,8 @@ public: void visit (TypeInfoConstDeclaration *d) final override { - Type *tm = mutableOf (d->tinfo); - tm = merge2 (tm); + Type *tm = dmd::mutableOf (d->tinfo); + tm = dmd::merge2 (tm); /* The vtable for TypeInfo_Const. */ this->layout_base (Type::typeinfoconst); @@ -594,8 +594,8 @@ public: void visit (TypeInfoInvariantDeclaration *d) final override { - Type *tm = mutableOf (d->tinfo); - tm = merge2 (tm); + Type *tm = dmd::mutableOf (d->tinfo); + tm = dmd::merge2 (tm); /* The vtable for TypeInfo_Invariant. */ this->layout_base (Type::typeinfoinvariant); @@ -611,8 +611,8 @@ public: void visit (TypeInfoSharedDeclaration *d) final override { - Type *tm = unSharedOf (d->tinfo); - tm = merge2 (tm); + Type *tm = dmd::unSharedOf (d->tinfo); + tm = dmd::merge2 (tm); /* The vtable for TypeInfo_Shared. */ this->layout_base (Type::typeinfoshared); @@ -628,8 +628,8 @@ public: void visit (TypeInfoWildDeclaration *d) final override { - Type *tm = mutableOf (d->tinfo); - tm = merge2 (tm); + Type *tm = dmd::mutableOf (d->tinfo); + tm = dmd::merge2 (tm); /* The vtable for TypeInfo_Inout. */ this->layout_base (Type::typeinfowild); @@ -1091,7 +1091,7 @@ public: this->layout_field (xcmp); /* string function(const(void)*) xtoString; */ - FuncDeclaration *fdx = search_toString (sd); + FuncDeclaration *fdx = dmd::search_toString (sd); if (fdx) this->layout_field (build_address (get_symbol_decl (fdx))); else @@ -1099,7 +1099,7 @@ public: /* StructFlags m_flags; */ int m_flags = StructFlags::none; - if (hasPointers (ti)) + if (dmd::hasPointers (ti)) m_flags |= StructFlags::hasPointers; this->layout_field (build_integer_cst (m_flags, d_uint_type)); @@ -1551,7 +1551,7 @@ create_typeinfo (Type *type, Module *mod, bool generate) create_frontend_tinfo_types (); /* Do this since not all Type's are merged. */ - Type *t = merge2 (type); + Type *t = dmd::merge2 (type); Identifier *ident; if (!t->vtinfo) diff --git a/gcc/d/types.cc b/gcc/d/types.cc index ed97aa3..9fa2f88 100644 --- a/gcc/d/types.cc +++ b/gcc/d/types.cc @@ -144,7 +144,7 @@ same_type_p (Type *t1, Type *t2) return true; /* Types are mutably the same type. */ - if (tb1->ty == tb2->ty && equivalent (tb1, tb2)) + if (tb1->ty == tb2->ty && dmd::equivalent (tb1, tb2)) return true; return false; @@ -1334,7 +1334,7 @@ build_ctype (Type *t) t->accept (&v); else { - Type *tb = castMod (t, 0); + Type *tb = dmd::castMod (t, 0); if (!tb->ctype) tb->accept (&v); t->ctype = insert_type_modifiers (tb->ctype, t->mod); diff --git a/gcc/testsuite/gdc.test/compilable/imports/test24390a.d b/gcc/testsuite/gdc.test/compilable/imports/test24390a.d new file mode 100644 index 0000000..0792c67 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test24390a.d @@ -0,0 +1,2 @@ +module imports.test24390a; +public import imports.test24390b; diff --git a/gcc/testsuite/gdc.test/compilable/imports/test24390b.d b/gcc/testsuite/gdc.test/compilable/imports/test24390b.d new file mode 100644 index 0000000..914553e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test24390b.d @@ -0,0 +1,9 @@ +module imports.test24390b; +static if (__traits(compiles, __vector(int[4])) && __traits(compiles, __vector(byte[16]))) +{ + __vector(int[4]) _mm_set1_epi8 (byte a) + { + __vector(byte[16]) b = a; + return cast(__vector(int[4]))b; + } +} diff --git a/gcc/testsuite/gdc.test/compilable/interpret3.d b/gcc/testsuite/gdc.test/compilable/interpret3.d index 1414263..69f65b1 100644 --- a/gcc/testsuite/gdc.test/compilable/interpret3.d +++ b/gcc/testsuite/gdc.test/compilable/interpret3.d @@ -2326,7 +2326,7 @@ struct Bug10840 Data10840* _data; } -bool bug10840(int n) +enum bug10840 = (int n) { Bug10840 stack; if (n == 1) @@ -2336,7 +2336,7 @@ bool bug10840(int n) } // Wrong-code for ?: return stack._data ? false : true; -} +}; static assert(bug10840(0)); static assert(!is(typeof(Compileable!(bug10840(1))))); @@ -5910,13 +5910,13 @@ struct Bug7527 char[] data; } -int bug7527() +enum bug7527 = () { auto app = Bug7527(); app.data.ptr[0 .. 1] = "x"; return 1; -} +}; static assert(!is(typeof(compiles!(bug7527())))); diff --git a/gcc/testsuite/gdc.test/compilable/test24390.d b/gcc/testsuite/gdc.test/compilable/test24390.d new file mode 100644 index 0000000..f02054d --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test24390.d @@ -0,0 +1,26 @@ +// PERMUTE_ARGS: -O -inline +// EXTRA_SOURCES: imports/test24390a.d imports/test24390b.d +static if (__traits(compiles, __vector(int[4])) && __traits(compiles, __vector(byte[16]))) +{ + import imports.test24390a; + + void main() + { + __vector(int[4]) mmA ; + __vector(int[4]) mmB ; + auto mask = _mm_cmpestrm(mmA, mmB); + } + + __vector(int[4]) _mm_cmpestrm(__vector(int[4]) mmA, __vector(int[4]) mmB) + { + __vector(int[4]) R; + for (int pos ; pos < 16; ++pos) + { + byte charK = (cast(__vector(byte[16]))mmA).array[pos]; + __vector(int[4]) eqMask = _mm_set1_epi8(charK); + R = R & eqMask; + + } + return R; + } +} diff --git a/gcc/testsuite/gdc.test/compilable/traits.d b/gcc/testsuite/gdc.test/compilable/traits.d index 3c65dac..d5e2cb0 100644 --- a/gcc/testsuite/gdc.test/compilable/traits.d +++ b/gcc/testsuite/gdc.test/compilable/traits.d @@ -316,3 +316,7 @@ extern(C++, `inst`) mixin GetNamespaceTestTemplatedMixin!() GNTT; static assert (__traits(getCppNamespaces, GNTT.foo) == Seq!(`inst`,/*`decl`,*/ `f`)); + +int[1] arr; +// test that index assignment parses as an expression, not a type +enum _ = __traits(compiles, arr[0] = 0); diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/issue21685.d b/gcc/testsuite/gdc.test/fail_compilation/imports/issue21685.d index eef95bf..cfc39de 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/imports/issue21685.d +++ b/gcc/testsuite/gdc.test/fail_compilation/imports/issue21685.d @@ -3,4 +3,5 @@ module issue21685; class E { private this() {} + public this(int) {} } diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue21685_main.d b/gcc/testsuite/gdc.test/fail_compilation/issue21685_main.d index c6e29c3..5b95d9b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/issue21685_main.d +++ b/gcc/testsuite/gdc.test/fail_compilation/issue21685_main.d @@ -1,7 +1,8 @@ /* REQUIRED_ARGS: -preview=dip1000 -Ifail_compilation/imports TEST_OUTPUT: --- -fail_compilation/issue21685_main.d(11): Error: class `issue21685.E` constructor `this` is not accessible +fail_compilation/issue21685_main.d(12): Error: constructor `issue21685.E.this` is not accessible from module `issue21685_main` +fail_compilation/issue21685_main.d(19): Error: constructor `issue21685.E.this` is not accessible from module `issue21685_main` --- */ import issue21685; @@ -10,3 +11,11 @@ void main() { new E; } + +class F : E +{ + this() + { + super(); + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23786.d b/gcc/testsuite/gdc.test/fail_compilation/test23786.d new file mode 100644 index 0000000..11fe5d4 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23786.d @@ -0,0 +1,39 @@ +/* TEST_OUTPUT: +--- +fail_compilation/test23786.d(22): Error: function `foo` is not callable using argument types `(double)` +fail_compilation/test23786.d(22): cannot pass argument `1.0` of type `double` to parameter `int i` +fail_compilation/test23786.d(19): `test23786.foo(int i)` declared here +fail_compilation/test23786.d(29): Error: function `bar` is not callable using argument types `(int*)` +fail_compilation/test23786.d(29): cannot pass argument `& i` of type `int*` to parameter `int i` +fail_compilation/test23786.d(26): `test23786.bar(int i)` declared here +fail_compilation/test23786.d(37): Error: function `baz` is not callable using argument types `(int*)` +fail_compilation/test23786.d(37): cannot pass argument `& i` of type `int*` to parameter `int i` +fail_compilation/test23786.d(34): `test23786.baz(int i)` declared here +--- +*/ + +// https://issues.dlang.org/show_bug.cgi?id=23786 + +module test23786; + +void foo(int i) +{ + static assert(__traits(parent, {}).mangleof == "_D9test237863fooFiZv"); + __traits(parent, {})(1.0); +} +void foo(int* p) {} + +void bar(int i) +{ + static assert(__traits(parent, {}).mangleof == "_D9test237863barFiZv"); + __traits(parent, {})(&i); +} +void bar(int* p) {} + +void baz(int* p) {} +void baz(int i) +{ + static assert(__traits(parent, {}).mangleof == "_D9test237863bazFiZv"); + __traits(parent, {})(&i); +} +void baz(float* p) {} diff --git a/gcc/testsuite/gdc.test/runnable/link15021.d b/gcc/testsuite/gdc.test/runnable/link15021.d index 2e82610..1c136fc 100644 --- a/gcc/testsuite/gdc.test/runnable/link15021.d +++ b/gcc/testsuite/gdc.test/runnable/link15021.d @@ -13,7 +13,7 @@ class AliasDecl {} void aliasDecl(AliasDecl ad) { - AliasDecl* zis; + AliasDecl* zis = &ad; static if (is(typeof(to!string(*zis)))) { diff --git a/gcc/testsuite/gdc.test/runnable/mars1.d b/gcc/testsuite/gdc.test/runnable/mars1.d index b24eced..f493eac 100644 --- a/gcc/testsuite/gdc.test/runnable/mars1.d +++ b/gcc/testsuite/gdc.test/runnable/mars1.d @@ -2479,6 +2479,19 @@ void test21835() } //////////////////////////////////////////////////////////////////////// +// https://github.com/dlang/dmd/pull/16187#issuecomment-1946534649 + +void testDoWhileContinue() +{ + int i = 10; + do + { + continue; + } + while(--i > 0); +} + +//////////////////////////////////////////////////////////////////////// int main() { @@ -2578,6 +2591,7 @@ int main() test21256(); test21816(); test21835(); + testDoWhileContinue(); printf("Success\n"); return 0; diff --git a/gcc/testsuite/gdc.test/runnable/staticaa.d b/gcc/testsuite/gdc.test/runnable/staticaa.d index e5b25d1..089144c4 100644 --- a/gcc/testsuite/gdc.test/runnable/staticaa.d +++ b/gcc/testsuite/gdc.test/runnable/staticaa.d @@ -165,6 +165,22 @@ void testEnumInit() ///////////////////////////////////////////// +// https://issues.dlang.org/show_bug.cgi?id=24370 +immutable uint[3][string] test = [ + "oneTwoThree": [1,2,3], + "fourFiveSix": [4,5,6], + "sevenEightNine": [7,8,9], +]; + +void testStaticArray() +{ + assert(test["oneTwoThree"] == [1, 2, 3]); + assert(test["fourFiveSix"] == [4, 5, 6]); + assert(test["sevenEightNine"] == [7, 8, 9]); +} + +///////////////////////////////////////////// + void main() { testSimple(); @@ -175,4 +191,5 @@ void main() testImmutable(); testLocalStatic(); testEnumInit(); + testStaticArray(); } diff --git a/gcc/testsuite/gdc.test/runnable_cxx/test7925.d b/gcc/testsuite/gdc.test/runnable_cxx/test7925.d index 2f52826..f05aac9 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/test7925.d +++ b/gcc/testsuite/gdc.test/runnable_cxx/test7925.d @@ -1,10 +1,10 @@ // EXTRA_CPP_SOURCES: cpp7925.cpp /* -Exclude -O due to a codegen bug on OSX: +Exclude -O/-inline due to a codegen bug on OSX: https://issues.dlang.org/show_bug.cgi?id=22556 -PERMUTE_ARGS(osx): -inline -release -g +PERMUTE_ARGS(osx): -release -g */ import core.vararg; |