summaryrefslogtreecommitdiff
path: root/odb/semantics
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-10-15 07:01:17 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-10-15 07:01:17 +0200
commita482f1c4dd4efab83d3b19309900f1cbf54383a5 (patch)
tree3c1ab27e420cbf760a54a1c4be61bbd0448a4873 /odb/semantics
parent400d258aab3722be3a4b8548870afad1574f3ad8 (diff)
Automatically map C++11 enum classes (strong enums)
Diffstat (limited to 'odb/semantics')
-rw-r--r--odb/semantics/elements.hxx7
-rw-r--r--odb/semantics/enum.cxx21
-rw-r--r--odb/semantics/enum.hxx90
-rw-r--r--odb/semantics/fundamental.cxx68
-rw-r--r--odb/semantics/fundamental.hxx61
5 files changed, 204 insertions, 43 deletions
diff --git a/odb/semantics/elements.hxx b/odb/semantics/elements.hxx
index 1199c0c..059b639 100644
--- a/odb/semantics/elements.hxx
+++ b/odb/semantics/elements.hxx
@@ -178,9 +178,10 @@ namespace semantics
// edges.
//
void
- add_edge_right (edge&)
- {
- }
+ add_edge_left (edge&) {}
+
+ void
+ add_edge_right (edge&) {}
protected:
// For virtual inheritance. Should never be actually called.
diff --git a/odb/semantics/enum.cxx b/odb/semantics/enum.cxx
index 7cffe30..dd8b905 100644
--- a/odb/semantics/enum.cxx
+++ b/odb/semantics/enum.cxx
@@ -22,13 +22,18 @@ namespace semantics
{
}
+ underlies::
+ underlies ()
+ : type_ (0), enum__ (0), hint_ (0)
+ {
+ }
+
enum_::
enum_ (path const& file,
size_t line,
size_t column,
- tree tn,
- bool unsigned_)
- : node (file, line, column, tn), unsigned__ (unsigned_)
+ tree tn)
+ : node (file, line, column, tn)
{
}
@@ -54,15 +59,25 @@ namespace semantics
//
{
type_info ti (typeid (enumerator));
+ ti.add_base (typeid (nameable));
ti.add_base (typeid (instance));
insert (ti);
}
+ // underlies
+ //
+ {
+ type_info ti (typeid (underlies));
+ ti.add_base (typeid (edge));
+ insert (ti);
+ }
+
// enum_
//
{
type_info ti (typeid (enum_));
ti.add_base (typeid (type));
+ ti.add_base (typeid (scope));
insert (ti);
}
}
diff --git a/odb/semantics/enum.hxx b/odb/semantics/enum.hxx
index de07885..02f2b27 100644
--- a/odb/semantics/enum.hxx
+++ b/odb/semantics/enum.hxx
@@ -7,6 +7,7 @@
#include <vector>
#include <odb/semantics/elements.hxx>
+#include <odb/semantics/fundamental.hxx>
namespace semantics
{
@@ -101,7 +102,62 @@ namespace semantics
//
//
- class enum_: public type
+ class underlies: public edge
+ {
+ public:
+ typedef semantics::enum_ enum_type;
+
+ integral_type&
+ type () const
+ {
+ return *type_;
+ }
+
+ enum_type&
+ enum_ () const
+ {
+ return *enum__;
+ }
+
+ // Names edge in terms of which this edge was defined. Can be NULL.
+ //
+ public:
+ void
+ hint (names& hint)
+ {
+ hint_ = &hint;
+ }
+
+ names*
+ hint () const
+ {
+ return hint_;
+ }
+
+ public:
+ underlies ();
+
+ void
+ set_left_node (integral_type& n)
+ {
+ type_ = &n;
+ }
+
+ void
+ set_right_node (enum_type& n)
+ {
+ enum__ = &n;
+ }
+
+ protected:
+ integral_type* type_;
+ enum_type* enum__;
+ names* hint_;
+ };
+
+ //
+ //
+ class enum_: public type, public scope
{
private:
typedef std::vector<enumerates*> enumerates_list;
@@ -123,14 +179,38 @@ namespace semantics
return enumerates_.end ();
}
+ underlies&
+ underlied () const
+ {
+ return *underlied_;
+ }
+
+ integral_type&
+ underlying_type () const
+ {
+ return underlied_->type ();
+ }
+
+ names*
+ underlying_type_hint () const
+ {
+ return underlied_->hint ();
+ }
+
bool
unsigned_ () const
{
- return unsigned__;
+ return underlying_type ().unsigned_ ();
}
public:
- enum_ (path const&, size_t line, size_t column, tree, bool unsigned_);
+ enum_ (path const&, size_t line, size_t column, tree);
+
+ void
+ add_edge_right (underlies& e)
+ {
+ underlied_ = &e;
+ }
void
add_edge_left (enumerates& e)
@@ -138,9 +218,11 @@ namespace semantics
enumerates_.push_back (&e);
}
+ using scope::add_edge_left;
+
private:
- bool unsigned__;
enumerates_list enumerates_;
+ underlies* underlied_;
};
}
diff --git a/odb/semantics/fundamental.cxx b/odb/semantics/fundamental.cxx
index 537a5cf..4a3bd69 100644
--- a/odb/semantics/fundamental.cxx
+++ b/odb/semantics/fundamental.cxx
@@ -2,6 +2,8 @@
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
// license : GNU GPL v3; see accompanying LICENSE file
+#include <odb/gcc.hxx>
+
#include <cutl/compiler/type-info.hxx>
#include <odb/semantics/fundamental.hxx>
@@ -22,6 +24,22 @@ namespace semantics
return type::fq_name (hint);
}
+ // char
+ //
+ bool fund_char::
+ unsigned_ () const
+ {
+ return TYPE_UNSIGNED (tree_node ()) != 0;
+ }
+
+ // wchar_t
+ //
+ bool fund_wchar::
+ unsigned_ () const
+ {
+ return TYPE_UNSIGNED (tree_node ()) != 0;
+ }
+
// type info
//
namespace
@@ -48,11 +66,19 @@ namespace semantics
insert (ti);
}
+ // integral_type
+ //
+ {
+ type_info ti (typeid (integral_type));
+ ti.add_base (typeid (fund_type));
+ insert (ti);
+ }
+
// fund_bool
//
{
type_info ti (typeid (fund_bool));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -60,7 +86,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_char));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -68,7 +94,23 @@ namespace semantics
//
{
type_info ti (typeid (fund_wchar));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
+ insert (ti);
+ }
+
+ // fund_char16
+ //
+ {
+ type_info ti (typeid (fund_char16));
+ ti.add_base (typeid (integral_type));
+ insert (ti);
+ }
+
+ // fund_char32
+ //
+ {
+ type_info ti (typeid (fund_char32));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -76,7 +118,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_signed_char));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -84,7 +126,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_unsigned_char));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -92,7 +134,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_short));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -100,7 +142,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_unsigned_short));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -108,7 +150,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_int));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -116,7 +158,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_unsigned_int));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -124,7 +166,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_long));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -132,7 +174,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_unsigned_long));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -140,7 +182,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_long_long));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
@@ -148,7 +190,7 @@ namespace semantics
//
{
type_info ti (typeid (fund_unsigned_long_long));
- ti.add_base (typeid (fund_type));
+ ti.add_base (typeid (integral_type));
insert (ti);
}
diff --git a/odb/semantics/fundamental.hxx b/odb/semantics/fundamental.hxx
index 55ce322..75cbbf5 100644
--- a/odb/semantics/fundamental.hxx
+++ b/odb/semantics/fundamental.hxx
@@ -13,7 +13,7 @@ namespace semantics
// Fundamental C++ types.
//
- struct fund_type: public type
+ struct fund_type: type
{
virtual string
fq_name () const;
@@ -27,84 +27,105 @@ namespace semantics
fund_void (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
};
- struct fund_bool: fund_type
- {
- fund_bool (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
- };
-
//
// Integral.
//
- struct fund_char: fund_type
+ struct integral_type: fund_type
+ {
+ virtual bool
+ unsigned_ () const = 0;
+ };
+
+ struct fund_bool: integral_type
+ {
+ fund_bool (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return true;}
+ };
+
+ struct fund_char: integral_type
{
fund_char (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const;
};
- struct fund_wchar: fund_type
+ struct fund_wchar: integral_type
{
fund_wchar (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const;
};
- struct fund_char16: fund_type
+ struct fund_char16: integral_type
{
fund_char16 (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return true;}
};
- struct fund_char32: fund_type
+ struct fund_char32: integral_type
{
fund_char32 (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return true;}
};
- struct fund_signed_char: fund_type
+ struct fund_signed_char: integral_type
{
fund_signed_char (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return false;}
};
- struct fund_unsigned_char: fund_type
+ struct fund_unsigned_char: integral_type
{
fund_unsigned_char (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return true;}
};
- struct fund_short: fund_type
+ struct fund_short: integral_type
{
fund_short (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return false;}
};
- struct fund_unsigned_short: fund_type
+ struct fund_unsigned_short: integral_type
{
fund_unsigned_short (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return true;}
};
- struct fund_int: fund_type
+ struct fund_int: integral_type
{
fund_int (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return false;}
};
- struct fund_unsigned_int: fund_type
+ struct fund_unsigned_int: integral_type
{
fund_unsigned_int (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return true;}
};
- struct fund_long: fund_type
+ struct fund_long: integral_type
{
fund_long (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return false;}
};
- struct fund_unsigned_long: fund_type
+ struct fund_unsigned_long: integral_type
{
fund_unsigned_long (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return true;}
};
- struct fund_long_long: fund_type
+ struct fund_long_long: integral_type
{
fund_long_long (tree tn): node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return false;}
};
- struct fund_unsigned_long_long: fund_type
+ struct fund_unsigned_long_long: integral_type
{
fund_unsigned_long_long (tree tn)
: node (path ("<fundamental>"), 0, 0, tn) {}
+ virtual bool unsigned_ () const {return true;}
};
//