Synopsis - Synopsis/PTree/Encoding.hh

File: Synopsis/PTree/Encoding.hh

      1//
      2// Copyright (C) 1997 Shigeru Chiba
      3// Copyright (C) 2004 Stefan Seefeld
      4// All rights reserved.
      5// Licensed to the public under the terms of the GNU LGPL (>= 2),
      6// see the file COPYING for details.
      7//
      8#ifndef Synopsis_PTree_Encoding_hh_
      9#define Synopsis_PTree_Encoding_hh_
     10
     11#include <string>
     12#include <iostream>
     13#include <cassert>
     14#include <cstring>
     15#include <cstdio> // for EOF
     16
     17namespace Synopsis
     18{
     19namespace PTree
     20{
     21
     22class Node;
     23class Atom;
     24
     25//. An Encoding represents a mangled (type) name. Here is a quick reference of the grammar:
     26//.
     27//. - `b`: boolean
     28//. - `c`: char
     29//. - `w`: wchar_t
     30//. - `i`: int (signed, unsigned)
     31//. - `s`: short (short int)
     32//. - `l`: long (long int)
     33//. - `j`: long long
     34//. - `f`: float
     35//. - `d`: double
     36//. - `r`: long double
     37//. - `v`: void
     38//. - `T`: template class (e.g. `Foo<int,char>` ==> `T[3]Foo[2]ic`.  `[2]` means
     39//.   the length of `ic`.  It doesn't mean the number of template arguments.
     40//.
     41//. - `e`: ...
     42//. - `?`: no return type.  the return type of constructors
     43//. - `*`: non-type template parameter
     44//.
     45//. - `S`: `signed`
     46//. - `U`: `unsigned`
     47//. - `C`: `const`
     48//. - `V`: `volatile`
     49//.
     50//. - `P`: pointer
     51//. - `R`: reference
     52//. - `A`: array (e.g. `char[16]` ==> `A16_c`)
     53//. - `F`: function (e.g. `char foo(int)` ==> `Fi_c`)
     54//. - `M`: pointer to member (e.g. `Type::*` ==> `M[4]Type`)
     55//.
     56//. - `Q`: qualified class (e.g. `X::YY` ==> `Q[2][1]X[2]YY`, `::YY` ==> `Q[2][0][2]YY`)
     57//.
     58//. - `[x]`: means `0x80 + x`
     59//. - `0`: means `::` (global scope)
     60//.
     61//. Special function names:
     62//.
     63//. - operator + ==> +
     64//. - operator new[] ==> new[]
     65//. - operator <type> ==> @<encoded type>		cast operator
     66//.
     67class Encoding
     68{
     69public:
     70  struct char_traits
     71  {
     72    typedef unsigned char  char_type;
     73    typedef unsigned long  int_type;
     74    typedef std::streampos pos_type;
     75    typedef std::streamoff off_type;
     76    typedef std::mbstate_t state_type;
     77
     78    static void assign(char_type &c1, const char_type &c2) { c1 = c2;}
     79    static bool eq(const char_type &c1, const char_type &c2) { return c1 == c2;}
     80    static bool lt(const char_type &c1, const char_type &c2) { return c1 < c2;}
     81    static int compare(const char_type *s1, const char_type *s2, std::size_t n) { return memcmp(s1, s2, n);}
     82    static std::size_t length(const char_type *s) { return strlen((const char *)s);}
     83    static const char_type *find(const char_type *s, std::size_t n, const char_type &a)
     84    { return static_cast<const char_type *>(memchr(s, a, n));}
     85    static char_type *move(char_type *s1, const char_type *s2, std::size_t n)
     86    { return static_cast<char_type *>(memmove(s1, s2, n));}
     87    static char_type *copy(char_type *s1, const char_type *s2, std::size_t n)
     88    { return static_cast<char_type *>(memcpy(s1, s2, n));}
     89    static char_type *assign(char_type *s, std::size_t n, char_type a)
     90    { return static_cast<char_type *>(memset(s, a, n));}
     91    static char_type to_char_type(const int_type &c) { return static_cast<char_type>(c);}
     92    static int_type to_int_type(const char_type &c) { return static_cast<int_type>(c);}
     93    static bool eq_int_type(const int_type &c1, const int_type &c2) { return c1 == c2;}
     94    static int_type eof() { return static_cast<int_type>(EOF);}
     95    static int_type not_eof(const int_type &c) { return !eq_int_type(c, eof()) ? c : to_int_type(char_type());}
     96  };
     97
     98  typedef std::basic_string<unsigned char, char_traits> Code;
     99  typedef Code::const_iterator iterator;
    100
    101  static void do_init_static();
    102
    103  Encoding() {}
    104  Encoding(const Code &b) : my_buffer(b) {}
    105  Encoding(const char *b) : my_buffer(b, b + strlen(b)) {}
    106  Encoding(const char *b, size_t s) : my_buffer(b, b + s) {}
    107  Encoding(iterator b, iterator e) : my_buffer(b, e) {}
    108  static Encoding simple_name(PTree::Atom const *name);
    109
    110  void clear() { my_buffer.clear();}
    111  bool empty() const { return my_buffer.empty();}
    112  size_t size() const { return my_buffer.size();}
    113  iterator begin() const { return my_buffer.begin();}
    114  iterator end() const { return my_buffer.end();}
    115  unsigned char front() const { return *begin();}
    116  unsigned char at(size_t i) const { return my_buffer.at(i);}
    117  //. return a copy of the underlaying buffer
    118  //. FIXME: this is a temporary workaround while there are
    119  //. still places that use raw strings
    120  const char *copy() const;
    121
    122  bool operator == (const Encoding &e) const { return my_buffer == e.my_buffer;}
    123  bool operator == (const std::string &s) const { return my_buffer == (const unsigned char *)s.c_str();}
    124  bool operator == (const char *s) const { return my_buffer == (const unsigned char *)s;}
    125
    126  void prepend(unsigned char c) { my_buffer.insert(my_buffer.begin(), c);}
    127  void prepend(const char *p, size_t s) { my_buffer.insert(0, (const unsigned char *)p, s);}
    128  void prepend(const Encoding &e) { my_buffer.insert(0, e.my_buffer);}
    129
    130  void append(unsigned char c) { my_buffer.append(1, c);}
    131  void append(const char *p, size_t s) { my_buffer.append((const unsigned char *)p, s);}
    132  void append(const Encoding &e) { my_buffer.append(e.my_buffer);}
    133  void append_with_length(const char *s, size_t n) { append(0x80 + n); append((const char *)s, n);}
    134  void append_with_length(const Encoding &e) { append(0x80 + e.size()); append(e);}
    135
    136  unsigned char pop();
    137  void pop(size_t n) { my_buffer.erase(my_buffer.begin(), my_buffer.begin() + n);}
    138
    139  void cv_qualify(const Node *, const Node * = 0);
    140  void simple_const() { append("Ci", 2);}
    141  void global_scope();
    142  void simple_name(const Node *);
    143  void anonymous();
    144  void template_(const Node *, const Encoding &);
    145  void qualified(int);
    146  void destructor(const Node *);
    147  void ptr_operator(int);
    148  void ptr_to_member(const Encoding &, int);
    149  void cast_operator(const Encoding &);
    150  void array() { prepend("A_", 2);}
    151  void array(unsigned long s);
    152  void function(const Encoding &e) { prepend(e);}
    153  void recursion(const Encoding &e) { prepend(e);}
    154  void start_func_args() { append('F');}
    155  void end_func_args() { append('_');}
    156  void void_() { append('v');}
    157  void ellipsis_arg() { append('e');}
    158  void no_return_type() { append('?');}
    159  void value_temp_param() { append('*');}
    160
    161  //. if this Encoding represents a qualified name,
    162  //. return the name of the outer scope
    163  Encoding get_scope() const;
    164  //. if this Encoding represents a qualified name,
    165  //. return the name of the symbol inside the outer scope,
    166  //. else return the unmodified name
    167  Encoding get_symbol() const;
    168  Encoding get_template_arguments() const;
    169
    170  std::string unmangled() const;
    171
    172  PTree::Node *make_name();
    173  PTree::Node *make_qname();
    174  PTree::Node *make_ptree(PTree::Node *);
    175  bool is_simple_name() const { return front() >= 0x80;}
    176  bool is_global_scope() const { return front() == 0x80 && size() == 1;}
    177  bool is_qualified() const { return front() == 'Q';}
    178  bool is_function() const;
    179  bool is_template() const { return front() == 'T';}
    180  PTree::Node *name_to_ptree();
    181
    182  friend bool operator < (const Encoding &, const Encoding &);
    183  friend std::ostream &operator << (std::ostream &, const Encoding &);
    184
    185private:
    186
    187  iterator end_of_scope() const;
    188
    189  Code my_buffer;
    190
    191public:
    192  static PTree::Node *bool_t, *char_t, *wchar_t_t, *int_t, *short_t, *long_t,
    193		 *float_t, *double_t, *void_t;
    194
    195  static PTree::Node *signed_t, *unsigned_t, *const_t, *volatile_t;
    196
    197  static PTree::Node *operator_name, *new_operator, *anew_operator,
    198		 *delete_operator, *adelete_operator;
    199
    200  static PTree::Node *star, *ampersand, *comma, *dots, *scope, *tilder,
    201		 *left_paren, *right_paren, *left_bracket, *right_bracket,
    202		 *left_angle, *right_angle;
    203};
    204
    205inline bool operator < (const Encoding &e1, const Encoding &e2)
    206{
    207  return e1.my_buffer < e2.my_buffer;
    208}
    209
    210inline std::ostream &operator << (std::ostream &os, const Encoding &e)
    211{
    212  for (Encoding::iterator i = e.begin();
    213       i != e.end();
    214       ++i)
    215    if(*i < 0x80) os.put(static_cast<char>(*i));
    216    else os << '[' << static_cast<int>(*i - 0x80) << ']';
    217  return os;
    218}
    219
    220inline unsigned char Encoding::pop()
    221{
    222  unsigned char code = my_buffer[0];
    223  my_buffer.erase(0, 1);
    224  return code;
    225}
    226
    227inline bool Encoding::is_function() const
    228{
    229  if (front() == 'F') return true;
    230  // const (member) function.
    231  else if (front() == 'C' && *(begin() + 1) == 'F') return true;
    232  else return false;
    233}
    234
    235}
    236}
    237
    238#endif

Generated on Thu Apr 16 16:28:02 2009 by
synopsis (version devel)