From 01f77f6d38283b4efbe2b55fc9c7c837fd6498dc Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 25 Mar 2010 13:47:43 +0200 Subject: Add support for union, enum, class/union template --- odb/makefile | 17 +- odb/plugin.cxx | 718 +++++++++++++++++++++++++++++++++------ odb/semantics.hxx | 5 + odb/semantics/class-template.cxx | 42 +++ odb/semantics/class-template.hxx | 76 +++++ odb/semantics/class.cxx | 10 +- odb/semantics/class.hxx | 20 +- odb/semantics/elements.cxx | 17 + odb/semantics/elements.hxx | 35 ++ odb/semantics/enum.cxx | 48 +++ odb/semantics/enum.hxx | 133 ++++++++ odb/semantics/template.cxx | 66 ++++ odb/semantics/template.hxx | 158 +++++++++ odb/semantics/union-template.cxx | 42 +++ odb/semantics/union-template.hxx | 41 +++ odb/semantics/union.cxx | 33 ++ odb/semantics/union.hxx | 32 ++ 17 files changed, 1354 insertions(+), 139 deletions(-) create mode 100644 odb/semantics/class-template.cxx create mode 100644 odb/semantics/class-template.hxx create mode 100644 odb/semantics/enum.cxx create mode 100644 odb/semantics/enum.hxx create mode 100644 odb/semantics/template.cxx create mode 100644 odb/semantics/template.hxx create mode 100644 odb/semantics/union-template.cxx create mode 100644 odb/semantics/union-template.hxx create mode 100644 odb/semantics/union.cxx create mode 100644 odb/semantics/union.hxx (limited to 'odb') diff --git a/odb/makefile b/odb/makefile index 825cd7b..f1dd9be 100644 --- a/odb/makefile +++ b/odb/makefile @@ -9,12 +9,17 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make # cxx_ptun := plugin.cxx -cxx_ptun += \ -semantics/class.cxx \ -semantics/derived.cxx \ -semantics/elements.cxx \ -semantics/fundamental.cxx \ -semantics/namespace.cxx \ +cxx_ptun += \ +semantics/class.cxx \ +semantics/class-template.cxx \ +semantics/derived.cxx \ +semantics/elements.cxx \ +semantics/enum.cxx \ +semantics/fundamental.cxx \ +semantics/namespace.cxx \ +semantics/template.cxx \ +semantics/union.cxx \ +semantics/union-template.cxx \ semantics/unit.cxx # Driver units 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 (t, file, line, clmn); + break; + } + case UNION_TYPE: + { + node = &emit_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 (*scope_, node, name); + unit_->new_edge (*scope_, *node, name); else - unit_->new_edge (*scope_, node, name); + unit_->new_edge (*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 (*scope_, *t_node, name); + else + unit_->new_edge (*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 (*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 (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 (*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 (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 + 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 (*n); + c_node = &dynamic_cast (*n); } else { - class_node = &unit_->new_node (file, line, clmn); - unit_->insert (c, *class_node); + c_node = &unit_->new_node (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 (*n); + name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (base))); + } + else + { + b_node = &dynamic_cast (emit_type (base, file, line, clmn)); + name = emit_type_name (base); + } + + unit_->new_edge (*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 ( - *class_node, dynamic_cast (*base_node), a, virt); + name.c_str (), + static_cast (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 (file, line, clmn)); unit_->new_edge (member_node, type_node); - unit_->new_edge (*class_node, member_node, name, a); + unit_->new_edge (*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 + 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 (*n); + } + else + { + u_node = &unit_->new_node (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 (file, line, clmn)); + + unit_->new_edge (member_node, type_node); + unit_->new_edge (*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 (*n); + } + else + { + e_node = &unit_->new_node (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 (file, line, clmn); + unit_->new_edge (*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 (t, file, line, clmn); + else + r = &emit_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 (t, f, l, c, true); + else + r = &emit_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 (*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 (t, file, line, clmn); + else + i_node = &emit_union (t, file, line, clmn); - /* + warning (0, G_ ("end %s instantiation (%p) in %s:%d"), + tree_code_name[tc], + static_cast (i_node), + file.string ().c_str (), + line); + + unit_->new_edge (*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 ( + 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 ( + 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 = ""; break; } @@ -966,7 +1464,7 @@ private: } default: { - r = ""; + r = "<" + string (tree_code_name[tc]) + ">"; break; } } diff --git a/odb/semantics.hxx b/odb/semantics.hxx index 46350be..c30bece 100644 --- a/odb/semantics.hxx +++ b/odb/semantics.hxx @@ -7,10 +7,15 @@ #define ODB_SEMANTICS_HXX #include +#include #include #include +#include #include #include +#include +#include +#include #include #endif // ODB_SEMANTICS_HXX diff --git a/odb/semantics/class-template.cxx b/odb/semantics/class-template.cxx new file mode 100644 index 0000000..05deef8 --- /dev/null +++ b/odb/semantics/class-template.cxx @@ -0,0 +1,42 @@ +// file : odb/semantics/class-template.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include + +namespace semantics +{ + // type info + // + namespace + { + struct init + { + init () + { + using compiler::type_info; + + // class_template + // + { + type_info ti (typeid (class_template)); + ti.add_base (typeid (type_template)); + ti.add_base (typeid (scope)); + insert (ti); + } + + // class_instantiation + // + { + type_info ti (typeid (class_instantiation)); + ti.add_base (typeid (class_)); + ti.add_base (typeid (type_instantiation)); + insert (ti); + } + } + } init_; + } +} diff --git a/odb/semantics/class-template.hxx b/odb/semantics/class-template.hxx new file mode 100644 index 0000000..6443a19 --- /dev/null +++ b/odb/semantics/class-template.hxx @@ -0,0 +1,76 @@ +// file : odb/semantics/class-template.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_SEMANTICS_CLASS_TEMPLATE_HXX +#define ODB_SEMANTICS_CLASS_TEMPLATE_HXX + +#include +#include +#include + +namespace semantics +{ + class class_template: public type_template, public scope + { + private: + typedef std::vector inherits_list; + + public: + typedef inherits_list::const_iterator inherits_iterator; + + inherits_iterator + inherits_begin () const + { + return inherits_.begin (); + } + + inherits_iterator + inherits_end () const + { + return inherits_.end (); + } + + public: + class_template (path const& file, size_t line, size_t column) + : node (file, line, column) + { + } + + void + add_edge_left (inherits& e) + { + inherits_.push_back (&e); + } + + void + add_edge_right (inherits&) + { + } + + using scope::add_edge_left; + using scope::add_edge_right; + + // Resolve conflict between scope::scope and nameable::scope. + // + using nameable::scope; + + private: + inherits_list inherits_; + }; + + class class_instantiation: public class_, public type_instantiation + { + public: + class_instantiation (path const& file, size_t line, size_t column) + : node (file, line, column) + { + } + + using class_::add_edge_left; + using type_instantiation::add_edge_left; + }; +} + +#endif // ODB_SEMANTICS_CLASS_TEMPLATE_HXX diff --git a/odb/semantics/class.cxx b/odb/semantics/class.cxx index 5575745..7462d7c 100644 --- a/odb/semantics/class.cxx +++ b/odb/semantics/class.cxx @@ -19,15 +19,6 @@ namespace semantics { using compiler::type_info; - // data_member - // - { - type_info ti (typeid (data_member)); - ti.add_base (typeid (nameable)); - ti.add_base (typeid (instance)); - insert (ti); - } - // inherits // { @@ -40,6 +31,7 @@ namespace semantics // { type_info ti (typeid (class_)); + ti.add_base (typeid (type)); ti.add_base (typeid (scope)); insert (ti); } diff --git a/odb/semantics/class.hxx b/odb/semantics/class.hxx index d4a0900..bbe4687 100644 --- a/odb/semantics/class.hxx +++ b/odb/semantics/class.hxx @@ -13,19 +13,6 @@ namespace semantics { class class_; - // - // - class data_member: public nameable, public instance - { - public: - data_member (path const& file, size_t line, size_t column) - : node (file, line, column) - { - } - }; - - // - // class inherits: public edge { public: @@ -83,7 +70,7 @@ namespace semantics // // - class class_: public type, public scope + class class_: public virtual type, public scope { private: typedef std::vector inherits_list; @@ -127,6 +114,11 @@ namespace semantics // using nameable::scope; + protected: + class_ () + { + } + private: inherits_list inherits_; }; diff --git a/odb/semantics/elements.cxx b/odb/semantics/elements.cxx index d14835c..caed01e 100644 --- a/odb/semantics/elements.cxx +++ b/odb/semantics/elements.cxx @@ -149,6 +149,23 @@ namespace semantics ti.add_base (typeid (node)); insert (ti); } + + // data_member + // + { + type_info ti (typeid (data_member)); + ti.add_base (typeid (nameable)); + ti.add_base (typeid (instance)); + insert (ti); + } + + // unsupported_type + // + { + type_info ti (typeid (unsupported_type)); + ti.add_base (typeid (type)); + insert (ti); + } } } init_; } diff --git a/odb/semantics/elements.hxx b/odb/semantics/elements.hxx index 0b89831..97f386f 100644 --- a/odb/semantics/elements.hxx +++ b/odb/semantics/elements.hxx @@ -543,6 +543,41 @@ namespace semantics private: belongs_type* belongs_; }; + + // Data member for class and union types. + // + class data_member: public nameable, public instance + { + public: + data_member (path const& file, size_t line, size_t column) + : node (file, line, column) + { + } + }; + + // Unsupported type. + // + class unsupported_type: public type + { + public: + string const& + type_name () const + { + return type_name_; + } + + public: + unsupported_type (path const& file, + size_t line, + size_t column, + string const& type_name) + : node (file, line, column), type_name_ (type_name) + { + } + + private: + string const type_name_; + }; } #include diff --git a/odb/semantics/enum.cxx b/odb/semantics/enum.cxx new file mode 100644 index 0000000..ab19c70 --- /dev/null +++ b/odb/semantics/enum.cxx @@ -0,0 +1,48 @@ +// file : odb/semantics/enum.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include + +namespace semantics +{ + // type info + // + namespace + { + struct init + { + init () + { + using compiler::type_info; + + // enumerates + // + { + type_info ti (typeid (enumerates)); + ti.add_base (typeid (edge)); + insert (ti); + } + + // enumerator + // + { + type_info ti (typeid (enumerator)); + ti.add_base (typeid (instance)); + insert (ti); + } + + // enum_ + // + { + type_info ti (typeid (enum_)); + ti.add_base (typeid (type)); + insert (ti); + } + } + } init_; + } +} diff --git a/odb/semantics/enum.hxx b/odb/semantics/enum.hxx new file mode 100644 index 0000000..e628ad9 --- /dev/null +++ b/odb/semantics/enum.hxx @@ -0,0 +1,133 @@ +// file : odb/semantics/enum.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_SEMANTICS_ENUM_HXX +#define ODB_SEMANTICS_ENUM_HXX + +#include +#include + +namespace semantics +{ + class enum_; + class enumerator; + + class enumerates: public edge + { + public: + typedef semantics::enum_ enum_type; + typedef semantics::enumerator enumerator_type; + + enum_type& + enum_ () const + { + return *enum__; + } + + enumerator_type& + enumerator () const + { + return *enumerator_; + } + + public: + enumerates () + { + } + + void + set_left_node (enum_type& n) + { + enum__ = &n; + } + + void + set_right_node (enumerator_type& n) + { + enumerator_ = &n; + } + + protected: + enum_type* enum__; + enumerator_type* enumerator_; + }; + + // + // + class enumerator: public instance + { + public: + typedef semantics::enum_ enum_type; + + enum_type& + enum_ () const + { + return enumerated_->enum_ (); + } + + enumerates& + enumerated () const + { + return *enumerated_; + } + + public: + enumerator (path const& file, size_t line, size_t column) + : node (file, line, column) + { + } + + void + add_edge_right (enumerates& e) + { + enumerated_ = &e; + } + + using instance::add_edge_right; + + private: + enumerates* enumerated_; + }; + + // + // + class enum_: public type + { + private: + typedef std::vector enumerates_list; + + public: + typedef enumerates_list::const_iterator enumerates_iterator; + + enumerates_iterator + enumerates_begin () const + { + return enumerates_.begin (); + } + + enumerates_iterator + enumerates_end () const + { + return enumerates_.end (); + } + + public: + enum_ (path const& file, size_t line, size_t column) + : node (file, line, column) + { + } + + void + add_edge_left (enumerates& e) + { + enumerates_.push_back (&e); + } + + private: + enumerates_list enumerates_; + }; +} + +#endif // ODB_SEMANTICS_ENUM_HXX diff --git a/odb/semantics/template.cxx b/odb/semantics/template.cxx new file mode 100644 index 0000000..4882aa3 --- /dev/null +++ b/odb/semantics/template.cxx @@ -0,0 +1,66 @@ +// file : odb/semantics/template.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include + +namespace semantics +{ + // type info + // + namespace + { + struct init + { + init () + { + using compiler::type_info; + + // template_ + // + { + type_info ti (typeid (template_)); + ti.add_base (typeid (nameable)); + insert (ti); + } + + // instantiates + // + { + type_info ti (typeid (instantiates)); + ti.add_base (typeid (edge)); + insert (ti); + } + + // instantiation + // + { + type_info ti (typeid (instantiation)); + ti.add_base (typeid (node)); + insert (ti); + } + + // type_template + // + { + type_info ti (typeid (type_template)); + ti.add_base (typeid (template_)); + insert (ti); + } + + // type_instantiation + // + { + type_info ti (typeid (type_instantiation)); + ti.add_base (typeid (type)); + ti.add_base (typeid (instantiation)); + insert (ti); + } + + } + } init_; + } +} diff --git a/odb/semantics/template.hxx b/odb/semantics/template.hxx new file mode 100644 index 0000000..1357dbf --- /dev/null +++ b/odb/semantics/template.hxx @@ -0,0 +1,158 @@ +// file : odb/semantics/template.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_SEMANTICS_TEMPLATE_HXX +#define ODB_SEMANTICS_TEMPLATE_HXX + +#include +#include + +namespace semantics +{ + // + // + class instantiates; + + class template_: public virtual nameable + { + typedef std::vector instantiated; + + public: + typedef + pointer_iterator + instantiated_iterator; + + instantiated_iterator + instantiated_begin () const + { + return instantiated_.begin (); + } + + instantiated_iterator + instantiated_end () const + { + return instantiated_.end (); + } + + public: + void + add_edge_right (instantiates& e) + { + instantiated_.push_back (&e); + } + + using nameable::add_edge_right; + + protected: + template_ () + { + } + + private: + instantiated instantiated_; + }; + + // + // + class instantiation; + + class instantiates: public edge + { + public: + typedef semantics::template_ template_type; + typedef semantics::instantiation instantiation_type; + + template_type& + template_ () const + { + return *template__; + } + + instantiation_type& + instantiation () const + { + return *instantiation_; + } + + public: + instantiates () + { + } + + void + set_left_node (instantiation_type& n) + { + instantiation_ = &n; + } + + void + set_right_node (template_type& n) + { + template__ = &n; + } + + private: + template_type* template__; + instantiation_type* instantiation_; + }; + + // + // + class instantiation: public virtual node + { + public: + typedef semantics::template_ template_type; + typedef semantics::instantiates instantiates_type; + + template_type& + template_ () const + { + return instantiates_->template_ (); + } + + instantiates_type& + instantiates () const + { + return *instantiates_; + } + + public: + void + add_edge_left (instantiates_type& e) + { + instantiates_ = &e; + } + + protected: + instantiation () + { + } + + private: + instantiates_type* instantiates_; + }; + + // + // Type template and instantiation. + // + + class type_template: public template_ + { + protected: + type_template () + { + } + }; + + class type_instantiation: public virtual type, public instantiation + { + protected: + type_instantiation () + { + } + }; +} + +#endif // ODB_SEMANTICS_TEMPLATE_HXX diff --git a/odb/semantics/union-template.cxx b/odb/semantics/union-template.cxx new file mode 100644 index 0000000..a83748f --- /dev/null +++ b/odb/semantics/union-template.cxx @@ -0,0 +1,42 @@ +// file : odb/semantics/union-template.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include + +namespace semantics +{ + // type info + // + namespace + { + struct init + { + init () + { + using compiler::type_info; + + // union_template + // + { + type_info ti (typeid (union_template)); + ti.add_base (typeid (type_template)); + ti.add_base (typeid (scope)); + insert (ti); + } + + // union_instantiation + // + { + type_info ti (typeid (union_instantiation)); + ti.add_base (typeid (union_)); + ti.add_base (typeid (type_instantiation)); + insert (ti); + } + } + } init_; + } +} diff --git a/odb/semantics/union-template.hxx b/odb/semantics/union-template.hxx new file mode 100644 index 0000000..1aaadb7 --- /dev/null +++ b/odb/semantics/union-template.hxx @@ -0,0 +1,41 @@ +// file : odb/semantics/union-template.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_SEMANTICS_UNION_TEMPLATE_HXX +#define ODB_SEMANTICS_UNION_TEMPLATE_HXX + +#include +#include +#include + +namespace semantics +{ + class union_template: public type_template, public scope + { + public: + union_template (path const& file, size_t line, size_t column) + : node (file, line, column) + { + } + + // Resolve conflict between scope::scope and nameable::scope. + // + using nameable::scope; + }; + + class union_instantiation: public union_, public type_instantiation + { + public: + union_instantiation (path const& file, size_t line, size_t column) + : node (file, line, column) + { + } + + using union_::add_edge_left; + using type_instantiation::add_edge_left; + }; +} + +#endif // ODB_SEMANTICS_UNION_TEMPLATE_HXX diff --git a/odb/semantics/union.cxx b/odb/semantics/union.cxx new file mode 100644 index 0000000..a4e62a1 --- /dev/null +++ b/odb/semantics/union.cxx @@ -0,0 +1,33 @@ +// file : odb/semantics/union.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include + +namespace semantics +{ + // type info + // + namespace + { + struct init + { + init () + { + using compiler::type_info; + + // union_ + // + { + type_info ti (typeid (union_)); + ti.add_base (typeid (type)); + ti.add_base (typeid (scope)); + insert (ti); + } + } + } init_; + } +} diff --git a/odb/semantics/union.hxx b/odb/semantics/union.hxx new file mode 100644 index 0000000..2873d97 --- /dev/null +++ b/odb/semantics/union.hxx @@ -0,0 +1,32 @@ +// file : odb/semantics/union.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_SEMANTICS_UNION_HXX +#define ODB_SEMANTICS_UNION_HXX + +#include + +namespace semantics +{ + class union_: public virtual type, public scope + { + public: + union_ (path const& file, size_t line, size_t column) + : node (file, line, column) + { + } + + // Resolve conflict between scope::scope and nameable::scope. + // + using nameable::scope; + + protected: + union_ () + { + } + }; +} + +#endif // ODB_SEMANTICS_UNION_HXX -- cgit v1.1