@@ -341,9 +341,29 @@ class TypeInfoVisitor : public Visitor
{
using Visitor::visit;
- tree type_;
+ tree decl_;
vec<constructor_elt, va_gc> *init_;
+ /* Build an internal comdat symbol for the manifest constant VALUE, so that
+ its address can be taken. */
+
+ tree internal_reference (tree value)
+ {
+ /* Use the typeinfo decl name as a prefix for the internal symbol. */
+ const char *prefix = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (this->decl_));
+ tree decl = build_artificial_decl (TREE_TYPE (value), value, prefix);
+
+ /* The internal pointer reference should be public, but not visible outside
+ the compilation unit. */
+ DECL_EXTERNAL (decl) = 0;
+ TREE_PUBLIC (decl) = 1;
+ DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
+ DECL_COMDAT (decl) = 1;
+ d_pushdecl (decl);
+
+ return decl;
+ }
+
/* Add VALUE to the constructor values list. */
void layout_field (tree value)
@@ -364,10 +384,8 @@ class TypeInfoVisitor : public Visitor
TREE_STATIC (value) = 1;
/* Taking the address, so assign the literal to a static var. */
- tree decl = build_artificial_decl (TREE_TYPE (value), value);
+ tree decl = this->internal_reference (value);
TREE_READONLY (decl) = 1;
- DECL_EXTERNAL (decl) = 0;
- d_pushdecl (decl);
value = d_array_value (build_ctype (Type::tchar->arrayOf ()),
size_int (len), build_address (decl));
@@ -500,9 +518,9 @@ class TypeInfoVisitor : public Visitor
public:
- TypeInfoVisitor (tree type)
+ TypeInfoVisitor (tree decl)
{
- this->type_ = type;
+ this->decl_ = decl;
this->init_ = NULL;
}
@@ -510,7 +528,7 @@ public:
tree result (void)
{
- return build_struct_literal (this->type_, this->init_);
+ return build_struct_literal (TREE_TYPE (this->decl_), this->init_);
}
/* Layout of TypeInfo is:
@@ -1125,19 +1143,12 @@ public:
build_typeinfo (d->loc, arg->type));
}
tree ctor = build_constructor (build_ctype (satype), elms);
- tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor);
-
- /* The internal pointer reference should be public, but not visible outside
- the compilation unit, as it's referencing COMDAT decls. */
- TREE_PUBLIC (decl) = 1;
- DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
- DECL_COMDAT (decl) = 1;
+ tree decl = this->internal_reference (ctor);
tree length = size_int (ti->arguments->dim);
tree ptr = build_address (decl);
this->layout_field (d_array_value (array_type_node, length, ptr));
- d_pushdecl (decl);
rest_of_decl_compilation (decl, 1, 0);
}
};
@@ -1152,8 +1163,7 @@ layout_typeinfo (TypeInfoDeclaration *d)
if (!Type::dtypeinfo)
create_frontend_tinfo_types ();
- tree type = TREE_TYPE (get_typeinfo_decl (d));
- TypeInfoVisitor v = TypeInfoVisitor (type);
+ TypeInfoVisitor v = TypeInfoVisitor (get_typeinfo_decl (d));
d->accept (&v);
return v.result ();
}
@@ -1168,8 +1178,7 @@ layout_classinfo (ClassDeclaration *cd)
create_frontend_tinfo_types ();
TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
- tree type = TREE_TYPE (get_classinfo_decl (cd));
- TypeInfoVisitor v = TypeInfoVisitor (type);
+ TypeInfoVisitor v = TypeInfoVisitor (get_classinfo_decl (cd));
d->accept (&v);
return v.result ();
}