// Copyright (C) 2011 The Android Open Source Project
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//

#ifndef __GABIXX_CXXABI_H__
#define __GABIXX_CXXABI_H__

#include <typeinfo>

namespace abi = __cxxabiv1;

namespace __cxxabiv1
{
  extern "C" void __cxa_pure_virtual();

  // Derived types of type_info below are based on 2.9.5 of C++ ABI.

  // Typeinfo for fundamental types.
  class __fundamental_type_info : public std::type_info
  {
  public:
    ~__fundamental_type_info();
  };

  // Typeinfo for array types.
  class __array_type_info : public std::type_info
  {
  public:
    ~__array_type_info();
  };

  // Typeinfo for function types.
  class __function_type_info : public std::type_info
  {
  public:
    ~__function_type_info();
  };

  // Typeinfo for enum types.
  class __enum_type_info : public std::type_info
  {
  public:
    ~__enum_type_info();
  };

  // Typeinfo for classes with no bases.
  class __class_type_info : public std::type_info
  {
  public:
    ~__class_type_info();

    enum class_type_info_code
      {
        CLASS_TYPE_INFO_CODE,
        SI_CLASS_TYPE_INFO_CODE,
        VMI_CLASS_TYPE_INFO_CODE
      };

    virtual class_type_info_code
    code() const { return CLASS_TYPE_INFO_CODE; }
  };

  // Typeinfo for classes containing only a single, public, non-virtual base at
  // offset zero.
  class __si_class_type_info : public __class_type_info
  {
  public:
    ~__si_class_type_info();
    const __class_type_info *__base_type;

    virtual __class_type_info::class_type_info_code
    code() const { return SI_CLASS_TYPE_INFO_CODE; }
  };

  struct __base_class_type_info
  {
  public:
    const __class_type_info *__base_type;

    // All but the lower __offset_shift bits of __offset_flags are a signed
    // offset. For a non-virtual base, this is the offset in the object of the
    // base subobject. For a virtual base, this is the offset in the virtual
    // table of the virtual base offset for the virtual base referenced
    // (negative).
    long __offset_flags;

    enum __offset_flags_masks
      {
        __virtual_mask = 0x1,
        __public_mask = 0x2,
        __offset_shift = 8
      };

    bool inline
    is_virtual() const { return (__offset_flags & __virtual_mask) != 0; }

    bool inline
    is_public() const { return (__offset_flags & __public_mask) != 0; }

    // FIXME: Right-shift of signed integer is implementation dependent.
    long inline
    offset() const { return __offset_flags >> __offset_shift; }

    long inline
    flags() const { return __offset_flags & ((1L << __offset_shift) - 1); }
  };

  // Typeinfo for classes with bases that do not satisfy the
  // __si_class_type_info constraints.
  class __vmi_class_type_info : public __class_type_info
  {
  public:
    ~__vmi_class_type_info();
    unsigned int __flags;
    unsigned int __base_count;
    __base_class_type_info __base_info[1];

    enum __flags_masks
      {
        __non_diamond_repeat_mask = 0x1,
        __diamond_shaped_mask = 0x2
      };

    virtual __class_type_info::class_type_info_code
    code() const { return VMI_CLASS_TYPE_INFO_CODE; }
  };

  class __pbase_type_info : public std::type_info
  {
  public:
    ~__pbase_type_info();
    unsigned int __flags;
    const std::type_info *__pointee;

    enum __masks
      {
        __const_mask = 0x1,
        __volatile_mask = 0x2,
        __restrict_mask = 0x4,
        __incomplete_mask = 0x8,
        __incomplete_class_mask = 0x10
      };
  };

  class __pointer_type_info : public __pbase_type_info
  {
  public:
    ~__pointer_type_info();
  };

  class __pointer_to_member_type_info : public __pbase_type_info
  {
  public:
    ~__pointer_to_member_type_info();
  };
}

#endif /* defined(__GABIXX_CXXABI_H__) */

