diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2019-04-18 09:50:56 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-04-01 00:12:47 +0200 |
commit | 013fca64fc17ba646c3564eab52fac50f0751188 (patch) | |
tree | c75868fd2d0b82c3e4ba548430629646ea5fb681 /gcc/d/decl.cc | |
parent | 1c16f7fc903c1c1c912faf7889b69d83429b7b2e (diff) | |
download | gcc-013fca64fc17ba646c3564eab52fac50f0751188.zip gcc-013fca64fc17ba646c3564eab52fac50f0751188.tar.gz gcc-013fca64fc17ba646c3564eab52fac50f0751188.tar.bz2 |
d: Merge UDAs between function prototype and definitions (PR90136)
This change fixes the symbol merging in get_symbol_decl to also consider
prototypes. This allows the ability to set user defined attributes on
the prototype of a function, which then get applied to the definition,
if found later in the compilation.
The lowering of UDAs to GCC attributes has been commonized into a single
function called apply_user_attributes.
gcc/d/ChangeLog:
PR d/90136
* d-attribs.cc: Include dmd/attrib.h.
(build_attributes): Redeclare as static.
(apply_user_attributes): New function.
* d-tree.h (class UserAttributeDeclaration): Remove.
(build_attributes): Remove.
(apply_user_attributes): Declare.
(finish_aggregate_type): Remove attrs argument.
* decl.cc (get_symbol_decl): Merge declaration prototypes with
definitions. Use apply_user_attributes.
* modules.cc (layout_moduleinfo_fields): Remove last argument to
finish_aggregate_type.
* typeinfo.cc (layout_classinfo_interfaces): Likewise.
* types.cc (layout_aggregate_members): Likewise.
(finish_aggregate_type): Remove attrs argument.
(TypeVisitor::visit (TypeEnum *)): Use apply_user_attributes.
(TypeVisitor::visit (TypeStruct *)): Remove last argument to
finish_aggregate_type. Use apply_user_attributes.
(TypeVisitor::visit (TypeClass *)): Likewise.
gcc/testsuite/ChangeLog:
PR d/90136
* gdc.dg/pr90136a.d: New test.
* gdc.dg/pr90136b.d: New test.
* gdc.dg/pr90136c.d: New test.
Diffstat (limited to 'gcc/d/decl.cc')
-rw-r--r-- | gcc/d/decl.cc | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 053d553..042c10c 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -1110,7 +1110,10 @@ get_symbol_decl (Declaration *decl) /* Set function type afterwards as there could be self references. */ TREE_TYPE (decl->csym) = build_ctype (fd->type); - if (!fd->fbody) + /* Set DECL_INITIAL now if the function has a definition. */ + if (fd->fbody) + DECL_INITIAL (decl->csym) = error_mark_node; + else DECL_EXTERNAL (decl->csym) = 1; } else @@ -1151,26 +1154,38 @@ get_symbol_decl (Declaration *decl) mangled_name); /* The frontend doesn't handle duplicate definitions of unused symbols with the same mangle. So a check is done here instead. */ - if (!DECL_EXTERNAL (decl->csym)) + if (IDENTIFIER_DSYMBOL (mangled_name)) { - if (IDENTIFIER_DSYMBOL (mangled_name)) - { - Declaration *other = IDENTIFIER_DSYMBOL (mangled_name); + Declaration *other = IDENTIFIER_DSYMBOL (mangled_name); + tree olddecl = decl->csym; + decl->csym = get_symbol_decl (other); - /* Non-templated variables shouldn't be defined twice. */ - if (!decl->isInstantiated ()) - ScopeDsymbol::multiplyDefined (decl->loc, decl, other); - - decl->csym = get_symbol_decl (other); + /* The current declaration is a prototype or marked extern, merge + applied user attributes and return. */ + if (DECL_EXTERNAL (olddecl) && !DECL_INITIAL (olddecl)) + { + apply_user_attributes (decl, decl->csym); return decl->csym; } - + /* The previous declaration is a prototype or marked extern, set the + current declaration as the main reference of the symbol. */ + else if (DECL_EXTERNAL (decl->csym) && !DECL_INITIAL (decl->csym)) + { + IDENTIFIER_DSYMBOL (mangled_name) = decl; + DECL_EXTERNAL (decl->csym) = 0; + } + /* Non-extern, non-templated decls shouldn't be defined twice. */ + else if (!decl->isInstantiated ()) + ScopeDsymbol::multiplyDefined (decl->loc, decl, other); + } + else + { IDENTIFIER_PRETTY_NAME (mangled_name) = get_identifier (decl->toPrettyChars (true)); IDENTIFIER_DSYMBOL (mangled_name) = decl; - } - SET_DECL_ASSEMBLER_NAME (decl->csym, mangled_name); + SET_DECL_ASSEMBLER_NAME (decl->csym, mangled_name); + } } DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (decl); @@ -1358,13 +1373,7 @@ get_symbol_decl (Declaration *decl) } /* Apply any user attributes that may affect semantic meaning. */ - if (decl->userAttribDecl) - { - Expressions *attrs = decl->userAttribDecl->getAttributes (); - decl_attributes (&decl->csym, build_attributes (attrs), 0); - } - else if (DECL_ATTRIBUTES (decl->csym) != NULL) - decl_attributes (&decl->csym, DECL_ATTRIBUTES (decl->csym), 0); + apply_user_attributes (decl, decl->csym); /* %% Probably should be a little more intelligent about setting this. */ TREE_USED (decl->csym) = 1; |