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