Excerpts from David Malcolm via Gcc-patches's message of Mai 23, 2022 9:28 pm: > gcc/d/ChangeLog: > * decl.cc: Add "final" and "override" to all "visit" vfunc decls > as appropriate. > * expr.cc: Likewise. > * toir.cc: Likewise. > * typeinfo.cc: Likewise. > * types.cc: Likewise. > > Signed-off-by: David Malcolm <dmalc...@redhat.com>
Thanks David! Looks OK to me. Iain. > --- > gcc/d/decl.cc | 36 +++++++++++++------------- > gcc/d/expr.cc | 2 +- > gcc/d/toir.cc | 64 +++++++++++++++++++++++------------------------ > gcc/d/typeinfo.cc | 34 ++++++++++++------------- > gcc/d/types.cc | 30 +++++++++++----------- > 5 files changed, 83 insertions(+), 83 deletions(-) > > diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc > index f5c21078aad..5d850065bf0 100644 > --- a/gcc/d/decl.cc > +++ b/gcc/d/decl.cc > @@ -149,13 +149,13 @@ public: > > /* This should be overridden by each declaration class. */ > > - void visit (Dsymbol *) > + void visit (Dsymbol *) final override > { > } > > /* Compile a D module, and all members of it. */ > > - void visit (Module *d) > + void visit (Module *d) final override > { > if (d->semanticRun >= PASS::obj) > return; > @@ -166,7 +166,7 @@ public: > > /* Write the imported symbol to debug. */ > > - void visit (Import *d) > + void visit (Import *d) final override > { > if (d->semanticRun >= PASS::obj) > return; > @@ -218,7 +218,7 @@ public: > > /* Expand any local variables found in tuples. */ > > - void visit (TupleDeclaration *d) > + void visit (TupleDeclaration *d) final override > { > for (size_t i = 0; i < d->objects->length; i++) > { > @@ -234,7 +234,7 @@ public: > > /* Walk over all declarations in the attribute scope. */ > > - void visit (AttribDeclaration *d) > + void visit (AttribDeclaration *d) final override > { > Dsymbols *ds = d->include (NULL); > > @@ -248,7 +248,7 @@ public: > /* Pragmas are a way to pass special information to the compiler and to add > vendor specific extensions to D. */ > > - void visit (PragmaDeclaration *d) > + void visit (PragmaDeclaration *d) final override > { > if (d->ident == Identifier::idPool ("lib") > || d->ident == Identifier::idPool ("startaddress")) > @@ -266,7 +266,7 @@ public: > /* Conditional compilation is the process of selecting which code to > compile > and which code to not compile. Look for version conditions that may */ > > - void visit (ConditionalDeclaration *d) > + void visit (ConditionalDeclaration *d) final override > { > bool old_condition = this->in_version_unittest_; > > @@ -284,7 +284,7 @@ public: > > /* Walk over all members in the namespace scope. */ > > - void visit (Nspace *d) > + void visit (Nspace *d) final override > { > if (isError (d) || !d->members) > return; > @@ -298,7 +298,7 @@ public: > voldemort type, then it's members must be compiled before the parent > function finishes. */ > > - void visit (TemplateDeclaration *d) > + void visit (TemplateDeclaration *d) final override > { > /* Type cannot be directly named outside of the scope it's declared in, > so > the only way it can be escaped is if the function has auto return. */ > @@ -329,7 +329,7 @@ public: > > /* Walk over all members in the instantiated template. */ > > - void visit (TemplateInstance *d) > + void visit (TemplateInstance *d) final override > { > if (isError (d)|| !d->members) > return; > @@ -343,7 +343,7 @@ public: > > /* Walk over all members in the mixin template scope. */ > > - void visit (TemplateMixin *d) > + void visit (TemplateMixin *d) final override > { > if (isError (d)|| !d->members) > return; > @@ -355,7 +355,7 @@ public: > /* Write out compiler generated TypeInfo, initializer and functions for the > given struct declaration, walking over all static members. */ > > - void visit (StructDeclaration *d) > + void visit (StructDeclaration *d) final override > { > if (d->semanticRun >= PASS::obj) > return; > @@ -470,7 +470,7 @@ public: > /* Write out compiler generated TypeInfo, initializer and vtables for the > given class declaration, walking over all static members. */ > > - void visit (ClassDeclaration *d) > + void visit (ClassDeclaration *d) final override > { > if (d->semanticRun >= PASS::obj) > return; > @@ -544,7 +544,7 @@ public: > /* Write out compiler generated TypeInfo and vtables for the given > interface > declaration, walking over all static members. */ > > - void visit (InterfaceDeclaration *d) > + void visit (InterfaceDeclaration *d) final override > { > if (d->semanticRun >= PASS::obj) > return; > @@ -587,7 +587,7 @@ public: > /* Write out compiler generated TypeInfo and initializer for the given > enum declaration. */ > > - void visit (EnumDeclaration *d) > + void visit (EnumDeclaration *d) final override > { > if (d->semanticRun >= PASS::obj) > return; > @@ -626,7 +626,7 @@ public: > /* Finish up a variable declaration and push it into the current scope. > This can either be a static, local or manifest constant. */ > > - void visit (VarDeclaration *d) > + void visit (VarDeclaration *d) final override > { > if (d->semanticRun >= PASS::obj) > return; > @@ -753,7 +753,7 @@ public: > /* Generate and compile a static TypeInfo declaration, but only if it is > needed in the current compilation. */ > > - void visit (TypeInfoDeclaration *d) > + void visit (TypeInfoDeclaration *d) final override > { > if (d->semanticRun >= PASS::obj) > return; > @@ -770,7 +770,7 @@ public: > /* Finish up a function declaration and compile it all the way > down to assembler language output. */ > > - void visit (FuncDeclaration *d) > + void visit (FuncDeclaration *d) final override > { > /* Already generated the function. */ > if (d->semanticRun >= PASS::obj) > diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc > index 7f5e683a676..c259e7df6d5 100644 > --- a/gcc/d/expr.cc > +++ b/gcc/d/expr.cc > @@ -2556,7 +2556,7 @@ public: > /* Build a tuple literal. Just an argument list that may have > side effects that need evaluation. */ > > - void visit (TupleExp *e) > + void visit (TupleExp *e) final override > { > tree result = NULL_TREE; > > diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc > index d20c5c3b927..50d44156cca 100644 > --- a/gcc/d/toir.cc > +++ b/gcc/d/toir.cc > @@ -534,7 +534,7 @@ public: > > /* This should be overridden by each statement class. */ > > - void visit (Statement *) > + void visit (Statement *) final override > { > gcc_unreachable (); > } > @@ -543,13 +543,13 @@ public: > try/catch/finally. At this point, this statement is just an empty > placeholder. Maybe the frontend shouldn't leak these. */ > > - void visit (ScopeGuardStatement *) > + void visit (ScopeGuardStatement *) final override > { > } > > /* If statements provide simple conditional execution of statements. */ > > - void visit (IfStatement *s) > + void visit (IfStatement *s) final override > { > this->start_scope (level_cond); > > @@ -588,7 +588,7 @@ public: > here would be the place to do it. For now, all pragmas are handled > by the frontend. */ > > - void visit (PragmaStatement *) > + void visit (PragmaStatement *) final override > { > } > > @@ -596,7 +596,7 @@ public: > This visitor is not strictly required other than to enforce that > these kinds of statements never reach here. */ > > - void visit (WhileStatement *) > + void visit (WhileStatement *) final override > { > gcc_unreachable (); > } > @@ -604,7 +604,7 @@ public: > /* Do while statments implement simple loops. The body is executed, then > the condition is evaluated. */ > > - void visit (DoStatement *s) > + void visit (DoStatement *s) final override > { > tree lbreak = this->push_break_label (s); > > @@ -633,7 +633,7 @@ public: > /* For statements implement loops with initialization, test, and > increment clauses. */ > > - void visit (ForStatement *s) > + void visit (ForStatement *s) final override > { > tree lbreak = this->push_break_label (s); > this->start_scope (level_loop); > @@ -674,7 +674,7 @@ public: > This visitor is not strictly required other than to enforce that > these kinds of statements never reach here. */ > > - void visit (ForeachStatement *) > + void visit (ForeachStatement *) final override > { > gcc_unreachable (); > } > @@ -683,7 +683,7 @@ public: > loops. This visitor is not strictly required other than to enforce that > these kinds of statements never reach here. */ > > - void visit (ForeachRangeStatement *) > + void visit (ForeachRangeStatement *) final override > { > gcc_unreachable (); > } > @@ -691,7 +691,7 @@ public: > /* Jump to the associated exit label for the current loop. If IDENT > for the Statement is not null, then the label is user defined. */ > > - void visit (BreakStatement *s) > + void visit (BreakStatement *s) final override > { > if (s->ident) > { > @@ -710,7 +710,7 @@ public: > /* Jump to the associated continue label for the current loop. If IDENT > for the Statement is not null, then the label is user defined. */ > > - void visit (ContinueStatement *s) > + void visit (ContinueStatement *s) final override > { > if (s->ident) > { > @@ -726,7 +726,7 @@ public: > > /* A goto statement jumps to the statement identified by the given label. > */ > > - void visit (GotoStatement *s) > + void visit (GotoStatement *s) final override > { > gcc_assert (s->label->statement != NULL); > gcc_assert (s->tf == s->label->statement->tf); > @@ -742,7 +742,7 @@ public: > /* Statements can be labeled. A label is an identifier that precedes > a statement. */ > > - void visit (LabelStatement *s) > + void visit (LabelStatement *s) final override > { > LabelDsymbol *sym; > > @@ -766,7 +766,7 @@ public: > /* A switch statement goes to one of a collection of case statements > depending on the value of the switch expression. */ > > - void visit (SwitchStatement *s) > + void visit (SwitchStatement *s) final override > { > this->start_scope (level_switch); > tree lbreak = this->push_break_label (s); > @@ -855,7 +855,7 @@ public: > > /* Declare the case label associated with the current SwitchStatement. */ > > - void visit (CaseStatement *s) > + void visit (CaseStatement *s) final override > { > /* Emit the case label. */ > tree label = this->define_label (s); > @@ -881,7 +881,7 @@ public: > > /* Declare the default label associated with the current SwitchStatement. > */ > > - void visit (DefaultStatement *s) > + void visit (DefaultStatement *s) final override > { > /* Emit the default case label. */ > tree label = this->define_label (s); > @@ -902,7 +902,7 @@ public: > /* Implements `goto default' by jumping to the label associated with > the DefaultStatement in a switch block. */ > > - void visit (GotoDefaultStatement *s) > + void visit (GotoDefaultStatement *s) final override > { > tree label = this->lookup_label (s->sw->sdefault); > this->do_jump (label); > @@ -911,7 +911,7 @@ public: > /* Implements `goto case' by jumping to the label associated with the > CaseStatement in a switch block. */ > > - void visit (GotoCaseStatement *s) > + void visit (GotoCaseStatement *s) final override > { > tree label = this->lookup_label (s->cs); > this->do_jump (label); > @@ -920,7 +920,7 @@ public: > /* Throw a SwitchError exception, called when a switch statement has > no DefaultStatement, yet none of the cases match. */ > > - void visit (SwitchErrorStatement *s) > + void visit (SwitchErrorStatement *s) final override > { > /* A throw SwitchError statement gets turned into a library call. > The call is wrapped in the enclosed expression. */ > @@ -931,7 +931,7 @@ public: > /* A return statement exits the current function and supplies its return > value, if the return type is not void. */ > > - void visit (ReturnStatement *s) > + void visit (ReturnStatement *s) final override > { > if (s->exp == NULL || s->exp->type->toBasetype ()->ty == TY::Tvoid) > { > @@ -1044,7 +1044,7 @@ public: > > /* Evaluate the enclosed expression, and add it to the statement list. */ > > - void visit (ExpStatement *s) > + void visit (ExpStatement *s) final override > { > if (s->exp) > { > @@ -1056,7 +1056,7 @@ public: > > /* Evaluate all enclosed statements. */ > > - void visit (CompoundStatement *s) > + void visit (CompoundStatement *s) final override > { > if (s->statements == NULL) > return; > @@ -1074,7 +1074,7 @@ public: > These are compiled down as a `do ... while (0)', where each unrolled > loop > is nested inside and given their own continue label to jump to. */ > > - void visit (UnrolledLoopStatement *s) > + void visit (UnrolledLoopStatement *s) final override > { > if (s->statements == NULL) > return; > @@ -1105,7 +1105,7 @@ public: > /* Start a new scope and visit all nested statements, wrapping > them up into a BIND_EXPR at the end of the scope. */ > > - void visit (ScopeStatement *s) > + void visit (ScopeStatement *s) final override > { > if (s->statement == NULL) > return; > @@ -1118,7 +1118,7 @@ public: > /* A with statement is a way to simplify repeated references to the same > object, where the handle is either a class or struct instance. */ > > - void visit (WithStatement *s) > + void visit (WithStatement *s) final override > { > this->start_scope (level_with); > > @@ -1143,7 +1143,7 @@ public: > thrown is a class type, but does not check if it is derived from > Object. Foreign objects are not currently supported at run-time. */ > > - void visit (ThrowStatement *s) > + void visit (ThrowStatement *s) final override > { > ClassDeclaration *cd = s->exp->type->toBasetype ()->isClassHandle (); > InterfaceDeclaration *id = cd->isInterfaceDeclaration (); > @@ -1174,7 +1174,7 @@ public: > handling generated by the frontend. This is also used to implement > `scope (failure)' statements. */ > > - void visit (TryCatchStatement *s) > + void visit (TryCatchStatement *s) final override > { > this->start_scope (level_try); > if (s->_body) > @@ -1263,7 +1263,7 @@ public: > handling generated by the frontend. This is also used to implement > `scope (exit)' statements. */ > > - void visit (TryFinallyStatement *s) > + void visit (TryFinallyStatement *s) final override > { > this->start_scope (level_try); > if (s->_body) > @@ -1285,7 +1285,7 @@ public: > This visitor is not strictly required other than to enforce that > these kinds of statements never reach here. */ > > - void visit (SynchronizedStatement *) > + void visit (SynchronizedStatement *) final override > { > gcc_unreachable (); > } > @@ -1294,7 +1294,7 @@ public: > an assembly parser for each supported target. Instead we leverage > GCC extended assembler using the GccAsmStatement class. */ > > - void visit (AsmStatement *) > + void visit (AsmStatement *) final override > { > sorry ("D inline assembler statements are not supported in GDC."); > } > @@ -1302,7 +1302,7 @@ public: > /* Build a GCC extended assembler expression, whose components are > an INSN string, some OUTPUTS, some INPUTS, and some CLOBBERS. */ > > - void visit (GccAsmStatement *s) > + void visit (GccAsmStatement *s) final override > { > StringExp *insn = s->insn->toStringExp (); > tree outputs = NULL_TREE; > @@ -1454,7 +1454,7 @@ public: > > /* Import symbols from another module. */ > > - void visit (ImportStatement *s) > + void visit (ImportStatement *s) final override > { > if (s->imports == NULL) > return; > diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc > index 668b7b3c8e1..a31762fe270 100644 > --- a/gcc/d/typeinfo.cc > +++ b/gcc/d/typeinfo.cc > @@ -556,7 +556,7 @@ public: > void **__vptr; > void *__monitor; */ > > - void visit (TypeInfoDeclaration *) > + void visit (TypeInfoDeclaration *) final override > { > /* The vtable for TypeInfo. */ > this->layout_base (Type::dtypeinfo); > @@ -567,7 +567,7 @@ public: > void *__monitor; > TypeInfo base; */ > > - void visit (TypeInfoConstDeclaration *d) > + void visit (TypeInfoConstDeclaration *d) final override > { > Type *tm = d->tinfo->mutableOf (); > tm = tm->merge2 (); > @@ -584,7 +584,7 @@ public: > void *__monitor; > TypeInfo base; */ > > - void visit (TypeInfoInvariantDeclaration *d) > + void visit (TypeInfoInvariantDeclaration *d) final override > { > Type *tm = d->tinfo->mutableOf (); > tm = tm->merge2 (); > @@ -601,7 +601,7 @@ public: > void *__monitor; > TypeInfo base; */ > > - void visit (TypeInfoSharedDeclaration *d) > + void visit (TypeInfoSharedDeclaration *d) final override > { > Type *tm = d->tinfo->unSharedOf (); > tm = tm->merge2 (); > @@ -618,7 +618,7 @@ public: > void *__monitor; > TypeInfo base; */ > > - void visit (TypeInfoWildDeclaration *d) > + void visit (TypeInfoWildDeclaration *d) final override > { > Type *tm = d->tinfo->mutableOf (); > tm = tm->merge2 (); > @@ -637,7 +637,7 @@ public: > string name; > void[] m_init; */ > > - void visit (TypeInfoEnumDeclaration *d) > + void visit (TypeInfoEnumDeclaration *d) final override > { > TypeEnum *ti = d->tinfo->isTypeEnum (); > EnumDeclaration *ed = ti->sym; > @@ -669,7 +669,7 @@ public: > void *__monitor; > TypeInfo m_next; */ > > - void visit (TypeInfoPointerDeclaration *d) > + void visit (TypeInfoPointerDeclaration *d) final override > { > TypePointer *ti = d->tinfo->isTypePointer (); > > @@ -685,7 +685,7 @@ public: > void *__monitor; > TypeInfo value; */ > > - void visit (TypeInfoArrayDeclaration *d) > + void visit (TypeInfoArrayDeclaration *d) final override > { > TypeDArray *ti = d->tinfo->isTypeDArray (); > > @@ -702,7 +702,7 @@ public: > TypeInfo value; > size_t len; */ > > - void visit (TypeInfoStaticArrayDeclaration *d) > + void visit (TypeInfoStaticArrayDeclaration *d) final override > { > TypeSArray *ti = d->tinfo->isTypeSArray (); > > @@ -722,7 +722,7 @@ public: > TypeInfo value; > TypeInfo key; */ > > - void visit (TypeInfoAssociativeArrayDeclaration *d) > + void visit (TypeInfoAssociativeArrayDeclaration *d) final override > { > TypeAArray *ti = d->tinfo->isTypeAArray (); > > @@ -741,7 +741,7 @@ public: > void *__monitor; > TypeInfo base; */ > > - void visit (TypeInfoVectorDeclaration *d) > + void visit (TypeInfoVectorDeclaration *d) final override > { > TypeVector *ti = d->tinfo->isTypeVector (); > > @@ -758,7 +758,7 @@ public: > TypeInfo next; > string deco; */ > > - void visit (TypeInfoFunctionDeclaration *d) > + void visit (TypeInfoFunctionDeclaration *d) final override > { > TypeFunction *ti = d->tinfo->isTypeFunction (); > gcc_assert (ti->deco != NULL); > @@ -779,7 +779,7 @@ public: > TypeInfo next; > string deco; */ > > - void visit (TypeInfoDelegateDeclaration *d) > + void visit (TypeInfoDelegateDeclaration *d) final override > { > TypeDelegate *ti = d->tinfo->isTypeDelegate (); > gcc_assert (ti->deco != NULL); > @@ -813,7 +813,7 @@ public: > Information relating to interfaces, and their vtables are laid out > immediately after the named fields, if there is anything to write. */ > > - void visit (TypeInfoClassDeclaration *d) > + void visit (TypeInfoClassDeclaration *d) final override > { > TypeClass *ti = d->tinfo->isTypeClass (); > ClassDeclaration *cd = ti->sym; > @@ -1004,7 +1004,7 @@ public: > void *__monitor; > TypeInfo_Class info; */ > > - void visit (TypeInfoInterfaceDeclaration *d) > + void visit (TypeInfoInterfaceDeclaration *d) final override > { > TypeClass *ti = d->tinfo->isTypeClass (); > > @@ -1034,7 +1034,7 @@ public: > uint m_align; > immutable(void)* xgetRTInfo; */ > > - void visit (TypeInfoStructDeclaration *d) > + void visit (TypeInfoStructDeclaration *d) final override > { > TypeStruct *ti = d->tinfo->isTypeStruct (); > StructDeclaration *sd = ti->sym; > @@ -1119,7 +1119,7 @@ public: > void *__monitor; > TypeInfo[] elements; */ > > - void visit (TypeInfoTupleDeclaration *d) > + void visit (TypeInfoTupleDeclaration *d) final override > { > TypeTuple *ti = d->tinfo->isTypeTuple (); > > diff --git a/gcc/d/types.cc b/gcc/d/types.cc > index c54049dfb98..b17b15359c8 100644 > --- a/gcc/d/types.cc > +++ b/gcc/d/types.cc > @@ -665,7 +665,7 @@ public: > > /* This should be overridden by each type class. */ > > - void visit (Type *) > + void visit (Type *) final override > { > gcc_unreachable (); > } > @@ -673,21 +673,21 @@ public: > /* Type assigned to erroneous expressions or constructs that > failed during the semantic stage. */ > > - void visit (TypeError *t) > + void visit (TypeError *t) final override > { > t->ctype = error_mark_node; > } > > /* Type assigned to generic nullable types. */ > > - void visit (TypeNull *t) > + void visit (TypeNull *t) final override > { > t->ctype = ptr_type_node; > } > > /* Bottom type used for functions that never return. */ > > - void visit (TypeNoreturn *t) > + void visit (TypeNoreturn *t) final override > { > t->ctype = noreturn_type_node; > TYPE_NAME (t->ctype) = get_identifier (t->toChars ()); > @@ -695,7 +695,7 @@ public: > > /* Basic Data Types. */ > > - void visit (TypeBasic *t) > + void visit (TypeBasic *t) final override > { > /* [type/basic-data-types] > > @@ -761,7 +761,7 @@ public: > > /* Build a simple pointer to data type, analogous to C pointers. */ > > - void visit (TypePointer *t) > + void visit (TypePointer *t) final override > { > t->ctype = build_pointer_type (build_ctype (t->next)); > } > @@ -769,7 +769,7 @@ public: > /* Build a dynamic array type, consisting of a length and a pointer > to the array data. */ > > - void visit (TypeDArray *t) > + void visit (TypeDArray *t) final override > { > /* In [abi/arrays], dynamic array layout is: > .length array dimension. > @@ -787,7 +787,7 @@ public: > /* Build a static array type, distinguished from dynamic arrays by > having a length fixed at compile-time, analogous to C arrays. */ > > - void visit (TypeSArray *t) > + void visit (TypeSArray *t) final override > { > if (t->dim->isConst () && t->dim->type->isintegral ()) > { > @@ -804,7 +804,7 @@ public: > > /* Build a vector type, a fixed array of floating or integer types. */ > > - void visit (TypeVector *t) > + void visit (TypeVector *t) final override > { > int nunits = t->basetype->isTypeSArray ()->dim->toUInteger (); > tree inner = build_ctype (t->elementType ()); > @@ -821,7 +821,7 @@ public: > /* Build an associative array type, distinguished from arrays by having an > index that's not necessarily an integer, and can be sparsely populated. > */ > > - void visit (TypeAArray *t) > + void visit (TypeAArray *t) final override > { > /* In [abi/associative-arrays], associative arrays are a struct that only > consist of a pointer to an opaque, implementation defined type. */ > @@ -835,7 +835,7 @@ public: > /* Build type for a function declaration, which consists of a return type, > and a list of parameter types, and a linkage attribute. */ > > - void visit (TypeFunction *t) > + void visit (TypeFunction *t) final override > { > tree fnparams = NULL_TREE; > tree fntype; > @@ -925,7 +925,7 @@ public: > reference and a pointer to a non-static member function, or a pointer > to a closure and a pointer to a nested function. */ > > - void visit (TypeDelegate *t) > + void visit (TypeDelegate *t) final override > { > /* In [abi/delegates], delegate layout is: > .ptr context pointer. > @@ -952,7 +952,7 @@ public: > /* Build a named enum type, a distinct value whose values are restrict to > a group of constants of the same underlying base type. */ > > - void visit (TypeEnum *t) > + void visit (TypeEnum *t) final override > { > tree basetype = (t->sym->memtype) > ? build_ctype (t->sym->memtype) : void_type_node; > @@ -1067,7 +1067,7 @@ public: > /* Build a struct or union type. Layout should be exactly represented > as an equivalent C struct, except for non-POD or nested structs. */ > > - void visit (TypeStruct *t) > + void visit (TypeStruct *t) final override > { > /* Merge types in the back-end if the front-end did not itself do so. */ > tree deco = get_identifier (d_mangle_decl (t->sym)); > @@ -1123,7 +1123,7 @@ public: > /* Build a class type. Whereas structs are value types, classes are > reference types, with all the object-orientated features. */ > > - void visit (TypeClass *t) > + void visit (TypeClass *t) final override > { > /* Merge types in the back-end if the front-end did not itself do so. */ > tree deco = get_identifier (d_mangle_decl (t->sym)); > -- > 2.26.3 > >