diff options
Diffstat (limited to 'odb/odb/semantics/derived.cxx')
-rw-r--r-- | odb/odb/semantics/derived.cxx | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/odb/odb/semantics/derived.cxx b/odb/odb/semantics/derived.cxx new file mode 100644 index 0000000..771ad21 --- /dev/null +++ b/odb/odb/semantics/derived.cxx @@ -0,0 +1,254 @@ +// file : odb/semantics/derived.cxx +// license : GNU GPL v3; see accompanying LICENSE file + +#include <sstream> + +#include <libcutl/compiler/type-info.hxx> +#include <odb/semantics/derived.hxx> + +using namespace std; + +namespace semantics +{ + qualifies:: + qualifies () + : hint_ (0) + { + } + + qualifier:: + qualifier (path const& file, + size_t line, + size_t column, + tree tn, + bool c, + bool v, + bool r) + : node (file, line, column, tn), c_ (c), v_ (v), r_ (r) + { + } + + string qualifier:: + fq_name (names* hint) const + { + if (hint != 0 || defined_ != 0) + return nameable::fq_name (hint); + + // GCC type_as_string() for some reason cannot correctly print names + // like 'const std::string'. Instead it prints 'const string'. + // + type& bt (base_type ()); + + // Use the trailing qualifier syntax so that we don't get bogged down + // in stuff like 'const const foo*'. We also have to handle arrays in + // a special way since char[16] const is not a legal syntax. + // + string q; + if (c_) + q += " const"; + + if (v_) + q += " volatile"; + + if (r_) + q += " __restrict"; + + hint = qualifies ().hint (); + + if (array* a = dynamic_cast<array*> (&bt)) + return a->fq_name (hint, q); + else + return bt.fq_name (hint) + q; + } + + points:: + points () + : hint_ (0) + { + } + + pointer:: + pointer (path const& file, size_t line, size_t column, tree tn) + : node (file, line, column, tn) + { + } + + string pointer:: + fq_name (names* hint) const + { + if (hint != 0 || defined_ != 0) + return nameable::fq_name (hint); + + // GCC type_as_string() for some reason cannot correctly print names + // like 'const std::string*'. Instead it prints 'const string*'. + // + string r (base_type ().fq_name (points ().hint ())); + r += '*'; + return r; + } + + references:: + references () + : hint_ (0) + { + } + + reference:: + reference (path const& file, size_t line, size_t column, tree tn) + : node (file, line, column, tn) + { + } + + string reference:: + fq_name (names* hint) const + { + if (hint != 0 || defined_ != 0) + return nameable::fq_name (hint); + + // GCC type_as_string() for some reason cannot correctly print names + // like 'const std::string&'. Instead it prints 'const string&'. + // + string r (base_type ().fq_name (points ().hint ())); + r += '&'; + return r; + } + + contains:: + contains () + : hint_ (0) + { + } + + array:: + array (path const& file, + size_t line, + size_t column, + tree tn, + unsigned long long size) + : node (file, line, column, tn), size_ (size) + { + } + + string array:: + fq_name (names* hint) const + { + // GCC type_as_string() for some reason cannot correctly print names + // like 'const std::string[123]'. Instead it prints 'const string[123]'. + // + string t; + return fq_name (hint, t); + } + + string array:: + fq_name (names* hint, string& t) const + { + if (hint != 0 || defined_ != 0) + return nameable::fq_name (hint) + t; + + t += '['; + ostringstream ostr; + ostr << size (); + t += ostr.str (); + + if (size () > 0xFFFFFFFF) + t += "ULL"; + else if (size () > 2147483647) + t += "U"; + + t += ']'; + + type& bt (base_type ()); + hint = contains ().hint (); + array* a; + + if (hint != 0 || (a = dynamic_cast<array*> (&bt)) == 0) + return bt.fq_name (hint) + t; + else + return a->fq_name (0, t); + } + + // type info + // + namespace + { + struct init + { + init () + { + using compiler::type_info; + + // derived_type + // + { + type_info ti (typeid (derived_type)); + ti.add_base (typeid (type)); + insert (ti); + } + + // qualifies + // + { + type_info ti (typeid (qualifies)); + ti.add_base (typeid (edge)); + insert (ti); + } + + // qualifier + // + { + type_info ti (typeid (qualifier)); + ti.add_base (typeid (derived_type)); + insert (ti); + } + + // points + // + { + type_info ti (typeid (points)); + ti.add_base (typeid (edge)); + insert (ti); + } + + // pointer + // + { + type_info ti (typeid (pointer)); + ti.add_base (typeid (derived_type)); + insert (ti); + } + + // references + // + { + type_info ti (typeid (references)); + ti.add_base (typeid (edge)); + insert (ti); + } + + // reference + // + { + type_info ti (typeid (reference)); + ti.add_base (typeid (derived_type)); + insert (ti); + } + + // contains + // + { + type_info ti (typeid (contains)); + ti.add_base (typeid (edge)); + insert (ti); + } + + // array + // + { + type_info ti (typeid (array)); + ti.add_base (typeid (derived_type)); + insert (ti); + } + } + } init_; + } +} |