summaryrefslogtreecommitdiff
path: root/odb/lookup.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-09-16 16:03:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-09-16 16:03:25 +0200
commitb79567fbc72df23f870049652d5f254aba948bea (patch)
tree186168269cf249ce97be89fd02aab4c75e83574c /odb/lookup.cxx
parentd780414989ef7e101cdaf269d4b01003d0721e6a (diff)
Support for views; integrated part
Diffstat (limited to 'odb/lookup.cxx')
-rw-r--r--odb/lookup.cxx129
1 files changed, 129 insertions, 0 deletions
diff --git a/odb/lookup.cxx b/odb/lookup.cxx
new file mode 100644
index 0000000..4f87203
--- /dev/null
+++ b/odb/lookup.cxx
@@ -0,0 +1,129 @@
+// file : odb/lookup.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v3; see accompanying LICENSE file
+
+#include <odb/lookup.hxx>
+
+using namespace std;
+
+namespace lookup
+{
+ std::string
+ parse_scoped_name (std::string& t, cpp_ttype& tt, cxx_lexer& lex)
+ {
+ string name;
+
+ if (tt == CPP_SCOPE)
+ {
+ name += "::";
+ tt = lex.next (t);
+ }
+
+ while (true)
+ {
+ // @@ We still need to handle fundamental types, e.g., unsigned int.
+ //
+ if (tt != CPP_NAME && tt != CPP_KEYWORD)
+ throw invalid_name ();
+
+ name += t;
+ tt = lex.next (t);
+
+ if (tt != CPP_SCOPE)
+ break;
+
+ name += "::";
+ tt = lex.next (t);
+ }
+
+ return name;
+ }
+
+ tree
+ resolve_scoped_name (string& t,
+ cpp_ttype& tt,
+ cpp_ttype& ptt,
+ cxx_lexer& lex,
+ tree scope,
+ string& name,
+ bool is_type,
+ tree* end_scope)
+ {
+ tree id;
+ bool first (true);
+
+ if (tt == CPP_SCOPE)
+ {
+ name += "::";
+ scope = global_namespace;
+ first = false;
+
+ ptt = tt;
+ tt = lex.next (t);
+ }
+
+ while (true)
+ {
+ if (end_scope != 0)
+ *end_scope = scope;
+
+ // @@ We still need to handle fundamental types, e.g., unsigned int.
+ //
+ if (tt != CPP_NAME && tt != CPP_KEYWORD)
+ throw invalid_name ();
+
+ name += t;
+ id = get_identifier (t.c_str ());
+ ptt = tt;
+ tt = lex.next (t);
+
+ bool last (tt != CPP_SCOPE);
+ tree decl = lookup_qualified_name (scope, id, last && is_type, false);
+
+ // If this is the first component in the name, then also search the
+ // outer scopes.
+ //
+ if (decl == error_mark_node && first && scope != global_namespace)
+ {
+ do
+ {
+ scope = TYPE_P (scope)
+ ? CP_TYPE_CONTEXT (scope)
+ : CP_DECL_CONTEXT (scope);
+ decl = lookup_qualified_name (scope, id, last && is_type, false);
+ } while (decl == error_mark_node && scope != global_namespace);
+ }
+
+ if (decl == error_mark_node)
+ throw unable_to_resolve (name, last);
+
+ scope = decl;
+
+ if (last)
+ break;
+
+ first = false;
+
+ if (TREE_CODE (scope) == TYPE_DECL)
+ scope = TREE_TYPE (scope);
+
+ name += "::";
+
+ ptt = tt;
+ tt = lex.next (t);
+ }
+
+ // Get the actual type if this is a TYPE_DECL.
+ //
+ if (is_type)
+ {
+ if (TREE_CODE (scope) == TYPE_DECL)
+ scope = TREE_TYPE (scope);
+
+ scope = TYPE_MAIN_VARIANT (scope);
+ }
+
+ return scope;
+ }
+}