// 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 <exception>
#include <typeinfo>
#include <unwind.h>

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

  class __shim_type_info : public std::type_info
  {
   public:
    virtual ~__shim_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const = 0;
  };

  // Typeinfo for fundamental types.
  class __fundamental_type_info : public __shim_type_info
  {
  public:
    virtual ~__fundamental_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
  };

  // Typeinfo for array types.
  class __array_type_info : public __shim_type_info
  {
  public:
    virtual ~__array_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
  };

  // Typeinfo for function types.
  class __function_type_info : public __shim_type_info
  {
  public:
    virtual ~__function_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
  };

  // Typeinfo for enum types.
  class __enum_type_info : public __shim_type_info
  {
  public:
    virtual ~__enum_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
  };


  class __class_type_info;

  // Used in __vmi_class_type_info
  struct __base_class_type_info
  {
  public:
    const __class_type_info *__base_type;

    long __offset_flags;

    enum __offset_flags_masks {
      __virtual_mask = 0x1,
      __public_mask = 0x2,
      __offset_shift = 8   // lower 8 bits are flags
    };

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

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

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

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

  // Helper struct to support catch-clause match
  struct __UpcastInfo {
    enum ContainedStatus {
      unknown = 0,
      has_public_contained,
      has_ambig_or_not_public
    };

    ContainedStatus status;
    const __class_type_info* base_type;
    void* adjustedPtr;
    unsigned int premier_flags;
    bool nullobj_may_conflict;

    __UpcastInfo(const __class_type_info* type);
  };

  // Typeinfo for classes with no bases.
  class __class_type_info : public __shim_type_info
  {
  public:
    virtual ~__class_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;

    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; }

    virtual bool walk_to(const __class_type_info* base_type,
                         void*& adjustedPtr,
                         __UpcastInfo& info) const;

  protected:
    bool self_class_type_match(const __class_type_info* base_type,
                               void*& adjustedPtr,
                               __UpcastInfo& info) const;
  };

  // Typeinfo for classes containing only a single, public, non-virtual base at
  // offset zero.
  class __si_class_type_info : public __class_type_info
  {
  public:
    virtual ~__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; }

    virtual bool walk_to(const __class_type_info* base_type,
                         void*& adjustedPtr,
                         __UpcastInfo& info) const;
  };


  // 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:
    virtual ~__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; }

    virtual bool walk_to(const __class_type_info* base_type,
                         void*& adjustedPtr,
                         __UpcastInfo& info) const;
  };

  class __pbase_type_info : public __shim_type_info
  {
  public:
    virtual ~__pbase_type_info();
    virtual bool can_catch(const __shim_type_info* thrown_type,
                           void*& adjustedPtr) const;
    unsigned int __flags;
    const __shim_type_info* __pointee;

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


    virtual bool can_catch_typeinfo_wrapper(const __shim_type_info* thrown_type,
                                            void*& adjustedPtr,
                                            unsigned tracker) const;

  protected:
    enum __constness_tracker_status {
      first_time_init = 0x1,
      keep_constness = 0x2,
      after_gap = 0x4         // after one non-const qualified,
                              // we cannot face const again in future
    };

  private:
    bool can_catch_ptr(const __pbase_type_info *thrown_type,
                       void *&adjustedPtr,
                       unsigned tracker) const;

    // Return true if making decision done.
    virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
                                  void*& adjustedPtr,
                                  unsigned tracker,
                                  bool& result) const = 0;
  };

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

  private:
    virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
                                  void*& adjustedPtr,
                                  unsigned tracker,
                                  bool& result) const;
  };

  class __pointer_to_member_type_info : public __pbase_type_info
  {
  public:
    __class_type_info* __context;

    virtual ~__pointer_to_member_type_info();

  private:
    virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
                                  void*& adjustedPtr,
                                  unsigned tracker,
                                  bool& result) const;
  };


  extern "C" {

    // Compatible with GNU C++
    const uint64_t __gxx_exception_class = 0x474E5543432B2B00LL; // GNUCC++\0

    // TODO: Support dependent exception
    // TODO: Support C++0x exception propagation
    // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
    struct __cxa_exception {
      size_t referenceCount;

      std::type_info* exceptionType;
      void (*exceptionDestructor)(void*);
      std::unexpected_handler unexpectedHandler;
      std::terminate_handler terminateHandler;
      __cxa_exception* nextException;

      int handlerCount;
#ifdef __arm__
      /**
       * ARM EHABI requires the unwind library to keep track of exceptions
       * during cleanups.  These support nesting, so we need to keep a list of
       * them.
       */
      __cxa_exception* nextCleanup;
      int cleanupCount;
#endif
      int handlerSwitchValue;
      const uint8_t* actionRecord;
      const uint8_t* languageSpecificData;
      void* catchTemp;
      void* adjustedPtr;

      _Unwind_Exception unwindHeader; // must be last
    };

    struct __cxa_eh_globals {
      __cxa_exception* caughtExceptions;
      unsigned int uncaughtExceptions;
#ifdef __arm__
      __cxa_exception* cleanupExceptions;
#endif
    };

    struct __cxa_thread_info {
      std::unexpected_handler unexpectedHandler;
      std::terminate_handler terminateHandler;
      _Unwind_Exception* currentCleanup;

      __cxa_eh_globals globals;
    };

    __cxa_eh_globals* __cxa_get_globals();
    __cxa_eh_globals* __cxa_get_globals_fast();

    void* __cxa_allocate_exception(size_t thrown_size);
    void __cxa_free_exception(void* thrown_exception);

    void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*));
    void __cxa_rethrow();

    void* __cxa_begin_catch(void* exceptionObject);
    void __cxa_end_catch();

    bool __cxa_begin_cleanup(_Unwind_Exception*);
    void __cxa_end_cleanup();

    void __cxa_bad_cast();
    void __cxa_bad_typeid();

    void* __cxa_get_exception_ptr(void* exceptionObject);

    void __cxa_pure_virtual();

    // Missing libcxxabi functions.
    bool __cxa_uncaught_exception() throw();
    void __cxa_decrement_exception_refcount(void* exceptionObject) throw();
    void __cxa_increment_exception_refcount(void* exceptionObject) throw();
    void __cxa_rethrow_primary_exception(void* exceptionObject);
    void* __cxa_current_primary_exception() throw();

  } // extern "C"

} // namespace __cxxabiv1

namespace abi = __cxxabiv1;

#endif /* defined(__GABIXX_CXXABI_H__) */

