diff options
Diffstat (limited to 'gcc/d/decl.cc')
-rw-r--r-- | gcc/d/decl.cc | 104 |
1 files changed, 57 insertions, 47 deletions
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 0a87c85..9ddf7cf 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -1,5 +1,5 @@ /* decl.cc -- Lower D frontend declarations to GCC trees. - Copyright (C) 2006-2024 Free Software Foundation, Inc. + Copyright (C) 2006-2025 Free Software Foundation, Inc. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "dmd/nspace.h" #include "dmd/target.h" #include "dmd/template.h" +#include "dmd/typinf.h" #include "tree.h" #include "tree-iterator.h" @@ -255,18 +256,18 @@ public: void visit (Module *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; build_module_tree (d); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Write the imported symbol to debug. */ void visit (Import *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; /* Implements import declarations by telling the debug back-end we are @@ -319,7 +320,7 @@ public: false, false); } - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Finish a top-level `asm` definition. */ @@ -350,7 +351,7 @@ public: void visit (AttribDeclaration *d) final override { - Dsymbols *ds = d->include (NULL); + Dsymbols *ds = dmd::include (d, NULL); if (!ds) return; @@ -471,7 +472,7 @@ public: void visit (StructDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (d->type->ty == TY::Terror) @@ -519,7 +520,7 @@ public: if (d->xhash) this->build_dsymbol (d->xhash); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Finish semantic analysis of functions in vtbl for class CD. */ @@ -541,7 +542,7 @@ public: has_errors = true; /* No name hiding to check for. */ - if (!d->isFuncHidden (fd) || fd->isFuture ()) + if (!dmd::isFuncHidden (d, fd) || fd->isFuture ()) continue; /* The function fd is hidden from the view of the class. @@ -561,10 +562,8 @@ public: if (fd2->isFuture ()) continue; - if (FuncDeclaration::leastAsSpecialized (fd, fd2, NULL) - == MATCH::nomatch - && FuncDeclaration::leastAsSpecialized (fd2, fd, NULL) - == MATCH::nomatch) + if (dmd::leastAsSpecialized (fd, fd2, NULL) == MATCH::nomatch + && dmd::leastAsSpecialized (fd2, fd, NULL) == MATCH::nomatch) continue; /* Hiding detected; same name, overlapping specializations. */ @@ -589,7 +588,7 @@ public: void visit (ClassDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (d->type->ty == TY::Terror) @@ -618,7 +617,7 @@ public: /* Generate C symbols. */ d->csym = get_classinfo_decl (d); - Dsymbol *vtblsym = d->vtblSymbol (); + Dsymbol *vtblsym = dmd::vtblSymbol (d); vtblsym->csym = get_vtable_decl (d); tree sinit = aggregate_initializer_decl (d); @@ -652,10 +651,10 @@ public: } DECL_INITIAL (vtblsym->csym) - = build_constructor (TREE_TYPE (vtblsym->csym), elms); + = build_padded_constructor (TREE_TYPE (vtblsym->csym), elms); d_finish_decl (vtblsym->csym); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Write out compiler generated TypeInfo and vtables for the given interface @@ -663,7 +662,7 @@ public: void visit (InterfaceDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (d->type->ty == TY::Terror) @@ -698,7 +697,7 @@ public: DECL_INITIAL (d->csym) = layout_classinfo (d); d_finish_decl (d->csym); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Write out compiler generated TypeInfo and initializer for the given @@ -706,10 +705,10 @@ public: void visit (EnumDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; - if (d->errors || d->type->ty == TY::Terror) + if (d->errors () || d->type->ty == TY::Terror) { error_at (make_location_t (d->loc), "had semantic errors when compiling"); @@ -729,7 +728,7 @@ public: create_typeinfo (d->type, NULL); TypeEnum *tc = d->type->isTypeEnum (); - if (tc->sym->members && !d->type->isZeroInit ()) + if (tc->sym->members && !dmd::isZeroInit (d->type)) { /* Generate static initializer. */ d->sinit = enum_initializer_decl (d); @@ -737,7 +736,7 @@ public: d_finish_decl (d->sinit); } - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Finish up a variable declaration and push it into the current scope. @@ -745,7 +744,7 @@ public: void visit (VarDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; if (d->type->ty == TY::Terror) @@ -783,7 +782,7 @@ public: { /* Do not store variables we cannot take the address of, but keep the values for purposes of debugging. */ - if (d->type->isscalar () && !dmd::hasPointers (d->type)) + if (d->type->isScalar () && !dmd::hasPointers (d->type)) { tree decl = get_symbol_decl (d); d_pushdecl (decl); @@ -792,6 +791,12 @@ public: } else if (d->isDataseg ()) { + /* When the front-end type size is invalid, an error has already been + given for the declaration or type. */ + dinteger_t size = dmd::size (d->type, d->loc); + if (size == SIZE_INVALID) + return; + tree decl = get_symbol_decl (d); /* Only need to build the VAR_DECL for extern declarations. */ @@ -805,9 +810,7 @@ public: return; /* How big a symbol can be should depend on back-end. */ - tree size = build_integer_cst (d->type->size (d->loc), - build_ctype (Type::tsize_t)); - if (!valid_constant_size_p (size)) + if (!valid_constant_size_p (build_integer_cst (size, size_type_node))) { error_at (make_location_t (d->loc), "size is too large"); return; @@ -823,7 +826,7 @@ public: DECL_INITIAL (decl) = build_expr (e, true); } } - else if (!d->type->isZeroInit ()) + else if (!dmd::isZeroInit (d->type)) { /* Use default initializer for the type. */ if (TypeStruct *ts = d->type->isTypeStruct ()) @@ -836,8 +839,9 @@ public: } /* Frontend should have already caught this. */ - gcc_assert (!integer_zerop (size) - || d->type->toBasetype ()->isTypeSArray ()); + gcc_assert ((size != 0 && size != SIZE_INVALID) + || d->type->toBasetype ()->isTypeSArray () + || d->isCsymbol ()); d_finish_decl (decl); @@ -890,7 +894,7 @@ public: } } - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Generate and compile a static TypeInfo declaration, but only if it is @@ -898,16 +902,16 @@ public: void visit (TypeInfoDeclaration *d) final override { - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; - if (speculative_type_p (d->tinfo)) + if (dmd::isSpeculativeType (d->tinfo)) return; tree t = get_typeinfo_decl (d); DECL_INITIAL (t) = layout_typeinfo (d); d_finish_decl (t); - d->semanticRun = PASS::obj; + d->semanticRun (PASS::obj); } /* Finish up a function declaration and compile it all the way @@ -916,7 +920,7 @@ public: void visit (FuncDeclaration *d) final override { /* Already generated the function. */ - if (d->semanticRun >= PASS::obj) + if (d->semanticRun () >= PASS::obj) return; /* Don't emit any symbols from gcc.attributes module. */ @@ -958,7 +962,7 @@ public: } /* Ensure all semantic passes have run. */ - if (d->semanticRun < PASS::semantic3) + if (d->semanticRun () < PASS::semantic3) { gcc_assert (!doing_semantic_analysis_p); @@ -972,8 +976,8 @@ public: return; /* Start generating code for this function. */ - gcc_assert (d->semanticRun == PASS::semantic3done); - d->semanticRun = PASS::obj; + gcc_assert (d->semanticRun () == PASS::semantic3done); + d->semanticRun (PASS::obj); /* Duplicated FuncDeclarations map to the same symbol. Check if this is the one declaration which will be emitted. */ @@ -1116,7 +1120,7 @@ build_decl_tree (Dsymbol *d) if (d->loc.filename ()) input_location = make_location_t (d->loc); else - input_location = make_location_t (Loc ("<no_file>", 1, 0)); + input_location = make_location_t (Loc::singleFilename ("<no_file>")); DeclVisitor v = DeclVisitor (); v.build_dsymbol (d); @@ -1180,7 +1184,7 @@ maybe_build_decl_tree (Declaration *decl) /* Still running semantic analysis on declaration, or it has already had its code generated. */ - if (doing_semantic_analysis_p || decl->semanticRun >= PASS::obj) + if (doing_semantic_analysis_p || decl->semanticRun () >= PASS::obj) return decl->csym; if (error_operand_p (decl->csym)) @@ -1247,7 +1251,7 @@ get_symbol_decl (Declaration *decl) /* CONST_DECL was initially intended for enumerals and may be used for scalars in general, but not for aggregates. Here a non-constant value is generated anyway so as its value can be used. */ - if (!vd->canTakeAddressOf () && !vd->type->isscalar ()) + if (!vd->canTakeAddressOf () && !vd->type->isScalar ()) { gcc_assert (vd->_init && !vd->_init->isVoidInitializer ()); Expression *ie = dmd::initializerToExpression (vd->_init); @@ -1308,7 +1312,7 @@ get_symbol_decl (Declaration *decl) /* Cannot make an expression out of a void initializer. */ gcc_assert (vd->_init && !vd->_init->isVoidInitializer ()); /* Non-scalar manifest constants have already been dealt with. */ - gcc_assert (vd->type->isscalar ()); + gcc_assert (vd->type->isScalar ()); Expression *ie = dmd::initializerToExpression (vd->_init); DECL_INITIAL (decl->csym) = build_expr (ie, true); @@ -1325,7 +1329,7 @@ get_symbol_decl (Declaration *decl) /* `const` applies to data that cannot be changed by the const reference to that data. It may, however, be changed by another reference to that same data. */ - if (vd->isConst () && !vd->isDataseg ()) + if (vd->isConst () && !vd->isResult () && !vd->isDataseg ()) TREE_READONLY (decl->csym) = 1; } @@ -2213,7 +2217,7 @@ get_vtable_decl (ClassDeclaration *decl) will have a different type. However the back-end seems to accept this. */ tree type = build_ctype (dmd::sarrayOf (Type::tvoidptr, decl->vtbl.length)); - Dsymbol *vtblsym = decl->vtblSymbol (); + Dsymbol *vtblsym = dmd::vtblSymbol (decl); vtblsym->csym = declare_extern_var (ident, type); DECL_LANG_SPECIFIC (vtblsym->csym) = build_lang_decl (NULL); @@ -2394,6 +2398,12 @@ aggregate_initializer_decl (AggregateDeclaration *decl) SET_DECL_ALIGN (sinit, sd->alignment.get () * BITS_PER_UNIT); DECL_USER_ALIGN (sinit) = true; } + else if (sd == NULL) + { + /* Alignment of class is determined its biggest field alignment. */ + SET_DECL_ALIGN (sinit, decl->alignsize * BITS_PER_UNIT); + DECL_USER_ALIGN (sinit) = true; + } decl->sinit = sinit; return sinit; @@ -2404,7 +2414,7 @@ aggregate_initializer_decl (AggregateDeclaration *decl) tree layout_class_initializer (ClassDeclaration *cd) { - NewExp *ne = NewExp::create (cd->loc, NULL, cd->type, NULL); + NewExp *ne = NewExp::create (cd->loc, NULL, NULL, cd->type, NULL); ne->type = cd->type; Expression *e = dmd::ctfeInterpret (ne); @@ -2418,7 +2428,7 @@ layout_struct_initializer (StructDeclaration *sd) { StructLiteralExp *sle = StructLiteralExp::create (sd->loc, sd, NULL); - if (!sd->fill (sd->loc, *sle->elements, true)) + if (!dmd::fill (sd, sd->loc, *sle->elements, true)) gcc_unreachable (); sle->type = sd->type; |