198944Sobrien// Methods for type_info for -*- C++ -*- Run Time Type Identification.
298944Sobrien
3130803Smarcel// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002
4130803Smarcel// Free Software Foundation
598944Sobrien//
698944Sobrien// This file is part of GCC.
798944Sobrien//
898944Sobrien// GCC is free software; you can redistribute it and/or modify
998944Sobrien// it under the terms of the GNU General Public License as published by
1098944Sobrien// the Free Software Foundation; either version 2, or (at your option)
1198944Sobrien// any later version.
1298944Sobrien
1398944Sobrien// GCC is distributed in the hope that it will be useful,
1498944Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1598944Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698944Sobrien// GNU General Public License for more details.
1798944Sobrien
1898944Sobrien// You should have received a copy of the GNU General Public License
1998944Sobrien// along with GCC; see the file COPYING.  If not, write to
2098944Sobrien// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
2198944Sobrien// Boston, MA 02110-1301, USA.
2298944Sobrien
2398944Sobrien// As a special exception, you may use this file as part of a free software
2498944Sobrien// library without restriction.  Specifically, if other files instantiate
2598944Sobrien// templates or use macros or inline functions from this file, or you compile
2698944Sobrien// this file and link it with other files to produce an executable, this
2798944Sobrien// file does not by itself cause the resulting executable to be covered by
2898944Sobrien// the GNU General Public License.  This exception does not however
2998944Sobrien// invalidate any other reasons why the executable file might be covered by
3098944Sobrien// the GNU General Public License.
3198944Sobrien
3298944Sobrien#include <cstddef>
3398944Sobrien#include "tinfo.h"
3498944Sobrien#include "new"			// for placement new
3598944Sobrien
3698944Sobrien// We can't rely on having stdlib.h if we're freestanding.
3798944Sobrienextern "C" void abort ();
3898944Sobrien
3998944Sobrienusing std::type_info;
4098944Sobrien
4198944Sobrien#if !__GXX_MERGED_TYPEINFO_NAMES
4298944Sobrien
4398944Sobrienbool
4498944Sobrientype_info::before (const type_info &arg) const
4598944Sobrien{
4698944Sobrien  return __builtin_strcmp (name (), arg.name ()) < 0;
4798944Sobrien}
4898944Sobrien
4998944Sobrien#endif
5098944Sobrien
5198944Sobrien#include <cxxabi.h>
5298944Sobrien
5398944Sobriennamespace __cxxabiv1 {
5498944Sobrien
5598944Sobrienusing namespace std;
5698944Sobrien
5798944Sobrien// This has special meaning to the compiler, and will cause it
5898944Sobrien// to emit the type_info structures for the fundamental types which are
5998944Sobrien// mandated to exist in the runtime.
6098944Sobrien__fundamental_type_info::
6198944Sobrien~__fundamental_type_info ()
6298944Sobrien{}
6398944Sobrien
6498944Sobrien__array_type_info::
6598944Sobrien~__array_type_info ()
6698944Sobrien{}
6798944Sobrien
6898944Sobrien__function_type_info::
6998944Sobrien~__function_type_info ()
7098944Sobrien{}
7198944Sobrien
7298944Sobrien__enum_type_info::
7398944Sobrien~__enum_type_info ()
7498944Sobrien{}
7598944Sobrien
7698944Sobrien__pbase_type_info::
7798944Sobrien~__pbase_type_info ()
7898944Sobrien{}
7998944Sobrien
8098944Sobrien__pointer_type_info::
8198944Sobrien~__pointer_type_info ()
8298944Sobrien{}
8398944Sobrien
8498944Sobrien__pointer_to_member_type_info::
8598944Sobrien~__pointer_to_member_type_info ()
8698944Sobrien{}
8798944Sobrien
8898944Sobrienbool __pointer_type_info::
8998944Sobrien__is_pointer_p () const
9098944Sobrien{
9198944Sobrien  return true;
9298944Sobrien}
9398944Sobrien
9498944Sobrienbool __function_type_info::
9598944Sobrien__is_function_p () const
9698944Sobrien{
9798944Sobrien  return true;
9898944Sobrien}
9998944Sobrien
10098944Sobrienbool __pbase_type_info::
10198944Sobrien__do_catch (const type_info *thr_type,
10298944Sobrien            void **thr_obj,
10398944Sobrien            unsigned outer) const
10498944Sobrien{
10598944Sobrien  if (*this == *thr_type)
10698944Sobrien    return true;      // same type
10798944Sobrien  if (typeid (*this) != typeid (*thr_type))
10898944Sobrien    return false;     // not both same kind of pointers
10998944Sobrien
11098944Sobrien  if (!(outer & 1))
11198944Sobrien    // We're not the same and our outer pointers are not all const qualified
11298944Sobrien    // Therefore there must at least be a qualification conversion involved
11398944Sobrien    // But for that to be valid, our outer pointers must be const qualified.
11498944Sobrien    return false;
11598944Sobrien
11698944Sobrien  const __pbase_type_info *thrown_type =
11798944Sobrien    static_cast <const __pbase_type_info *> (thr_type);
11898944Sobrien
11998944Sobrien  if (thrown_type->__flags & ~__flags)
12098944Sobrien    // We're less qualified.
12198944Sobrien    return false;
122130803Smarcel
123130803Smarcel  if (!(__flags & __const_mask))
124130803Smarcel    outer &= ~1;
125130803Smarcel
126130803Smarcel  return __pointer_catch (thrown_type, thr_obj, outer);
127130803Smarcel}
128130803Smarcel
129130803Smarcelinline bool __pbase_type_info::
130130803Smarcel__pointer_catch (const __pbase_type_info *thrown_type,
131130803Smarcel                 void **thr_obj,
132130803Smarcel                 unsigned outer) const
133130803Smarcel{
134130803Smarcel  return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2);
135130803Smarcel}
136130803Smarcel
137130803Smarcelbool __pointer_type_info::
138130803Smarcel__pointer_catch (const __pbase_type_info *thrown_type,
139130803Smarcel                 void **thr_obj,
140130803Smarcel                 unsigned outer) const
141130803Smarcel{
142130803Smarcel  if (outer < 2 && *__pointee == typeid (void))
143130803Smarcel    {
144130803Smarcel      // conversion to void
145130803Smarcel      return !thrown_type->__pointee->__is_function_p ();
146130803Smarcel    }
147130803Smarcel
148130803Smarcel  return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer);
149130803Smarcel}
150130803Smarcel
151130803Smarcelbool __pointer_to_member_type_info::
15298944Sobrien__pointer_catch (const __pbase_type_info *thr_type,
15398944Sobrien                 void **thr_obj,
15498944Sobrien                 unsigned outer) const
15598944Sobrien{
15698944Sobrien  // This static cast is always valid, as our caller will have determined that
15798944Sobrien  // thr_type is really a __pointer_to_member_type_info.
15898944Sobrien  const __pointer_to_member_type_info *thrown_type =
15998944Sobrien    static_cast <const __pointer_to_member_type_info *> (thr_type);
16098944Sobrien
16198944Sobrien  if (*__context != *thrown_type->__context)
16298944Sobrien    return false;     // not pointers to member of same class
16398944Sobrien
16498944Sobrien  return __pbase_type_info::__pointer_catch (thrown_type, thr_obj, outer);
16598944Sobrien}
16698944Sobrien
167130803Smarcel} // namespace std
168130803Smarcel