00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef MORE_LANG_CT_TYPE_H
00031 #define MORE_LANG_CT_TYPE_H
00032
00033 #include <more/bits/config.h>
00034
00035 #ifdef HAVE_LIBFFI
00036 # include <ffi.h>
00037
00038
00039 # define MORE_LANG_PROVIDE_FFI
00040
00041
00042
00043
00044
00045 #endif
00046
00047 #ifdef HAVE_BDWGC
00048 # define MORE_LANG_USE_GC
00049 # include <bdwgc/gc_cpp.h>
00050 # include <more/gen/memory.h>
00051 # include <more/gen/gc_string.h>
00052 #endif
00053
00054 #include <iosfwd>
00055 #include <cstdlib>
00056 #include <cstring>
00057 #include <more/lang/fwd.h>
00058 #include <more/io/fwd.h>
00059 #include <more/gen/string.h>
00060 #include <more/gen/identifier.h>
00061 #include <more/math/hash.h>
00062 #include <typeinfo>
00063
00064
00065 namespace more {
00066 namespace lang {
00067
00068 using std::size_t;
00069 #ifdef MORE_LANG_USE_GC
00070 using gen::gc_string;
00071 using gen::gc_wstring;
00072 #endif
00073 using gen::identifier;
00074
00075
00076 typedef void (*fn_ptr_t)();
00077
00078
00079
00080 struct ct_type
00081 #ifdef MORE_LANG_USE_GC
00082 : gc
00083 #endif
00084 {
00085 typedef std::size_t size_type;
00086 typedef short alignment_type;
00087 typedef math::hash<192> hash_type;
00088
00089 typedef unsigned short printopt_type;
00090 static printopt_type const printopt_low_precedence = 1;
00091 static printopt_type const printopt_space_before_name = 2;
00092 static printopt_type const printopt_space_after_name = 4;
00093 static printopt_type const printopt_function_args = 8;
00094 static printopt_type const printopt_lang_cxx = 16;
00095
00096
00097
00098
00099 ct_type();
00100
00101 #ifdef MORE_LANG_USE_FFI
00102
00103
00104
00105 ct_type(bool const_p, bool volatile_p);
00106 #else
00107 ct_type(size_type, alignment_type);
00108 ct_type(size_type, alignment_type, bool const_p, bool volatile_p);
00109 #endif
00110
00111 virtual ~ct_type();
00112
00113
00114 virtual ct_type* clone() const = 0;
00115
00116
00117 #ifdef MORE_LANG_PROVIDE_FFI
00118 virtual ffi_type* ffi_type_of() const = 0;
00119 #endif
00120 #if 0
00121 virtual void construct(void* p) const = 0;
00122 #endif
00123
00124 virtual void construct_copy(void* p, void* src) const = 0;
00125
00126
00127 virtual void destruct(void* p) const = 0;
00128
00129
00130 virtual bool equal(void* p0, void* p1) const = 0;
00131
00132
00133
00134 virtual void print_object(std::ostream&, void*) const;
00135
00136
00137
00138
00139 void print_declaration(std::ostream&, printopt_type,
00140 char const* var = 0) const;
00141
00142
00143
00144 virtual void print_declaration_pre(std::ostream&,
00145 printopt_type) const = 0;
00146
00147
00148 virtual void print_declaration_post(std::ostream&,
00149 printopt_type) const = 0;
00150 protected:
00151
00152
00153 void print_declaration_cv(std::ostream&,
00154 printopt_type) const;
00155 public:
00156 virtual void hash(hash_type&) const = 0;
00157 virtual bool equal_to(ct_type const*) const = 0;
00158
00159 bool is_const() const { return m_is_const; }
00160 bool is_volatile() const { return m_is_volatile; }
00161
00162
00163 friend ct_type const*
00164 to_cv(ct_type const* rtt, bool const_p, bool volatile_p);
00165
00166 virtual bool is_builtin() const;
00167 virtual bool is_number() const;
00168
00169
00170
00171
00172 virtual int digits() const;
00173 virtual int digits10() const;
00174 virtual bool is_integer() const;
00175 virtual bool is_exact() const;
00176 virtual int radix() const;
00177
00178
00179 virtual int min_exponent() const;
00180 virtual int min_exponent10() const;
00181 virtual int max_exponent() const;
00182 virtual int max_exponent10() const;
00183 virtual bool has_infinity() const;
00184 virtual bool has_quiet_NaN() const;
00185 virtual bool has_signaling_NaN() const;
00186 virtual std::float_denorm_style has_denorm() const;
00187 virtual bool has_denorm_loss() const;
00188
00189
00190
00191
00192 virtual bool is_iec559() const;
00193 virtual bool is_bounded() const;
00194 virtual bool is_modulo() const;
00195 virtual bool traps() const;
00196 virtual bool tinyness_before() const;
00197 virtual std::float_round_style round_style() const;
00198
00199 virtual ct_type const* promoted() const;
00200
00201 #if 0 // c_name
00202 identifier c_name() const { return m_c_name; }
00203 void set_c_name(char const* str) { m_c_name = str; }
00204 #endif
00205
00206 char const* c_error_value() const { return 0; }
00207
00208 #ifdef MORE_LANG_USE_FFI
00209 size_type size() const { return ffi_type_of()->size; }
00210 alignment_type alignment() const { return ffi_type_of()->alignment; }
00211 #else
00212 size_type size() const { req_fin(); return m_size; }
00213 alignment_type alignment() const { req_fin(); return m_alignment; }
00214 #endif
00215
00216 private:
00217 #ifndef MORE_LANG_USE_FFI
00218 void req_fin() const
00219 {
00220 if (m_size == size_type(-1))
00221 throw std::logic_error("more::lang::ct_type: "
00222 "Access of unfinished type description.");
00223 }
00224 protected:
00225 void set_size_and_alignment(size_type size, alignment_type alignment)
00226 {
00227 if (m_size != size_type(-1))
00228 throw std::logic_error("more::lang::ct_type: "
00229 "Tried to redefine size and alignment.");
00230 m_size = size;
00231 m_alignment = alignment;
00232 }
00233 private:
00234 size_type m_size;
00235 alignment_type m_alignment;
00236 #endif
00237
00238 unsigned int m_is_const : 1;
00239 unsigned int m_is_volatile : 1;
00240 ct_type** m_cv_array;
00241 protected:
00242 static char const* s_private_pfx;
00243 };
00244
00245
00246
00247 inline bool
00248 equal(ct_type const* t0, ct_type const* t1)
00249 {
00250 return t0->equal_to(t1);
00251 }
00252
00253
00254
00255 struct ct_pointer : ct_type
00256 {
00257 explicit ct_pointer(ct_type const* t);
00258 virtual ~ct_pointer();
00259 virtual ct_pointer* clone() const;
00260
00261 #ifdef MORE_LANG_PROVIDE_FFI
00262 virtual ffi_type* ffi_type_of() const;
00263 #endif
00264 virtual void construct_copy(void*, void*) const;
00265 virtual void destruct(void*) const;
00266 virtual bool equal(void*, void*) const;
00267 virtual void print_object(std::ostream&, void*) const;
00268 virtual void print_declaration_pre(std::ostream&,
00269 printopt_type) const;
00270 virtual void print_declaration_post(std::ostream&,
00271 printopt_type) const;
00272 virtual void hash(hash_type&) const;
00273 virtual bool equal_to(ct_type const*) const;
00274
00275 ct_type const* deref_type() const { return m_deref_type; }
00276 void* deref(void* p) { return *(void**)p; }
00277
00278 private:
00279 ct_type const* m_deref_type;
00280 };
00281
00282
00283
00284
00285 struct ct_array : ct_type
00286 {
00287 ct_array(ct_type const* t, std::size_t);
00288 virtual ~ct_array();
00289 virtual ct_array* clone() const;
00290
00291 #ifdef MORE_LANG_PROVIDE_FFI
00292 virtual ffi_type* ffi_type_of() const;
00293 #endif
00294 virtual void construct_copy(void*, void*) const;
00295 virtual void destruct(void*) const;
00296 virtual bool equal(void*, void*) const;
00297 virtual void print_object(std::ostream&, void*) const;
00298 virtual void print_declaration_pre(std::ostream&,
00299 printopt_type) const;
00300 virtual void print_declaration_post(std::ostream&,
00301 printopt_type) const;
00302 virtual void hash(hash_type&) const;
00303 virtual bool equal_to(ct_type const*) const;
00304
00305 ct_type const* element_type() const { return m_element_type; }
00306 void* element(void*, std::size_t) const;
00307
00308 private:
00309 ct_type const* m_element_type;
00310 size_t m_count;
00311 #ifdef MORE_LANG_PROVIDE_FFI
00312 mutable ffi_type m_ffi_type;
00313 #endif
00314 };
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 template<typename T>
00325 struct _ct_type
00326 {
00327 static ct_type const* get() { return s_value; }
00328 static void set(ct_type const* s) { s_value = s; }
00329 static ct_type const* s_value;
00330 };
00331 template<typename T>
00332 ct_type const* _ct_type<T>::s_value = 0;
00333
00334 template<typename T>
00335 struct _ct_type<T const>
00336 {
00337 static ct_type const*
00338 get()
00339 {
00340 static ct_type const* t = 0;
00341 if (!t)
00342 t = to_cv(_ct_type<T>::get(), true, false);
00343 return t;
00344 }
00345 };
00346
00347 template<typename T>
00348 struct _ct_type<T volatile>
00349 {
00350 static ct_type const*
00351 get()
00352 {
00353 static ct_type const* t = 0;
00354 if (!t)
00355 t = to_cv(_ct_type<T>::get(), false, true);
00356 return t;
00357 }
00358 };
00359
00360 template<typename T>
00361 struct _ct_type<T const volatile>
00362 {
00363 static ct_type const*
00364 get()
00365 {
00366 static ct_type const* t = 0;
00367 if (!t)
00368 t = to_cv(_ct_type<T>::get(), true, true);
00369 return t;
00370 }
00371 };
00372
00373 template<typename T>
00374 struct _ct_type<T*>
00375 {
00376 static ct_type const*
00377 get()
00378 {
00379 static ct_pointer* t = 0;
00380 if (!t) {
00381 #ifdef MORE_LANG_USE_GC
00382 t = new(UseGC) ct_pointer(_ct_type<T>::get());
00383 #else
00384 t = new ct_pointer(_ct_type<T>::get());
00385 #endif
00386 }
00387 return t;
00388 }
00389 };
00390
00391 template<typename T, std::size_t N>
00392 struct _ct_type<T[N]>
00393 {
00394 static ct_type const*
00395 get()
00396 {
00397 static ct_array* t = 0;
00398 if (!t) {
00399 #ifdef MORE_LANG_USE_GC
00400 t = new(UseGC) ct_array(_ct_type<T>::get(), N);
00401 #else
00402 t = new ct_array(_ct_type<T>::get(), N);
00403 #endif
00404 }
00405 return t;
00406 }
00407 };
00408
00409 template<typename T, std::size_t N>
00410 struct _ct_type<T const[N]>
00411 {
00412 static ct_type const*
00413 get()
00414 {
00415 static ct_type const* t = 0;
00416 if (!t)
00417 t = to_cv(_ct_type<T[N]>::get(), true, false);
00418 return t;
00419 }
00420 };
00421
00422 template<typename T, std::size_t N>
00423 struct _ct_type<T volatile[N]>
00424 {
00425 static ct_type const*
00426 get()
00427 {
00428 static ct_type const* t = 0;
00429 if (!t)
00430 t = to_cv(_ct_type<T[N]>::get(), false, true);
00431 return t;
00432 }
00433 };
00434
00435 template<typename T, std::size_t N>
00436 struct _ct_type<T const volatile[N]>
00437 {
00438 static ct_type const*
00439 get()
00440 {
00441 static ct_type const* t = 0;
00442 if (!t)
00443 t = to_cv(_ct_type<T[N]>::get(), true, true);
00444 return t;
00445 }
00446 };
00447
00448
00449 template<> struct _ct_type<void> { static ct_type* get(); };
00450
00451 template<> struct _ct_type<char> { static ct_type* get(); };
00452 template<> struct _ct_type<signed char> { static ct_type* get(); };
00453 template<> struct _ct_type<unsigned char> { static ct_type* get(); };
00454 template<> struct _ct_type<short> { static ct_type* get(); };
00455 template<> struct _ct_type<unsigned short> { static ct_type* get(); };
00456 template<> struct _ct_type<int> { static ct_type* get(); };
00457 template<> struct _ct_type<unsigned int> { static ct_type* get(); };
00458 template<> struct _ct_type<long> { static ct_type* get(); };
00459 template<> struct _ct_type<unsigned long> { static ct_type* get(); };
00460 #ifdef CXX_HAVE_LONG_LONG
00461 template<> struct _ct_type<long long> { static ct_type* get(); };
00462 template<> struct _ct_type<unsigned long long>{ static ct_type* get(); };
00463 #endif
00464 template<> struct _ct_type<float> { static ct_type* get(); };
00465 template<> struct _ct_type<double> { static ct_type* get(); };
00466 template<> struct _ct_type<long double> { static ct_type* get(); };
00467
00468 #ifdef MORE_LANG_USE_GC
00469 template<> struct _ct_type<gc_wstring> { static ct_type* get(); };
00470 template<> struct _ct_type<gc_string> { static ct_type* get(); };
00471 template<> struct _ct_type<identifier> { static ct_type* get(); };
00472 template<> struct _ct_type<io::sourceref> { static ct_type* get(); };
00473 #endif
00474
00475
00476
00477
00478
00479
00480 template<typename T>
00481 inline ct_type const*
00482 ct_type_of()
00483 {
00484 if (ct_type const* t = _ct_type<T>::get())
00485 return t;
00486 else
00487 throw std::logic_error("more::lang::ct_type_of<\""
00488 + std::string(typeid(T).name())
00489 + "\">: Type is not registered.");
00490 }
00491
00492
00493 template<typename T>
00494 inline ct_type const*
00495 ct_type_of(T x)
00496 {
00497 return _ct_type<T>::get();
00498 }
00499
00500
00501 template<typename T>
00502 inline void
00503 register_ct_type_of(ct_type const* t)
00504 {
00505 if (_ct_type<T>::get())
00506 throw std::logic_error("more::lang::register_ct_type_of: "
00507 "Multiple definitions of type "
00508 "description.");
00509 _ct_type<T>::set(t);
00510 }
00511
00512
00513
00514
00515 ct_type const* arithmetic_result_type(ct_type const* x, ct_type const* y);
00516
00517 }}
00518 #endif