197403Sobrien// Methods for type_info for -*- C++ -*- Run Time Type Identification.
297403Sobrien
3102782Skan// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002
497403Sobrien// Free Software Foundation
597403Sobrien//
6132720Skan// This file is part of GCC.
797403Sobrien//
8132720Skan// GCC is free software; you can redistribute it and/or modify
997403Sobrien// it under the terms of the GNU General Public License as published by
1097403Sobrien// the Free Software Foundation; either version 2, or (at your option)
1197403Sobrien// any later version.
1297403Sobrien
13132720Skan// GCC is distributed in the hope that it will be useful,
1497403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1597403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1697403Sobrien// GNU General Public License for more details.
1797403Sobrien
1897403Sobrien// You should have received a copy of the GNU General Public License
19132720Skan// along with GCC; see the file COPYING.  If not, write to
20169691Skan// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21169691Skan// Boston, MA 02110-1301, USA.
2297403Sobrien
2397403Sobrien// As a special exception, you may use this file as part of a free software
2497403Sobrien// library without restriction.  Specifically, if other files instantiate
2597403Sobrien// templates or use macros or inline functions from this file, or you compile
2697403Sobrien// this file and link it with other files to produce an executable, this
2797403Sobrien// file does not by itself cause the resulting executable to be covered by
2897403Sobrien// the GNU General Public License.  This exception does not however
2997403Sobrien// invalidate any other reasons why the executable file might be covered by
3097403Sobrien// the GNU General Public License.
3197403Sobrien
3297403Sobrien#include <cstddef>
3397403Sobrien#include "tinfo.h"
3497403Sobrien#include "new"			// for placement new
3597403Sobrien
3697403Sobrien// We can't rely on having stdlib.h if we're freestanding.
3797403Sobrienextern "C" void abort ();
3897403Sobrien
3997403Sobrienusing std::type_info;
4097403Sobrien
4197403Sobrien#if !__GXX_MERGED_TYPEINFO_NAMES
4297403Sobrien
4397403Sobrienbool
4497403Sobrientype_info::before (const type_info &arg) const
4597403Sobrien{
4697403Sobrien  return __builtin_strcmp (name (), arg.name ()) < 0;
4797403Sobrien}
4897403Sobrien
4997403Sobrien#endif
5097403Sobrien
5197403Sobrien#include <cxxabi.h>
5297403Sobrien
5397403Sobriennamespace __cxxabiv1 {
5497403Sobrien
5597403Sobrienusing namespace std;
5697403Sobrien
5797403Sobrien// This has special meaning to the compiler, and will cause it
5897403Sobrien// to emit the type_info structures for the fundamental types which are
5997403Sobrien// mandated to exist in the runtime.
6097403Sobrien__fundamental_type_info::
6197403Sobrien~__fundamental_type_info ()
6297403Sobrien{}
6397403Sobrien
6497403Sobrien__array_type_info::
6597403Sobrien~__array_type_info ()
6697403Sobrien{}
6797403Sobrien
6897403Sobrien__function_type_info::
6997403Sobrien~__function_type_info ()
7097403Sobrien{}
7197403Sobrien
7297403Sobrien__enum_type_info::
7397403Sobrien~__enum_type_info ()
7497403Sobrien{}
7597403Sobrien
7697403Sobrien__pbase_type_info::
7797403Sobrien~__pbase_type_info ()
7897403Sobrien{}
7997403Sobrien
8097403Sobrien__pointer_type_info::
8197403Sobrien~__pointer_type_info ()
8297403Sobrien{}
8397403Sobrien
8497403Sobrien__pointer_to_member_type_info::
8597403Sobrien~__pointer_to_member_type_info ()
8697403Sobrien{}
8797403Sobrien
8897403Sobrienbool __pointer_type_info::
8997403Sobrien__is_pointer_p () const
9097403Sobrien{
9197403Sobrien  return true;
9297403Sobrien}
9397403Sobrien
9497403Sobrienbool __function_type_info::
9597403Sobrien__is_function_p () const
9697403Sobrien{
9797403Sobrien  return true;
9897403Sobrien}
9997403Sobrien
10097403Sobrienbool __pbase_type_info::
10197403Sobrien__do_catch (const type_info *thr_type,
10297403Sobrien            void **thr_obj,
10397403Sobrien            unsigned outer) const
10497403Sobrien{
10597403Sobrien  if (*this == *thr_type)
10697403Sobrien    return true;      // same type
10797403Sobrien  if (typeid (*this) != typeid (*thr_type))
10897403Sobrien    return false;     // not both same kind of pointers
10997403Sobrien
11097403Sobrien  if (!(outer & 1))
11197403Sobrien    // We're not the same and our outer pointers are not all const qualified
11297403Sobrien    // Therefore there must at least be a qualification conversion involved
11397403Sobrien    // But for that to be valid, our outer pointers must be const qualified.
11497403Sobrien    return false;
11597403Sobrien
11697403Sobrien  const __pbase_type_info *thrown_type =
11797403Sobrien    static_cast <const __pbase_type_info *> (thr_type);
11897403Sobrien
119102782Skan  if (thrown_type->__flags & ~__flags)
12097403Sobrien    // We're less qualified.
12197403Sobrien    return false;
12297403Sobrien
123102782Skan  if (!(__flags & __const_mask))
12497403Sobrien    outer &= ~1;
12597403Sobrien
12697403Sobrien  return __pointer_catch (thrown_type, thr_obj, outer);
12797403Sobrien}
12897403Sobrien
12997403Sobrieninline bool __pbase_type_info::
13097403Sobrien__pointer_catch (const __pbase_type_info *thrown_type,
13197403Sobrien                 void **thr_obj,
13297403Sobrien                 unsigned outer) const
13397403Sobrien{
13497403Sobrien  return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2);
13597403Sobrien}
13697403Sobrien
13797403Sobrienbool __pointer_type_info::
13897403Sobrien__pointer_catch (const __pbase_type_info *thrown_type,
13997403Sobrien                 void **thr_obj,
14097403Sobrien                 unsigned outer) const
14197403Sobrien{
14297403Sobrien  if (outer < 2 && *__pointee == typeid (void))
14397403Sobrien    {
14497403Sobrien      // conversion to void
14597403Sobrien      return !thrown_type->__pointee->__is_function_p ();
14697403Sobrien    }
14797403Sobrien
14897403Sobrien  return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer);
14997403Sobrien}
15097403Sobrien
15197403Sobrienbool __pointer_to_member_type_info::
15297403Sobrien__pointer_catch (const __pbase_type_info *thr_type,
15397403Sobrien                 void **thr_obj,
15497403Sobrien                 unsigned outer) const
15597403Sobrien{
15697403Sobrien  // This static cast is always valid, as our caller will have determined that
15797403Sobrien  // thr_type is really a __pointer_to_member_type_info.
15897403Sobrien  const __pointer_to_member_type_info *thrown_type =
15997403Sobrien    static_cast <const __pointer_to_member_type_info *> (thr_type);
16097403Sobrien
161102782Skan  if (*__context != *thrown_type->__context)
16297403Sobrien    return false;     // not pointers to member of same class
16397403Sobrien
16497403Sobrien  return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer);
16597403Sobrien}
16697403Sobrien
16797403Sobrien} // namespace std
168