From ad637abaa62a26461b276769c35dd1b67036b54b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 23 Mar 2010 13:55:13 +0200 Subject: Handle type declarations in class scope --- odb/plugin.cxx | 261 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 145 insertions(+), 116 deletions(-) (limited to 'odb/plugin.cxx') diff --git a/odb/plugin.cxx b/odb/plugin.cxx index 5af4230..0f34a5b 100644 --- a/odb/plugin.cxx +++ b/odb/plugin.cxx @@ -284,98 +284,106 @@ private: { case TYPE_DECL: { - tree t (TREE_TYPE (decl)); - tree decl_name (DECL_NAME (decl)); - char const* name (IDENTIFIER_POINTER (decl_name)); + emit_type_decl (decl); + break; + } + case TEMPLATE_DECL: + { + break; + } + } + } + } - if (DECL_ARTIFICIAL (decl) && TREE_CODE (t) == RECORD_TYPE) - { - // 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 (decl_name)) - { - tree d (TYPE_NAME (t)); + // Emit a type declaration. This is either a class definition/declaration + // or a typedef. + // + void + emit_type_decl (tree decl) + { + tree t (TREE_TYPE (decl)); + tree decl_name (DECL_NAME (decl)); + char const* name (IDENTIFIER_POINTER (decl_name)); - if (d != NULL_TREE && - !DECL_ARTIFICIAL (d) && - DECL_NAME (d) != NULL_TREE && - !ANON_AGGRNAME_P (DECL_NAME (d))) - { - decl = d; - decl_name = DECL_NAME (decl); - name = IDENTIFIER_POINTER (decl_name); - } - else - { - // This type has only the synthesized name which means that - // it is either typedef'ed as a derived type or it is used - // to declare a varibale or similar. The first case will be - // covered by the typedef handling code below. The second - // case we don't care about. - // - break; - } - } + if (DECL_ARTIFICIAL (decl) && TREE_CODE (t) == RECORD_TYPE) + { + // 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 (decl_name)) + { + tree d (TYPE_NAME (t)); - path file (DECL_SOURCE_FILE (decl)); - size_t line (DECL_SOURCE_LINE (decl)); - size_t clmn (DECL_SOURCE_COLUMN (decl)); + if (d != NULL_TREE && + !DECL_ARTIFICIAL (d) && + DECL_NAME (d) != NULL_TREE && + !ANON_AGGRNAME_P (DECL_NAME (d))) + { + decl = d; + decl_name = DECL_NAME (decl); + name = IDENTIFIER_POINTER (decl_name); + } + else + { + // This type has only the synthesized name which means that + // it is either typedef'ed as a derived type or it is used + // to declare a varibale or similar. The first case will be + // covered by the typedef handling code below. The second + // case will be covere by emit_type(). + // + return; + } + } - warning (0, G_ ("start class declaration %s in %s:%d"), - name, - DECL_SOURCE_FILE (decl), - DECL_SOURCE_LINE (decl)); + path file (DECL_SOURCE_FILE (decl)); + size_t line (DECL_SOURCE_LINE (decl)); + size_t clmn (DECL_SOURCE_COLUMN (decl)); - class_& node (emit_class (t, file, line, clmn)); + warning (0, G_ ("start class declaration %s in %s:%d"), + name, + DECL_SOURCE_FILE (decl), + DECL_SOURCE_LINE (decl)); - if (COMPLETE_TYPE_P (t)) - unit_->new_edge (*scope_, node, name); - else - unit_->new_edge (*scope_, node, name); + class_& node (emit_class (t, file, line, clmn)); - warning (0, G_ ("end class declaration %s (%p) in %s:%d"), - name, - &node, - DECL_SOURCE_FILE (decl), - DECL_SOURCE_LINE (decl)); - } - else - { - // Normal typedef. We need to detect and ignore the anonymous - // class typedef case described above since we already used - // this name to define the class. - // - if (TREE_CODE (t) == RECORD_TYPE && - TYPE_NAME (TYPE_MAIN_VARIANT (t)) == decl) - break; + if (COMPLETE_TYPE_P (t)) + unit_->new_edge (*scope_, node, name); + else + unit_->new_edge (*scope_, node, name); - path f (DECL_SOURCE_FILE (decl)); - size_t l (DECL_SOURCE_LINE (decl)); - size_t c (DECL_SOURCE_COLUMN (decl)); + warning (0, G_ ("end class declaration %s (%p) in %s:%d"), + name, + &node, + DECL_SOURCE_FILE (decl), + DECL_SOURCE_LINE (decl)); + } + else + { + // Normal typedef. We need to detect and ignore the anonymous + // class typedef case described above since we already used + // this name to define the class. + // + if (TREE_CODE (t) == RECORD_TYPE && + TYPE_NAME (TYPE_MAIN_VARIANT (t)) == decl) + return; - type& node (emit_type (t, f, l, c)); - unit_->new_edge (*scope_, node, name); + path f (DECL_SOURCE_FILE (decl)); + size_t l (DECL_SOURCE_LINE (decl)); + size_t c (DECL_SOURCE_COLUMN (decl)); - string s (emit_type_name (t, false)); + type& node (emit_type (t, f, l, c)); + unit_->new_edge (*scope_, node, name); - warning (0, G_ ("typedef declaration %s (%p) -> %s in %s:%i"), - s.c_str (), - &node, - name, - DECL_SOURCE_FILE (decl), - DECL_SOURCE_LINE (decl)); - } + string s (emit_type_name (t, false)); - break; - } - case TEMPLATE_DECL: - { - break; - } - } + warning (0, G_ ("typedef declaration %s (%p) -> %s in %s:%i"), + s.c_str (), + &node, + name, + DECL_SOURCE_FILE (decl), + DECL_SOURCE_LINE (decl)); } } @@ -451,50 +459,26 @@ private: *class_node, dynamic_cast (*base_node), a, virt); } - // Traverse data members. + // Collect members so that we can traverse then in the source + // code order. // + decl_set decls; + for (tree d (TYPE_FIELDS (c)); d != NULL_TREE ; d = TREE_CHAIN (d)) { - //if (DECL_ARTIFICIAL (field)) - // continue; - - // if (TREE_CODE (field) == TYPE_DECL && TREE_TYPE (field) == c) - // continue; - switch (TREE_CODE (d)) { + case TYPE_DECL: + { + if (!DECL_SELF_REFERENCE_P (d)) + decls.insert (d); + break; + } case FIELD_DECL: { if (!DECL_ARTIFICIAL (d)) - { - 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 (*class_node, member_node, name, a); - - warning (0, G_ ("\t%s data member %s (%p) %s in %s:%i"), - a.string (), - type_name.c_str (), - &type_node, - name, - file.string ().c_str (), - line); - - break; - } + decls.insert (d); + break; } default: { @@ -520,6 +504,51 @@ private: } } + 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 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 (*class_node, member_node, name, a); + + warning (0, G_ ("\t%s data member %s (%p) %s in %s:%i"), + a.string (), + type_name.c_str (), + &type_node, + name, + file.string ().c_str (), + line); + + break; + } + } + } + return *class_node; } -- cgit v1.1