diff options
author | YamaArashi <shadow962@live.com> | 2016-01-06 01:47:28 -0800 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2016-01-06 01:47:28 -0800 |
commit | be8b04496302184c6e8f04d6179f9c3afc50aeb6 (patch) | |
tree | 726e2468c0c07add773c0dbd86ab6386844259ae /gcc/cp/tinfo2.cc |
initial commit
Diffstat (limited to 'gcc/cp/tinfo2.cc')
-rwxr-xr-x | gcc/cp/tinfo2.cc | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/gcc/cp/tinfo2.cc b/gcc/cp/tinfo2.cc new file mode 100755 index 0000000..3de6a14 --- /dev/null +++ b/gcc/cp/tinfo2.cc @@ -0,0 +1,306 @@ +// Methods for type_info for -*- C++ -*- Run Time Type Identification. +// Copyright (C) 1994, 96-97, 1998 Free Software Foundation + +// This file is part of GNU CC. + +// GNU CC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. + +// GNU CC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with GNU CC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with other files, +// some of which are compiled with GCC, to produce an executable, +// this library does not by itself cause the resulting executable +// to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +/* CYGNUS LOCAL embedded c++ */ +#ifndef __EMBEDDED_CXX__ +/* END CYGNUS LOCAL */ +#include <stddef.h> +#include "tinfo.h" +#include "new" // for placement new + +using std::type_info; + +bool +type_info::before (const type_info &arg) const +{ + return strcmp (name (), arg.name ()) < 0; +} + +// type info for pointer type. + +struct __pointer_type_info : public type_info { + const type_info& type; + + __pointer_type_info (const char *n, const type_info& ti) + : type_info (n), type (ti) {} +}; + +// type info for attributes + +struct __attr_type_info : public type_info { + enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 }; + + const type_info& type; + cv attr; + + __attr_type_info (const char *n, cv a, const type_info& t) + : type_info (n), type (t), attr (a) {} +}; + +// type_info for builtin type + +struct __builtin_type_info : public type_info { + __builtin_type_info (const char *n): type_info (n) {} +}; + +// type info for function. + +struct __func_type_info : public type_info { + __func_type_info (const char *n) : type_info (n) {} +}; + +// type info for pointer to member function. + +struct __ptmf_type_info : public type_info { + __ptmf_type_info (const char *n) : type_info (n) {} +}; + +// type info for pointer to data member. + +struct __ptmd_type_info : public type_info { + __ptmd_type_info (const char *n): type_info (n) {} +}; + +// type info for array. + +struct __array_type_info : public type_info { + __array_type_info (const char *n): type_info (n) {} +}; + +// Entry points for the compiler. + +/* Low level match routine used by compiler to match types of catch + variables and thrown objects. */ + +extern "C" void* +__throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r, + void *objptr) +{ + const type_info &catch_type = *(const type_info *)catch_type_r; + const type_info &throw_type = *(const type_info *)throw_type_r; + + if (catch_type == throw_type) + return objptr; + +#if 0 + printf ("We want to match a %s against a %s!\n", + throw_type.name (), catch_type.name ()); +#endif + + void *new_objptr = 0; + + if (const __user_type_info *p + = dynamic_cast <const __user_type_info *> (&throw_type)) + { + /* The 1 skips conversions to private bases. */ + new_objptr = p->dcast (catch_type, 1, objptr); + } + else if (const __pointer_type_info *fr = + dynamic_cast <const __pointer_type_info *> (&throw_type)) + { + const __pointer_type_info *to = + dynamic_cast <const __pointer_type_info *> (&catch_type); + + if (! to) + goto fail; + + const type_info *subfr = &fr->type, *subto = &to->type; + __attr_type_info::cv cvfrom, cvto; + + if (const __attr_type_info *at + = dynamic_cast <const __attr_type_info *> (subfr)) + { + cvfrom = at->attr; + subfr = &at->type; + } + else + cvfrom = __attr_type_info::NONE; + + if (const __attr_type_info *at + = dynamic_cast <const __attr_type_info *> (subto)) + { + cvto = at->attr; + subto = &at->type; + } + else + cvto = __attr_type_info::NONE; + + if (((cvfrom & __attr_type_info::CONST) + > (cvto & __attr_type_info::CONST)) + || ((cvfrom & __attr_type_info::VOLATILE) + > (cvto & __attr_type_info::VOLATILE))) + goto fail; + + if (*subto == *subfr) + new_objptr = objptr; + else if (*subto == typeid (void) + && dynamic_cast <const __func_type_info *> (subfr) == 0) + new_objptr = objptr; + else if (const __user_type_info *p + = dynamic_cast <const __user_type_info *> (subfr)) + { + /* The 1 skips conversions to private bases. */ + new_objptr = p->dcast (*subto, 1, objptr); + } + else if (const __pointer_type_info *pfr + = dynamic_cast <const __pointer_type_info *> (subfr)) + { + // Multi-level pointer conversion. + + const __pointer_type_info *pto + = dynamic_cast <const __pointer_type_info *> (subto); + + if (! pto) + goto fail; + + bool constp = (cvto & __attr_type_info::CONST); + for (subto = &pto->type, subfr = &pfr->type; ; + subto = &pto->type, subfr = &pfr->type) + { + if (const __attr_type_info *at + = dynamic_cast <const __attr_type_info *> (subfr)) + { + cvfrom = at->attr; + subfr = &at->type; + } + else + cvfrom = __attr_type_info::NONE; + + if (const __attr_type_info *at + = dynamic_cast <const __attr_type_info *> (subto)) + { + cvto = at->attr; + subto = &at->type; + } + else + cvto = __attr_type_info::NONE; + + if (((cvfrom & __attr_type_info::CONST) + > (cvto & __attr_type_info::CONST)) + || ((cvfrom & __attr_type_info::VOLATILE) + > (cvto & __attr_type_info::VOLATILE))) + goto fail; + + if (! constp + && (((cvfrom & __attr_type_info::CONST) + < (cvto & __attr_type_info::CONST)) + || ((cvfrom & __attr_type_info::VOLATILE) + < (cvto & __attr_type_info::VOLATILE)))) + goto fail; + + if (*subto == *subfr) + { + new_objptr = objptr; + break; + } + + pto = dynamic_cast <const __pointer_type_info *> (subto); + pfr = dynamic_cast <const __pointer_type_info *> (subfr); + if (! pto || ! pfr) + goto fail; + + if (! (cvto & __attr_type_info::CONST)) + constp = false; + } + } + } + fail: + +#if 0 + if (new_objptr) + printf ("It converts, delta is %d\n", new_objptr-objptr); +#endif + return new_objptr; +} + +/* Called from __cp_pop_exception. Is P the type_info node for a pointer + of some kind? */ + +bool +__is_pointer (void *p) +{ + const type_info *t = reinterpret_cast <const type_info *>(p); + const __pointer_type_info *pt = + dynamic_cast <const __pointer_type_info *> (t); + return pt != 0; +} + +extern "C" void +__rtti_ptr (void *addr, const char *n, const type_info *ti) +{ new (addr) __pointer_type_info (n, *ti); } + +extern "C" void +__rtti_attr (void *addr, const char *n, int attrval, const type_info *ti) +{ + new (addr) __attr_type_info + (n, static_cast <__attr_type_info::cv> (attrval), *ti); +} + +extern "C" void +__rtti_func (void *addr, const char *name) +{ new (addr) __func_type_info (name); } + +extern "C" void +__rtti_ptmf (void *addr, const char *name) +{ new (addr) __ptmf_type_info (name); } + +extern "C" void +__rtti_ptmd (void *addr, const char *name) +{ new (addr) __ptmd_type_info (name); } + +extern "C" void +__rtti_array (void *addr, const char *name) +{ new (addr) __array_type_info (name); } + +extern "C" void * +__dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void), + int require_public, void *address, + const type_info & (*sub)(void), void *subptr) +{ + return static_cast <const __user_type_info &> (from ()).dcast + (to (), require_public, address, &(sub ()), subptr); +} + +// type_info nodes and functions for the builtin types. The mangling here +// must match the mangling in gcc/cp/rtti.c. + +#define BUILTIN(mangled) \ +unsigned char __ti##mangled [sizeof (__builtin_type_info)] \ + __attribute__ ((aligned (__alignof__ (void *)))); \ +extern "C" const type_info &__tf##mangled (void) { \ + if ((*(void **) __ti##mangled) == 0) \ + new (__ti##mangled) __builtin_type_info (#mangled); \ + return *(type_info *)__ti##mangled; \ +} + +BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b); +BUILTIN (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f); +BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc); +BUILTIN (Sc); +/* CYGNUS LOCAL embedded C++ */ +#endif +/* END CYGNUS LOCAL */ |