aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/decl.cc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2019-04-18 09:50:56 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-04-01 00:12:47 +0200
commit013fca64fc17ba646c3564eab52fac50f0751188 (patch)
treec75868fd2d0b82c3e4ba548430629646ea5fb681 /gcc/d/decl.cc
parent1c16f7fc903c1c1c912faf7889b69d83429b7b2e (diff)
downloadgcc-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.cc49
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;