aboutsummaryrefslogtreecommitdiff
path: root/odb/plugin.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-03-25 13:47:43 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-03-25 13:47:43 +0200
commit01f77f6d38283b4efbe2b55fc9c7c837fd6498dc (patch)
tree12059fa0c514a3f2b9da2a9419593e3596cc6f5d /odb/plugin.cxx
parentad637abaa62a26461b276769c35dd1b67036b54b (diff)
Add support for union, enum, class/union template
Diffstat (limited to 'odb/plugin.cxx')
-rw-r--r--odb/plugin.cxx718
1 files changed, 608 insertions, 110 deletions
diff --git a/odb/plugin.cxx b/odb/plugin.cxx
index 0f34a5b..bb50a3f 100644
--- a/odb/plugin.cxx
+++ b/odb/plugin.cxx
@@ -139,41 +139,12 @@ private:
if (DECL_NAME (decl) != NULL_TREE)
decls_.insert (decl);
- /*
- tree type (TREE_TYPE (decl));
-
- if (TREE_CODE (type) == RECORD_TYPE)
- {
- tree name (DECL_NAME (decl));
-
- if (name != NULL_TREE)
- {
- if (DECL_ARTIFICIAL (decl))
- {
- // If we have an anonymous class typedef, use the user-
- // supplied name instead of the synthesized one. ARM
- // says that in typedef struct {} S; S becomes struct's
- // name.
- //
- if (ANON_AGGRNAME_P (name))
- {
- tree d (TYPE_NAME (type));
-
- if (d != NULL_TREE &&
- !DECL_ARTIFICIAL (d) &&
- DECL_NAME (d) != NULL_TREE &&
- !ANON_AGGRNAME_P (DECL_NAME (d)))
- {
- decls_.insert (d);
- }
- }
- else
- decls_.insert (decl);
- }
- }
- }
- */
-
+ break;
+ }
+ case TEMPLATE_DECL:
+ {
+ if (DECL_CLASS_TEMPLATE_P (decl))
+ decls_.insert (decl);
break;
}
default:
@@ -289,6 +260,7 @@ private:
}
case TEMPLATE_DECL:
{
+ emit_template_decl (decl);
break;
}
}
@@ -302,10 +274,14 @@ private:
emit_type_decl (tree decl)
{
tree t (TREE_TYPE (decl));
+ int tc (TREE_CODE (t));
+
tree decl_name (DECL_NAME (decl));
char const* name (IDENTIFIER_POINTER (decl_name));
- if (DECL_ARTIFICIAL (decl) && TREE_CODE (t) == RECORD_TYPE)
+
+ if (DECL_ARTIFICIAL (decl) &&
+ (tc == RECORD_TYPE || tc == UNION_TYPE || tc == ENUMERAL_TYPE))
{
// If we have an anonymous class typedef, use the user-
// supplied name instead of the synthesized one. ARM
@@ -341,21 +317,42 @@ private:
size_t line (DECL_SOURCE_LINE (decl));
size_t clmn (DECL_SOURCE_COLUMN (decl));
- warning (0, G_ ("start class declaration %s in %s:%d"),
+ warning (0, G_ ("start %s declaration %s in %s:%d"),
+ tree_code_name[tc],
name,
DECL_SOURCE_FILE (decl),
DECL_SOURCE_LINE (decl));
- class_& node (emit_class (t, file, line, clmn));
+ type* node (0);
+
+ switch (tc)
+ {
+ case RECORD_TYPE:
+ {
+ node = &emit_class<class_> (t, file, line, clmn);
+ break;
+ }
+ case UNION_TYPE:
+ {
+ node = &emit_union<union_> (t, file, line, clmn);
+ break;
+ }
+ case ENUMERAL_TYPE:
+ {
+ node = &emit_enum (t, file, line, clmn);
+ break;
+ }
+ }
if (COMPLETE_TYPE_P (t))
- unit_->new_edge<defines> (*scope_, node, name);
+ unit_->new_edge<defines> (*scope_, *node, name);
else
- unit_->new_edge<declares> (*scope_, node, name);
+ unit_->new_edge<declares> (*scope_, *node, name);
- warning (0, G_ ("end class declaration %s (%p) in %s:%d"),
+ warning (0, G_ ("end %s declaration %s (%p) in %s:%d"),
+ tree_code_name[tc],
name,
- &node,
+ node,
DECL_SOURCE_FILE (decl),
DECL_SOURCE_LINE (decl));
}
@@ -365,7 +362,9 @@ private:
// class typedef case described above since we already used
// this name to define the class.
//
- if (TREE_CODE (t) == RECORD_TYPE &&
+ int tc (TREE_CODE (t));
+
+ if ((tc == RECORD_TYPE || tc == UNION_TYPE || tc == ENUMERAL_TYPE) &&
TYPE_NAME (TYPE_MAIN_VARIANT (t)) == decl)
return;
@@ -387,7 +386,215 @@ private:
}
}
- class_&
+ // Emit a template declaration.
+ //
+ void
+ emit_template_decl (tree decl)
+ {
+ // Currently we only handle class/union templates.
+ //
+ tree t (TREE_TYPE (DECL_TEMPLATE_RESULT (decl)));
+ int tc (TREE_CODE (t));
+
+ warning (0, G_ ("%s template (%p) %s (%p) %s"),
+ tree_code_name[tc],
+ decl,
+ IDENTIFIER_POINTER (DECL_NAME (decl)),
+ t,
+ tree_code_name[TREE_CODE (t)]);
+
+ warning (0, G_ ("specialization:"));
+
+ for (tree s (DECL_TEMPLATE_SPECIALIZATIONS (decl));
+ s != NULL_TREE; s = TREE_CHAIN (s))
+ {
+ tree t (TREE_TYPE (s));
+ tree d (TYPE_NAME (t));
+
+ warning (0, G_ ("\tspecialization %p at %s:%d"),
+ t,
+ DECL_SOURCE_FILE (d),
+ DECL_SOURCE_LINE (d));
+ }
+
+ warning (0, G_ ("instantiations:"));
+
+ for (tree i (DECL_TEMPLATE_INSTANTIATIONS (decl));
+ i != NULL_TREE; i = TREE_CHAIN (i))
+ {
+ tree t (TREE_VALUE (i));
+ tree d (TYPE_NAME (t));
+
+ warning (0, G_ ("\tinstantiation %p at %s:%d"),
+ t,
+ DECL_SOURCE_FILE (d),
+ DECL_SOURCE_LINE (d));
+ }
+
+ char const* name (IDENTIFIER_POINTER (DECL_NAME (decl)));
+
+ warning (0, G_ ("start %s template %s in %s:%d"),
+ tree_code_name[tc],
+ name,
+ DECL_SOURCE_FILE (decl),
+ DECL_SOURCE_LINE (decl));
+
+ type_template* t_node (0);
+
+ if (tc == RECORD_TYPE)
+ t_node = &emit_class_template (decl);
+ else
+ t_node = &emit_union_template (decl);
+
+ if (COMPLETE_TYPE_P (t))
+ unit_->new_edge<defines> (*scope_, *t_node, name);
+ else
+ unit_->new_edge<declares> (*scope_, *t_node, name);
+
+ warning (0, G_ ("end %s template %s (%p) in %s:%d"),
+ tree_code_name[tc],
+ name,
+ t_node,
+ DECL_SOURCE_FILE (decl),
+ DECL_SOURCE_LINE (decl));
+ }
+
+ class_template&
+ emit_class_template (tree t, bool stub = false)
+ {
+ // See if there is a stub already for this template.
+ //
+ class_template* ct_node (0);
+
+ if (node* n = unit_->find (t))
+ {
+ ct_node = &dynamic_cast<class_template&> (*n);
+ }
+ else
+ {
+ path f (DECL_SOURCE_FILE (t));
+ size_t l (DECL_SOURCE_LINE (t));
+ size_t c (DECL_SOURCE_COLUMN (t));
+
+ ct_node = &unit_->new_node<class_template> (f, l, c);
+ unit_->insert (t, *ct_node);
+ }
+
+ tree c (TREE_TYPE (DECL_TEMPLATE_RESULT (t)));
+
+ if (stub || !COMPLETE_TYPE_P (c))
+ return *ct_node;
+
+ // Collect member declarations so that we can traverse them in
+ // the source code order. For now we are only interested in
+ // nested class template declarations.
+ //
+ decl_set decls;
+
+ for (tree d (TYPE_FIELDS (c)); d != NULL_TREE ; d = TREE_CHAIN (d))
+ {
+ switch (TREE_CODE (d))
+ {
+ case TEMPLATE_DECL:
+ {
+ if (DECL_CLASS_TEMPLATE_P (d))
+ decls.insert (d);
+ break;
+ }
+ }
+ }
+
+ scope* prev_scope (scope_);
+ scope_ = ct_node;
+
+ for (decl_set::const_iterator i (decls.begin ()), e (decls.end ());
+ i != e; ++i)
+ {
+ tree d (*i);
+
+ switch (TREE_CODE (d))
+ {
+ case TEMPLATE_DECL:
+ {
+ emit_template_decl (d);
+ break;
+ }
+ }
+ }
+
+ scope_ = prev_scope;
+ return *ct_node;
+ }
+
+ union_template&
+ emit_union_template (tree t, bool stub = false)
+ {
+ // See if there is a stub already for this template.
+ //
+ union_template* ut_node (0);
+
+ if (node* n = unit_->find (t))
+ {
+ ut_node = &dynamic_cast<union_template&> (*n);
+ }
+ else
+ {
+ path f (DECL_SOURCE_FILE (t));
+ size_t l (DECL_SOURCE_LINE (t));
+ size_t c (DECL_SOURCE_COLUMN (t));
+
+ ut_node = &unit_->new_node<union_template> (f, l, c);
+ unit_->insert (t, *ut_node);
+ }
+
+ tree u (TREE_TYPE (DECL_TEMPLATE_RESULT (t)));
+
+ if (stub || !COMPLETE_TYPE_P (u))
+ return *ut_node;
+
+ // Collect member declarations so that we can traverse them in
+ // the source code order. For now we are only interested in
+ // nested class template declarations.
+ //
+ decl_set decls;
+
+ for (tree d (TYPE_FIELDS (u)); d != NULL_TREE ; d = TREE_CHAIN (d))
+ {
+ switch (TREE_CODE (d))
+ {
+ case TEMPLATE_DECL:
+ {
+ if (DECL_CLASS_TEMPLATE_P (d))
+ decls.insert (d);
+ break;
+ }
+ }
+ }
+
+ scope* prev_scope (scope_);
+ scope_ = ut_node;
+
+ for (decl_set::const_iterator i (decls.begin ()), e (decls.end ());
+ i != e; ++i)
+ {
+ tree d (*i);
+
+ switch (TREE_CODE (d))
+ {
+ case TEMPLATE_DECL:
+ {
+ emit_template_decl (d);
+ break;
+ }
+ }
+ }
+
+ scope_ = prev_scope;
+ return *ut_node;
+ }
+
+ template <typename T>
+ T&
emit_class (tree c,
path const& file,
size_t line,
@@ -398,20 +605,20 @@ private:
// See if there is a stub already for this type.
//
- class_* class_node (0);
+ T* c_node (0);
if (node* n = unit_->find (c))
{
- class_node = &dynamic_cast<class_&> (*n);
+ c_node = &dynamic_cast<T&> (*n);
}
else
{
- class_node = &unit_->new_node<class_> (file, line, clmn);
- unit_->insert (c, *class_node);
+ c_node = &unit_->new_node<T> (file, line, clmn);
+ unit_->insert (c, *c_node);
}
if (stub || !COMPLETE_TYPE_P (c))
- return *class_node;
+ return *c_node;
// Traverse base information.
//
@@ -443,24 +650,39 @@ private:
}
bool virt (BINFO_VIRTUAL_P (bi));
- tree base (BINFO_TYPE (bi));
+ tree base (TYPE_MAIN_VARIANT (BINFO_TYPE (bi)));
+
tree base_decl (TYPE_NAME (base)); // Typedef decl for this base.
- warning (0, G_ ("\t%s%s base %s"),
+ // Find the corresponding graph node. If we cannot find one then
+ // the base is a template instantiation since an ordinary class
+ // has to be defined (complete) in order to be a base.
+ //
+ class_* b_node (0);
+ string name;
+
+ if (node* n = unit_->find (base))
+ {
+ b_node = &dynamic_cast<class_&> (*n);
+ name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (base)));
+ }
+ else
+ {
+ b_node = &dynamic_cast<class_&> (emit_type (base, file, line, clmn));
+ name = emit_type_name (base);
+ }
+
+ unit_->new_edge<inherits> (*c_node, *b_node, a, virt);
+
+ warning (0, G_ ("\t%s%s base %s (%p)"),
a.string (),
(virt ? " virtual" : ""),
- IDENTIFIER_POINTER (DECL_NAME (base_decl)));
-
- // Find the corresponding graph node.
- //
- node* base_node (unit_->find (base));
- assert (base_node != 0);
- unit_->new_edge<inherits> (
- *class_node, dynamic_cast<class_&> (*base_node), a, virt);
+ name.c_str (),
+ static_cast<type*> (b_node));
}
- // Collect members so that we can traverse then in the source
- // code order.
+ // Collect member declarations so that we can traverse them in
+ // the source code order.
//
decl_set decls;
@@ -474,6 +696,12 @@ private:
decls.insert (d);
break;
}
+ case TEMPLATE_DECL:
+ {
+ if (DECL_CLASS_TEMPLATE_P (d))
+ decls.insert (d);
+ break;
+ }
case FIELD_DECL:
{
if (!DECL_ARTIFICIAL (d))
@@ -504,6 +732,9 @@ private:
}
}
+ scope* prev_scope (scope_);
+ scope_ = c_node;
+
for (decl_set::const_iterator i (decls.begin ()), e (decls.end ());
i != e; ++i)
{
@@ -516,6 +747,11 @@ private:
emit_type_decl (d);
break;
}
+ case TEMPLATE_DECL:
+ {
+ emit_template_decl (d);
+ break;
+ }
case FIELD_DECL:
{
tree t (TREE_TYPE (d));
@@ -534,7 +770,7 @@ private:
unit_->new_node<data_member> (file, line, clmn));
unit_->new_edge<belongs> (member_node, type_node);
- unit_->new_edge<names> (*class_node, member_node, name, a);
+ unit_->new_edge<names> (*c_node, member_node, name, a);
warning (0, G_ ("\t%s data member %s (%p) %s in %s:%i"),
a.string (),
@@ -549,7 +785,190 @@ private:
}
}
- return *class_node;
+ scope_ = prev_scope;
+ return *c_node;
+ }
+
+ template <typename T>
+ T&
+ emit_union (tree u,
+ path const& file,
+ size_t line,
+ size_t clmn,
+ bool stub = false)
+ {
+ u = TYPE_MAIN_VARIANT (u);
+
+ // See if there is a stub already for this type.
+ //
+ T* u_node (0);
+
+ if (node* n = unit_->find (u))
+ {
+ u_node = &dynamic_cast<T&> (*n);
+ }
+ else
+ {
+ u_node = &unit_->new_node<T> (file, line, clmn);
+ unit_->insert (u, *u_node);
+ }
+
+ if (stub || !COMPLETE_TYPE_P (u))
+ return *u_node;
+
+ // Collect member declarations so that we can traverse them in
+ // the source code order.
+ //
+ decl_set decls;
+
+ for (tree d (TYPE_FIELDS (u)); d != NULL_TREE ; d = TREE_CHAIN (d))
+ {
+ switch (TREE_CODE (d))
+ {
+ case TYPE_DECL:
+ {
+ if (!DECL_SELF_REFERENCE_P (d))
+ decls.insert (d);
+ break;
+ }
+ case TEMPLATE_DECL:
+ {
+ if (DECL_CLASS_TEMPLATE_P (d))
+ decls.insert (d);
+ break;
+ }
+ case FIELD_DECL:
+ {
+ if (!DECL_ARTIFICIAL (d))
+ decls.insert (d);
+ break;
+ }
+ default:
+ {
+ /*
+ tree name = DECL_NAME (d);
+
+ if (name != NULL_TREE)
+ {
+ warning (0, G_ ("\tsome declaration %s in %s:%i"),
+ IDENTIFIER_POINTER (name),
+ DECL_SOURCE_FILE (d),
+ DECL_SOURCE_LINE (d));
+ }
+ else
+ {
+ warning (0, G_ ("\tsome unnamed declaration in %s:%i"),
+ DECL_SOURCE_FILE (d),
+ DECL_SOURCE_LINE (d));
+ }
+ */
+ break;
+ }
+ }
+ }
+
+ scope* prev_scope (scope_);
+ scope_ = u_node;
+
+ for (decl_set::const_iterator i (decls.begin ()), e (decls.end ());
+ i != e; ++i)
+ {
+ tree d (*i);
+
+ switch (TREE_CODE (d))
+ {
+ case TYPE_DECL:
+ {
+ emit_type_decl (d);
+ break;
+ }
+ case TEMPLATE_DECL:
+ {
+ emit_template_decl (d);
+ break;
+ }
+ case FIELD_DECL:
+ {
+ tree t (TREE_TYPE (d));
+ char const* name (IDENTIFIER_POINTER (DECL_NAME (d)));
+
+ path file (DECL_SOURCE_FILE (d));
+ size_t line (DECL_SOURCE_LINE (d));
+ size_t clmn (DECL_SOURCE_COLUMN (d));
+
+ string type_name (emit_type_name (t));
+
+ access a (decl_access (d));
+
+ type& type_node (emit_type (t, file, line, clmn));
+ data_member& member_node (
+ unit_->new_node<data_member> (file, line, clmn));
+
+ unit_->new_edge<belongs> (member_node, type_node);
+ unit_->new_edge<names> (*u_node, member_node, name, a);
+
+ warning (0, G_ ("\t%s union member %s (%p) %s in %s:%i"),
+ a.string (),
+ type_name.c_str (),
+ &type_node,
+ name,
+ file.string ().c_str (),
+ line);
+
+ break;
+ }
+ }
+ }
+
+ scope_ = prev_scope;
+ return *u_node;
+ }
+
+ enum_&
+ emit_enum (tree e,
+ path const& file,
+ size_t line,
+ size_t clmn,
+ bool stub = false)
+ {
+ e = TYPE_MAIN_VARIANT (e);
+
+ // See if there is a stub already for this type.
+ //
+ enum_* e_node (0);
+
+ if (node* n = unit_->find (e))
+ {
+ e_node = &dynamic_cast<enum_&> (*n);
+ }
+ else
+ {
+ e_node = &unit_->new_node<enum_> (file, line, clmn);
+ unit_->insert (e, *e_node);
+ }
+
+ if (stub || !COMPLETE_TYPE_P (e))
+ return *e_node;
+
+ // Traverse enumerators.
+ //
+ for (tree er (TYPE_VALUES (e)); er != NULL_TREE ; er = TREE_CHAIN (er))
+ {
+ char const* name (IDENTIFIER_POINTER (TREE_PURPOSE (er)));
+
+ // There doesn't seem to be a way to get the proper position for
+ // each enumerator.
+ //
+ enumerator& er_node = unit_->new_node<enumerator> (file, line, clmn);
+ unit_->new_edge<enumerates> (*e_node, er_node);
+
+ warning (0, G_ ("\tenumerator %s in %s:%d"),
+ name,
+ file.string ().c_str (),
+ line);
+ }
+
+ return *e_node;
}
// Create new or find existing semantic graph type.
@@ -599,7 +1018,6 @@ private:
return q;
}
-
type&
create_type (tree t,
path const& file,
@@ -607,13 +1025,15 @@ private:
size_t clmn)
{
type* r (0);
+ int tc (TREE_CODE (t));
- switch (TREE_CODE (t))
+ switch (tc)
{
//
// User-defined types.
//
case RECORD_TYPE:
+ case UNION_TYPE:
{
tree ti (TYPE_TEMPLATE_INFO (t));
@@ -634,27 +1054,35 @@ private:
t = TYPE_MAIN_VARIANT (t);
tree d (TYPE_NAME (t));
- warning (0, G_ ("start anon/stub class declaration in %s:%d"),
+ warning (0, G_ ("start anon/stub %s declaration in %s:%d"),
+ tree_code_name[tc],
file.string ().c_str (),
line);
if (d == NULL_TREE || ANON_AGGRNAME_P (DECL_NAME (d)))
{
- r = &emit_class (t, file, line, clmn);
+ if (tc == RECORD_TYPE)
+ r = &emit_class<class_> (t, file, line, clmn);
+ else
+ r = &emit_union<union_> (t, file, line, clmn);
}
else
{
// Use the "defining" declaration's file, line, and column
// information to create the stub.
//
- r = &emit_class (t,
- path (DECL_SOURCE_FILE (d)),
- DECL_SOURCE_LINE (d),
- DECL_SOURCE_COLUMN (d),
- true);
+ path f (DECL_SOURCE_FILE (d));
+ size_t l (DECL_SOURCE_LINE (d));
+ size_t c (DECL_SOURCE_COLUMN (d));
+
+ if (tc == RECORD_TYPE)
+ r = &emit_class<class_> (t, f, l, c, true);
+ else
+ r = &emit_union<union_> (t, f, l, c, true);
}
- warning (0, G_ ("end anon/stub class declaration (%p) in %s:%d"),
+ warning (0, G_ ("end anon/stub %s declaration (%p) in %s:%d"),
+ tree_code_name[tc],
r,
file.string ().c_str (),
line);
@@ -663,50 +1091,105 @@ private:
{
// Template instantiation.
//
- /*
+ t = TYPE_MAIN_VARIANT (t);
tree decl (TI_TEMPLATE (ti)); // DECL_TEMPLATE
- string id (IDENTIFIER_POINTER (DECL_NAME (decl)));
- id += '<';
+ // Get to the most general template declaration.
+ //
+ while (DECL_TEMPLATE_INFO (decl))
+ decl = DECL_TI_TEMPLATE (decl);
- tree args (INNERMOST_TEMPLATE_ARGS (TI_ARGS (ti)));
+ type_template* t_node (0);
- int n (TREE_VEC_LENGTH (args));
-
- for (size_t i (0), n (TREE_VEC_LENGTH (args)); i < n ; ++i)
+ // Find the template node or create a stub if none exist.
+ //
+ if (node* n = unit_->find (decl))
+ t_node = &dynamic_cast<type_template&> (*n);
+ else
{
- tree a (TREE_VEC_ELT (args, i));
-
- if (i != 0)
- id += ", ";
+ warning (0, G_ ("start stub %s template for (%p) in %s:%d"),
+ tree_code_name[tc],
+ decl,
+ file.string ().c_str (),
+ line);
+
+ if (tc == RECORD_TYPE)
+ t_node = &emit_class_template (decl, true);
+ else
+ t_node = &emit_union_template (decl, true);
- // Assume type-only arguments.
- //
- id += emit_type (a);
+ warning (0, G_ ("end stub %s template (%p) in %s:%d"),
+ tree_code_name[tc],
+ t_node,
+ file.string ().c_str (),
+ line);
}
- id += '>';
+ warning (0, G_ ("start %s instantiation (%p) for template (%p) in %s:%d"),
+ tree_code_name[tc],
+ t,
+ t_node,
+ file.string ().c_str (),
+ line);
- r = id + r;
- */
- }
+ type_instantiation* i_node (0);
- break;
- }
+ if (tc == RECORD_TYPE)
+ i_node = &emit_class<class_instantiation> (t, file, line, clmn);
+ else
+ i_node = &emit_union<union_instantiation> (t, file, line, clmn);
- /*
+ warning (0, G_ ("end %s instantiation (%p) in %s:%d"),
+ tree_code_name[tc],
+ static_cast<type*> (i_node),
+ file.string ().c_str (),
+ line);
+
+ unit_->new_edge<instantiates> (*i_node, *t_node);
+ r = i_node;
+ }
- case UNION_TYPE:
- {
break;
}
case ENUMERAL_TYPE:
{
+ // The same logic as in the "ordinary class" case above
+ // applies here.
+ //
+
+ t = TYPE_MAIN_VARIANT (t);
+ tree d (TYPE_NAME (t));
+
+ warning (0, G_ ("start anon/stub %s declaration in %s:%d"),
+ tree_code_name[tc],
+ file.string ().c_str (),
+ line);
+
+ if (d == NULL_TREE || ANON_AGGRNAME_P (DECL_NAME (d)))
+ {
+ r = &emit_enum (t, file, line, clmn);
+ }
+ else
+ {
+ // Use the "defining" declaration's file, line, and column
+ // information to create the stub.
+ //
+ path f (DECL_SOURCE_FILE (d));
+ size_t l (DECL_SOURCE_LINE (d));
+ size_t c (DECL_SOURCE_COLUMN (d));
+
+ r = &emit_enum (t, f, l, c, true);
+ }
+
+ warning (0, G_ ("end anon/stub %s declaration (%p) in %s:%d"),
+ tree_code_name[tc],
+ r,
+ file.string ().c_str (),
+ line);
+
break;
}
- */
-
//
// Derived types.
//
@@ -772,15 +1255,28 @@ private:
unit_->insert (TYPE_MAIN_VARIANT (t), p);
r = &p;
}
+ else
+ {
+ r = &unit_->new_node<unsupported_type> (
+ file, line, clmn, "pointer_to_member_type");
+ warning (0, G_ ("unsupported pointer_to_member_type (%p) in %s:%d"),
+ r,
+ file.string ().c_str (),
+ line);
+ }
break;
}
default:
{
- error (G_ ("%s:%d: unexpected type %s"),
- file.string ().c_str (),
- line,
- tree_code_name[TREE_CODE (t)]);
+ r = &unit_->new_node<unsupported_type> (
+ file, line, clmn, tree_code_name[tc]);
+
+ warning (0, G_ ("unsupported %s (%p) in %s:%d"),
+ tree_code_name[tc],
+ r,
+ file.string ().c_str (),
+ line);
break;
}
}
@@ -824,13 +1320,16 @@ private:
if (CP_TYPE_RESTRICT_P (type))
r += " __restrict";
- switch (TREE_CODE (type))
+ int tc (TREE_CODE (type));
+
+ switch (tc)
{
//
// User-defined types.
//
case RECORD_TYPE:
+ case UNION_TYPE:
{
tree ti (TYPE_TEMPLATE_INFO (type));
@@ -876,16 +1375,13 @@ private:
break;
}
- /*
- case UNION_TYPE:
- {
- break;
- }
case ENUMERAL_TYPE:
{
+ type = TYPE_MAIN_VARIANT (type);
+ tree decl (TYPE_NAME (type));
+ r = IDENTIFIER_POINTER (DECL_NAME (decl)) + r;
break;
}
- */
//
// Derived types.
@@ -946,6 +1442,8 @@ private:
tree t (TREE_TYPE (type));
r = emit_type_name (t) + "*" + r;
}
+ else
+ r = "<pointer_to_member_type>";
break;
}
@@ -966,7 +1464,7 @@ private:
}
default:
{
- r = "<unsupported>";
+ r = "<" + string (tree_code_name[tc]) + ">";
break;
}
}