From 5a2e172ce1f2d823bf0957602662bbab0c0dcd0b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 11 May 2012 12:07:56 +0200 Subject: Move lookup to semantic graph from parser --- cli/parser.cxx | 107 +----------------------------------------------- cli/parser.hxx | 19 --------- cli/semantics/unit.hxx | 21 ++++++++++ cli/semantics/unit.txx | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 125 deletions(-) create mode 100644 cli/semantics/unit.txx (limited to 'cli') diff --git a/cli/parser.cxx b/cli/parser.cxx index 55090d4..3f9b19c 100644 --- a/cli/parser.cxx +++ b/cli/parser.cxx @@ -488,7 +488,7 @@ class_def () else ns = scope_->fq_name (); - if (class_* b = lookup (ns, name)) + if (class_* b = cur_->lookup (ns, name)) root_->new_edge (*n, *b); else { @@ -1289,108 +1289,3 @@ fundamental_type (token& t, string& r) return true; } - -template -T* parser:: -lookup (string const& ss, string const& name, cli_unit* unit, bool outer) -{ - if (unit == 0) - unit = cur_; - - // Resolve the starting scope in this unit, if any. - // - string::size_type b (0), e; - scope* s (0); - - do - { - e = ss.find ("::", b); - string n (ss, b, e == string::npos ? e : e - b); - - if (n.empty ()) - s = unit; - else - { - scope::names_iterator_pair ip (s->find (n)); - - for (s = 0; ip.first != ip.second; ++ip.first) - if (s = dynamic_cast (&ip.first->named ())) - break; - - if (s == 0) - break; // No such scope in this unit. - } - - b = e; - - if (b == string::npos) - break; - - b += 2; - } while (true); - - // If we have the starting scope, then try to resolve the name in it. - // - if (s != 0) - { - b = 0; - - do - { - e = name.find ("::", b); - string n (name, b, e == string::npos ? e : e - b); - - scope::names_iterator_pair ip (s->find (n)); - - // If this is the last name, then see if we have the desired type. - // - if (e == string::npos) - { - for (; ip.first != ip.second; ++ip.first) - if (T* r = dynamic_cast (&ip.first->named ())) - return r; - } - // Otherwise, this should be a scope. - // - else - { - for (s = 0; ip.first != ip.second; ++ip.first) - if (s = dynamic_cast (&ip.first->named ())) - break; - - if (s == 0) - break; // No such inner scope. - } - - b = e; - - if (b == string::npos) - break; - - b += 2; - } while (true); - } - - // If we are here, then that means the lookup didn't find anything in - // this unit. The next step is to examine all the included units. - // - for (cli_unit::includes_iterator i (unit->includes_begin ()); - i != unit->includes_end (); - ++i) - { - if (cli_includes* ci = dynamic_cast (&*i)) - if (T* r = lookup (ss, name, &ci->includee (), false)) - return r; - } - - // If we still haven't found anything, then the next step is to search - // one-outer scope, unless it is the global namespace. - // - if (outer && !ss.empty ()) - { - string n (ss, 0, ss.rfind ("::")); - return lookup (n, name, unit, true); - } - - return 0; -} diff --git a/cli/parser.hxx b/cli/parser.hxx index f7f6d68..29f4b22 100644 --- a/cli/parser.hxx +++ b/cli/parser.hxx @@ -61,25 +61,6 @@ private: void recover (token& t); - // Lookup a name in the specified starting scope. Empty scope denotes - // the global namespace. Starting scope should be a fully-qualified - // name while name can be qualified but should not be fully-qualified - // (to lookup a fully-qualified name use the global namespace as the - // starting scope). - // - // If starting unit is not specified, the lookup is performed in the - // current unit. It then continues in all the units that the starting - // unit includes, transitively. - // - // The outer flag specifies whether to search the outer scopes. - // - template - T* - lookup (std::string const& scope, - std::string const& name, - semantics::cli_unit* unit = 0, - bool outer = true); - private: paths const include_paths_; diff --git a/cli/semantics/unit.hxx b/cli/semantics/unit.hxx index f20ba82..cd4198b 100644 --- a/cli/semantics/unit.hxx +++ b/cli/semantics/unit.hxx @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -139,6 +140,24 @@ namespace semantics typedef std::vector includes_list; public: + // Lookup a name in the specified starting scope. Empty scope denotes + // the global namespace. Starting scope should be a fully-qualified + // name while name can be qualified but should not be fully-qualified + // (to lookup a fully-qualified name use the global namespace as the + // starting scope). + // + // The lookup starts in this unit and continues in all the units that + // this unit includes, transitively. + // + // The outer flag specifies whether to search the outer scopes. + // + template + T* + lookup (std::string const& scope, + std::string const& name, + bool outer = true); + + public: typedef pointer_iterator includes_iterator; @@ -286,4 +305,6 @@ namespace semantics }; } +#include + #endif // CLI_SEMANTICS_UNIT_HXX diff --git a/cli/semantics/unit.txx b/cli/semantics/unit.txx new file mode 100644 index 0000000..f884e18 --- /dev/null +++ b/cli/semantics/unit.txx @@ -0,0 +1,109 @@ +// file : cli/semantics/unit.txx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +namespace semantics +{ + template + T* cli_unit:: + lookup (std::string const& ss, std::string const& name, bool outer) + { + using std::string; + + // Resolve the starting scope in this unit, if any. + // + string::size_type b (0), e; + scope* s (0); + + do + { + e = ss.find ("::", b); + string n (ss, b, e == string::npos ? e : e - b); + + if (n.empty ()) + s = this; + else + { + scope::names_iterator_pair ip (s->find (n)); + + for (s = 0; ip.first != ip.second; ++ip.first) + if (s = dynamic_cast (&ip.first->named ())) + break; + + if (s == 0) + break; // No such scope in this unit. + } + + b = e; + + if (b == string::npos) + break; + + b += 2; + } while (true); + + // If we have the starting scope, then try to resolve the name in it. + // + if (s != 0) + { + b = 0; + + do + { + e = name.find ("::", b); + string n (name, b, e == string::npos ? e : e - b); + + scope::names_iterator_pair ip (s->find (n)); + + // If this is the last name, then see if we have the desired type. + // + if (e == string::npos) + { + for (; ip.first != ip.second; ++ip.first) + if (T* r = dynamic_cast (&ip.first->named ())) + return r; + } + // Otherwise, this should be a scope. + // + else + { + for (s = 0; ip.first != ip.second; ++ip.first) + if (s = dynamic_cast (&ip.first->named ())) + break; + + if (s == 0) + break; // No such inner scope. + } + + b = e; + + if (b == string::npos) + break; + + b += 2; + } while (true); + } + + // If we are here, then that means the lookup didn't find anything in + // this unit. The next step is to examine all the included units. + // + for (includes_iterator i (includes_begin ()); i != includes_end (); ++i) + { + if (cli_includes* ci = dynamic_cast (&*i)) + if (T* r = ci->includee ().lookup (ss, name, false)) + return r; + } + + // If we still haven't found anything, then the next step is to search + // one-outer scope, unless it is the global namespace. + // + if (outer && !ss.empty ()) + { + string n (ss, 0, ss.rfind ("::")); + return lookup (n, name, true); + } + + return 0; + } +} -- cgit v1.1