From cbdf12aa5110bf482ffda16a9d11f62bc837a0ed Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 9 Mar 2010 09:25:59 +0200 Subject: Traverse declarations in file order Also filter out declarations that are from other files. --- plugin.cxx | 97 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/plugin.cxx b/plugin.cxx index ec65633..b1faa32 100644 --- a/plugin.cxx +++ b/plugin.cxx @@ -31,6 +31,7 @@ extern "C" #include "cp/name-lookup.h" } +#include #include #include @@ -46,32 +47,41 @@ int plugin_is_GPL_compatible; // // * Will need to disable as many warnings as possible. // +// * How am I going to handle a case where the type of a private +// member is also private (i.e., local class or typedef -- fairly +// common). +// enum class_access { ca_public, ca_protected, ca_private }; const char* class_access_str[] = {"public", "protected", "private"}; -class collector +class traverser { public: - collector () + traverser () : file_ (main_input_filename) { } void - traverse (tree global_scope) + traverse (tree scope) { - traverse_namespace (global_scope); + // First collect all the declarations we are interested in + // in the line-decl map so that they appear in the source + // code order. + // + collect (scope); + emit (); } private: void - traverse_namespace (tree ns) + collect (tree ns) { cp_binding_level* level = NAMESPACE_LEVEL (ns); tree decl = level->names; - // Traverse declarations. + // Collect declarations. // for (; decl != NULL_TREE; decl = TREE_CHAIN (decl)) { @@ -79,20 +89,12 @@ private: { case TYPE_DECL: { - if (DECL_ARTIFICIAL (decl)) + if (DECL_ARTIFICIAL (decl) && + DECL_NAME (decl) != NULL_TREE && + TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE && + DECL_SOURCE_FILE (decl) == file_) { - tree type = TREE_TYPE (decl); - tree name = DECL_NAME (decl); - - if (name != NULL_TREE && TREE_CODE (type) == RECORD_TYPE) - { - warning (0, G_ ("class declaration %s in %s:%i"), - IDENTIFIER_POINTER (name), - DECL_SOURCE_FILE (decl), - DECL_SOURCE_LINE (decl)); - - traverse_class (type); - } + decls_[DECL_SOURCE_LINE (decl)] = decl; } break; @@ -128,31 +130,51 @@ private: // for(decl = level->namespaces; decl != NULL_TREE; decl = TREE_CHAIN (decl)) { - if (DECL_NAMESPACE_STD_P (decl) || DECL_IS_BUILTIN (decl)) - continue; - - tree name = DECL_NAME (decl); - - if (name == NULL_TREE) - { - warning (0, G_ ("anonymous namespace declaration in %s:%i"), - DECL_SOURCE_FILE (decl), - DECL_SOURCE_LINE (decl)); - } - else + if (!DECL_NAMESPACE_STD_P (decl) && + !DECL_IS_BUILTIN (decl) && + DECL_SOURCE_FILE (decl) == file_) { + tree name = DECL_NAME (decl); + warning (0, G_ ("namespace declaration %s in %s:%i"), - IDENTIFIER_POINTER (name), + name ? IDENTIFIER_POINTER (name) : "", DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); + + collect (decl); } + } + } + + void + emit () + { + for (decl_map::const_iterator i (decls_.begin ()), e (decls_.end ()); + i != e; ++i) + { + tree decl (i->second); + + switch (TREE_CODE (decl)) + { + case TYPE_DECL: + { + tree type = TREE_TYPE (decl); + tree name = DECL_NAME (decl); + + warning (0, G_ ("class declaration %s in %s:%i"), + IDENTIFIER_POINTER (name), + DECL_SOURCE_FILE (decl), + DECL_SOURCE_LINE (decl)); - traverse_namespace (decl); + emit_class (type); + break; + } + } } } void - traverse_class (tree c) + emit_class (tree c) { // Traverse base information. // @@ -250,7 +272,10 @@ private: } private: + typedef map decl_map; + string file_; + decl_map decls_; }; extern "C" void @@ -260,8 +285,8 @@ gate_callback (void* gcc_data, void* user_data) if (!errorcount && !sorrycount) { - collector c; - c.traverse (global_namespace); + traverser t; + t.traverse (global_namespace); } exit (0); -- cgit v1.1