home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / modhead1.zip / TYPEINFO.H < prev   
C/C++ Source or Header  |  1995-09-17  |  22KB  |  561 lines

  1. /*********************************************************************
  2. (C) Copyright 1994;       MetaWare Incorporated;  Santa Cruz, CA 95060
  3. This program is the unpublished property and trade secret of MetaWare.
  4. It is to be  utilized  solely  under  license  from  MetaWare  and  it
  5. is to be maintained on a confidential basis for internal  company  use
  6. only.  The  security  and  protection  of  the program is paramount to
  7. maintenance of the trade secret status.  It is to  be  protected  from
  8. disclosure  to    unauthorized parties, both within the Licensee company
  9. and outside, in a manner not less stringent than that utilized for Li-
  10. censee's own proprietary  internal  information.   No  copies  of  the
  11. source or Object Code are to leave the premises of Licensee's business
  12. except    in  strict accordance with the license agreement signed by Li-
  13. censee with MetaWare.
  14. *********************************************************************/
  15.  
  16. #ifndef _TYPEINFO_H
  17. #define _TYPEINFO_H
  18.  
  19. #if __TYPEINFO_IMPLEMENTATION
  20. #if __SOM_ENABLED__
  21. #include "som.ch"
  22. // IBM's somcorba.h defines true and false!
  23. #undef TRUE
  24. #undef FALSE
  25. #else
  26. class SOMClass{}; class SOMObject{}; typedef char boolean;
  27. #endif
  28. #define SOMClass SOMClass
  29. #endif
  30.  
  31. #if !defined(_CRTIMPCC)
  32.     #if _MSNT && _DLL && !_DLLBUILD
  33.     #define _CRTIMPCC __declspec(dllimport)
  34.     #else
  35.     #define _CRTIMPCC
  36.     #endif
  37. #endif
  38.  
  39. #pragma off(macro_substitution)
  40.  
  41. namespace typeinfo {
  42.  
  43. pragma on(run_time_type_info);
  44.  
  45. struct Force_vtab_at_0 {
  46.     virtual ~Force_vtab_at_0();// = 0;
  47.     };
  48.  
  49. // We used to figure out which kind a type was by doing address comparisons
  50. // but this failed across DLLs, because each DLL had a separate copy of
  51. // the fundamental types below.  So, we had to resort to storing the
  52. // kind in the type.
  53. short enum type_kind {     // short: MAKE SURE this is one byte always.
  54.     t_null,             // Not a type.
  55.     t_basic,            // basic type: integer or pointer.
  56.     t_pointer,          // pointer type
  57.     t_array,            // an array
  58.     t_class,            // a class/struct type
  59.     t_member_pointer,   // a pointer-to-member
  60.     t_func,             // a function type
  61.     t_modified,         // a const/volatile-modified type
  62.     t_SOM_class         // a SOM class/struct type
  63.     };
  64.  
  65. class Type_info : Force_vtab_at_0 {
  66.   private:
  67.     Type_info& operator= (const Type_info&);    // Permit no assignment.
  68.     char version;        // Version of the typeid structure.
  69.     unsigned char _fnhash;      // Hash of full name.  Check hash before doing strcmp.
  70.     type_kind tk;           // Which kind of type is this?
  71.     char pad1;            // Padding.
  72.     const char *_name;        // Likeable type name, such as int *.
  73.     const char *_full_name;    // Mangling, including full nesting.
  74.     long _size;            // Type size.  (For SOM, this is dynamic.)
  75.   protected:
  76.     Type_info(const Type_info&);
  77.     Type_info();
  78.   public:
  79.     virtual ~Type_info();
  80.     virtual int operator ==(const Type_info&) const;
  81.     virtual int operator !=(const Type_info&) const;
  82.     virtual int before(const Type_info&) const;
  83.     virtual const char* name() const;   // Simple name.
  84.     virtual const char* full_name() const;    // Full name: w/mangling.
  85.     virtual long size() const;    // Size of an object of this type.
  86.     };
  87.  
  88. // Modified types:
  89. class Modified_type_info: public Type_info {
  90.   private:
  91.     // Type flags from the compiler.  tf_CONST and tf_VOLATILE bits go here.
  92.     long _type_flags;    // Compiler type flags.
  93.     const Type_info *_modified_type;
  94.   public:
  95.     enum {tf_CONST = 1, tf_VOLATILE = 2};
  96.     ~Modified_type_info();
  97.     virtual long type_flags() const;
  98.     virtual const Type_info *modified_type() const;
  99.     };    
  100.  
  101. // Pointer types:
  102. class Pointer_type_info: public Type_info {
  103.   private:
  104.     const Type_info *_base_type; // Pointer to base type's type info.
  105.     char _pointer_is_ref;    // Whether this pointer is a reference type.
  106.   public:
  107.     ~Pointer_type_info();
  108.     virtual const Type_info *base_type() const;
  109.     virtual char pointer_is_ref() const;
  110.     };
  111.  
  112. // Pointer-to-member types:
  113. class Member_pointer_type_info: public Type_info {
  114.   private:
  115.     const Type_info *_base_type; // Pointer to base type's type info.
  116.     const Type_info *_of_class;    // Class members to which we may point.
  117.   public:
  118.     ~Member_pointer_type_info();
  119.     virtual const Type_info *base_type() const;
  120.     virtual const Type_info *of_class() const;
  121.     };
  122.  
  123. // Array types:
  124. class Array_type_info: public Type_info {
  125.   private:
  126.     const Type_info *_element_type;    // Element type.
  127.     unsigned long _element_count;      // # of elements.
  128.   public:
  129.     ~Array_type_info();
  130.     virtual const Type_info *element_type() const;
  131.     virtual unsigned long element_count() const;
  132.     };
  133.  
  134. // Function types:
  135. class Func_type_info: public Type_info {
  136.   private:
  137.     const Type_info *_return_type;
  138.     const char *_signature;    // Contains everything you wanted to know about
  139.                 // the type, except return type
  140.                 // (with cfront-based mangling schemes).
  141.   public:                
  142.     ~Func_type_info();
  143.     virtual const Type_info *return_type() const;
  144.     virtual const char *signature() const;
  145.     };
  146.  
  147. typedef short enum {        // short: MAKE SURE this is one byte always.
  148.     A_NULL, A_PRIVATE, A_PROTECTED, A_PUBLIC, A_IDENTITY,
  149.     } Access;
  150.  
  151. // Class types:
  152. class Class_type_info;
  153.  
  154. // Abundant class information is given only for native C++ classes.
  155. // SOM classes simply refer to the class object.
  156.  
  157. // pragma off(run_time_type_info);    // Don't want it for Base_info/Vbase_info/Member_info.
  158. struct Base_info {
  159.   private:
  160.     const Class_type_info *_base;    // We know bases are of Class_type.
  161.     Access _access;               // Access of base.
  162.     char _is_virtual;        // Is this base virtual?
  163.     char pad1,pad2;
  164.     long _offset;        // Offset to this base or to its virtual ptr.
  165.   public:
  166.     // These functions can't be virtual because it would change
  167.     // the size of Base_info and break binary compatibility.
  168.     // Same goes for Vbase_info and Member_info.
  169.     const Class_type_info *base() const;
  170.     Access access() const;
  171.     char is_virtual() const;
  172.     long offset() const;
  173.     };
  174.  
  175. struct Vbase_info {
  176.   private:
  177.     const Class_type_info *_base;    // We know bases are of Class_type.
  178.     char _has_ctd;        // Does this vbase have a ctor displacement?
  179.     char pad1,pad2,pad3;
  180.     long _offset;        // Offset to this base or to its virtual ptr.
  181.   public:
  182.     const Class_type_info *base() const;
  183.     //!EH RT needs has_ctd; but do I want others to know?
  184.     char has_ctd() const;
  185.     long offset() const;
  186.     };
  187.  
  188. // Members of class type; only these are relevant to exception handling.
  189. struct Member_info {
  190.   private:
  191.     const Type_info *_member;    // Could be array or array of classes.
  192.     long _offset;        // Offset of this member in the structure.
  193.     char _is_som;        // This is currently unused.
  194.     char pad1,pad2,pad3;    
  195.   public:
  196.     const Type_info *member() const;
  197.     long offset() const;
  198.     };
  199.  
  200. // pragma pop(run_time_type_info);    // Don't want it for Base_info/Vbase_info/Member_info.
  201. class Class_type_info: public Type_info {
  202.   public:
  203.     typedef void (*dtor_type)(void *object,int,int);    // Third parm needed for SOM.
  204.     typedef void (*ctor_type)(...);    // Constructor type.  Actual form private.
  205.     // When we call operator delete we always pass the size, whether
  206.     // or not it needs it.
  207.     typedef void (*delete_type)(void *, unsigned size);
  208.   private:
  209.     unsigned short _nbases;    // Number of bases.
  210.     unsigned short _nclass_members;    // Number of members that are classes.
  211.     unsigned short _nvbases;    // Number of transitive virtual bases.
  212.     enum { exception_aware = 1 };
  213.     // Next three fields for exception handling only; not accessible by public.
  214.     unsigned short _info;    // Bits from above enum.
  215.     int _nobjects;        // Number of subobjects for this type: 1+embedded objects.
  216.     int _total_subobjects;    // Number of total objects for the lattice rooted here.
  217.     const Base_info *base_list;       // List of bases.
  218.     const Vbase_info *vbase_list;    // List of virtual bases.
  219.     const Member_info *member_list;    // List of members of a class type.
  220.     // Used by some customers:  default constructor (ctor)
  221.     // and default copy constructor (copy_ctor).  These members are 0 if
  222.     // not provided.  To provide them, turn on toggle
  223.     // rtti_includes_constructors.  If On, the compiler attempts to
  224.     // generate the default constructor and copy constructor where it
  225.     // lays down the RTTI for the class, and places the address in the
  226.     // RTTI entry.  Such attempts at generation may produce compile-time
  227.     // errors in some cases.  For example:
  228.     //    - a base class has an inaccessible default ctor or copy ctor.
  229.     //      - a class has a copy constructor but no constructor; the
  230.     //        compiler is not permitted to synthesize a constructor.
  231.     // NOTE that this is for native C++ classes only; SOM classes do not
  232.     // use these RTTI structures.  The SOM object model does not allow
  233.     // storing a pointer to the RTTI structure in an object's method
  234.     // table, because SOM controls the object storage allocation and the
  235.     // method table generation.
  236.     //
  237.     // You use methods constructor_address() to determine whether the
  238.     // class has a constructor and/or copy constructor.  A non-zero
  239.     // result from means you can call the method call_constructor() to
  240.     // (default-) construct an object.  Similarly for
  241.     // copy_constructor_address() and call_copy_constructor().
  242.     ctor_type ctor, copy_ctor;
  243.     // Needed by exception handling:  the destructor for a class:
  244.     dtor_type dtor;
  245.     delete_type opdel;    // Class's operator delete.
  246.   public:
  247.     ~Class_type_info();
  248.     virtual int nbases() const;
  249.     virtual int nclass_members() const;
  250.     virtual int nvbases() const;
  251.     virtual const Member_info *class_member(unsigned i) const;
  252.     virtual const Base_info *base(unsigned i) const;
  253.     virtual const Vbase_info *vbase(unsigned i) const;
  254.  
  255.     // Returns the address of the default constructor; 0 if none.
  256.     virtual ctor_type constructor_address() const;
  257.     virtual void call_constructor(void *object) const;
  258.  
  259.     // Returns the address of the default constructor; 0 if none.
  260.     virtual ctor_type copy_constructor_address() const;
  261.     virtual void call_copy_constructor(void *dest, void *src) const;
  262.  
  263.     // Returns the address of the destructor; 0 if none.
  264.     virtual dtor_type destructor_address() const;
  265.     virtual void call_destructor(void *object, char as_base) const;
  266.  
  267.     // Returns the address of a class-specific operator delete; 0 if none.
  268.     virtual delete_type opdel_address() const;
  269.     virtual void call_opdel(void *object) const;
  270.  
  271.     // These are for EH only and are not available to others, even though
  272.     // stated public.  The implementation for them is within the EH RT only.
  273.     int nobjects() const;       // Number of subobjects for this type: 1+embedded objects.
  274.     int total_subobjects() const; // Number of total objects for the lattice rooted here.
  275.     };
  276.  
  277. class SOM_class_type_info: public Type_info {
  278.     // Because we can't declare SOMClass lest we traipse on ANSI name space,
  279.     // we ask if it's been defined.
  280.   public:
  281.     #ifdef SOMClass
  282.     typedef SOMClass** class_object_type;
  283.     #else
  284.     typedef void** class_object_type;
  285.     #endif
  286.   private:
  287.     class_object_type _class_object;    // Points to a location containing the class object pointer.
  288.   public:
  289.     ~SOM_class_type_info();
  290.     virtual class_object_type class_object() const;
  291.     };
  292.  
  293. // In the Jan '94 draft Bad_cast was known both as Bad_cast and badcast.
  294. // In the July 94 draft Bad_cast has become bad_cast.  Hmm.
  295. struct Bad_cast {
  296.     char *from;
  297.     Class_type_info *actual_type, *from_type, *to_type;
  298.     Bad_cast(char *from, Class_type_info *actual_type,
  299.     Class_type_info *from_type, Class_type_info *to_type) {
  300.     this->from = from;
  301.     this->actual_type = actual_type;
  302.     this->from_type = from_type;
  303.     this->to_type = to_type;
  304.     }
  305.     virtual ~Bad_cast();    // Locate type
  306.     };
  307.  
  308. pragma pop(run_time_type_info);
  309.  
  310. }
  311. using typeinfo::Bad_cast;
  312. using typeinfo::Type_info; // This what's it's supposed to be called?
  313.  
  314. /**************************************************************************
  315. Type info structures.
  316.  
  317. The type of an object is represented by another object that is of type
  318. Type_info or a type derived from Type_info.  For example, the type of a
  319. struct/union/class is of type Class_type_info; the type of a pointer
  320. type is of type Pointer_type_info.
  321.  
  322. For an object X of a polymorphic type, typeid(X) returns a reference to
  323. the type object Tobj representing the type of X.  In the implementation,
  324. location 0 of the virtual function table for X points to Tobj.
  325.  
  326. For a C++ type T, typeid(T) returns a reference to the type object
  327. representing the type T.
  328.  
  329. For example:
  330.  
  331.     struct s { ... };
  332.     s *p;
  333.               __vt_s         __rtti_1s
  334. p ->     +--------+      +--------+      +--------+
  335.     |        |  ->  |        |  ->  |        |  -> __vt_Class_type_info
  336.     +--------+      +--------+      +--------+
  337.     |  ...   |      |  ...   |      | 1 | 0  |
  338.     +--------+      +--------+      +--------+
  339.                     | info   |
  340.                     | about  |
  341.                     |   s    |
  342.                     +--------+
  343.  
  344. __vt_s is the virtual function table for type s.  It's 0th location
  345. points to the object representing the type of s.  Typeid(s) has two
  346. halfword 0s indicating no bases and no class members.
  347.  
  348. __rtti_1s is the type object for type s, obtained by writing Typeid(s)
  349. in C++.  Typeid(s) is of type Class_type_info, because s is a class;
  350. thus the virtual function table for Typeid(s) points to
  351. __vt_Class_type_info.
  352.  
  353. The above picture is a general picture for all structure types.  In
  354. general, for any structure type s, the compiler constructs an object
  355. __rtti_1s, makes its vfunc table be __vt_Class_type_info, and makes
  356. __vt_s[0] point to __rtti_1s.
  357.  
  358. This includes Class_type_info itself, which is a structure type.  If
  359. we apply this algorithm to Class_type_info we get:
  360.  
  361.     struct Class_type_info { ... };
  362.     Class_type_info *p;
  363.             __vt_Class_type_info  __rtti_15Class_type_info
  364. p ->     +--------+      +--------+      +--------+
  365.     |        |  ->  |        |  ->  |        |  -> __vt_Class_type_info
  366.     +--------+      +--------+      +--------+
  367.     |  ...   |      |  ...   |      | 1 | 0  |
  368.     +--------+      +--------+      +--------+     +--------+
  369.                     |  ...   |  -> | |      |
  370.                     +--------+     +-|------+
  371.                              |
  372.                              -> __rtti_16Type_info
  373.                             
  374. Now you can see that Typeid(*p), which is Typeid(Class_type_info), has
  375. type Class_type_info.  I.e.,
  376.  
  377.     Typeid(Class_type_info) = __rtti_15Class_type_info
  378.     Typeid(__rtti_15Class_type_info) = __rtti_15Class_type_info
  379.  
  380. and thus you can conclude
  381.  
  382.     Typeid(Class_type_info) = Typeid(Typeid(Class_type_info))
  383.  
  384. In words, Typeid(Class_type_info) is an object that is its own type.
  385.  
  386. __rtti_15Class_type_info shows that there is exactly one base, and the
  387. base is the __rtti_16Type_info object.  Examining Type_info we have the
  388. following picture:
  389.  
  390.     struct Type_info { ... };
  391.     Type_info *p;
  392.             __vt_Type_info  __rtti_16Type_info
  393. p ->     +--------+      +--------+      +--------+
  394.     |        |  ->  |        |  ->  |        |  -> __vt_Class_type_info
  395.     +--------+      +--------+      +--------+
  396.     |  ...   |      |  ...   |      | 0 | 0  |
  397.     +--------+      +--------+      +--------+
  398.                     |  ...   |
  399.                     +--------+
  400.                         
  401. I.e., Typeid(Type_info) == __rtti_16Type_info, and
  402. Typeid(__rtti_16Type_info) = __rtti_15Class_type_info.
  403.  
  404. Curiously, this means that __rtti_15Class_type_info is the type of the
  405. type of Class_type_info's base.  Or, looking at the structures,
  406. __rtti_15Class_type_info points to __rtti_16Type_info, and
  407. Typeof(__rtti_16Type_info) = __rtti_15Class_type_info.
  408.  
  409. Summarizing the relationships between Type_info and Class_type_info:
  410.  
  411.        +-----------------------------------------------+
  412.        V                                               |
  413. __vt_Class_type_info  __rtti_15Class_type_info           |
  414.     +--------+      +--------+                         |
  415.     |        |  ->  |        |  -----------------------+
  416.     +--------+      +--------+                         |
  417.     |  ...   |      | 1 | 0  |                         |
  418.     +--------+      +--------+     +--------+          |
  419.             |        |  -> | |      |          |
  420.             +--------+     +-|------+          |
  421.                      |                 |
  422.                +-------------+                 |
  423.                V                               |
  424. __vt_Type_info  __rtti_16Type_info                       |
  425.     +--------+      +--------+                         |
  426. ->  |        |  ->  |        |  -----------------------+
  427.     +--------+      +--------+
  428.     |  ...   |      | 0 | 0  |
  429.     +--------+      +--------+
  430.             |  ...   |
  431.             +--------+
  432.  
  433. // Example use:
  434.  
  435. #include "../tinfo.h"
  436. pragma on(run_time_type_info);
  437. struct base { int y; virtual goo() {} };
  438. struct s:base { int x; virtual foo(){}} z;
  439. main () {
  440.     printf("%s\n",typeid(z).name());
  441.     Class_type_info &cti = (Class_type_info&)typeid(z);
  442.     for (int i = 0; i < cti.nbases; i++)
  443.     printf("Base#%d is %s\n",i,cti.base_list[i].base->name());
  444.     }
  445.  
  446. // prints:
  447. s
  448. Base#0 is base
  449.  
  450. **************************************************************************/
  451.  
  452. #if __TYPEINFO_IMPLEMENTATION
  453. // Private to the implementation of typeinfo:
  454. namespace typeinfo {
  455.  
  456.     enum {FALSE,TRUE};    
  457.     
  458.     struct conversion {
  459.     void *object;    // Address of object, or pointer thereto.
  460.     char backwards;    // Set TRUE for ptr-to-member contravariant conversion.
  461.     conversion(void *O):object(O),backwards(FALSE) {}
  462.     conversion(void *O, int b) :object(O),backwards(b) {}
  463.     };
  464.  
  465.     int is_base_of_(
  466.     const Type_info *this, const Type_info *of_that, conversion *C,
  467.     char of_that_is_most_derived);
  468.  
  469.     int is_base_of(
  470.     const Type_info *this, const Type_info *of_that, conversion *C);
  471.     
  472.     int same_type(const Type_info *T1, const Type_info *T2);
  473.  
  474.     void each_transitive_base(const Type_info *of_that, char DFO) ->
  475.     (const Class_type_info*, char is_virtual);
  476.     
  477.     int modifier_superset(const Type_info *this, const Type_info *that);
  478.  
  479.     int is_modified_type(const Type_info *T);
  480.     // Remove modifiers from a type.
  481.     const Type_info *un_modify(const Type_info *tip);
  482.     long modifiers(const Type_info *tip);
  483.     type_kind tkind_mod(const Type_info *T);
  484.     type_kind tkind(const Type_info *T);
  485.     int is_reference_type(const Type_info *tip);
  486.     // Remove a & from a reference type.
  487.     const Type_info *un_ref(const Type_info *tip);
  488.     pragma on(mangle_fname_only);
  489.     void *dynamic_cast(char *ptr,
  490.     Class_type_info *actual_type,
  491.     Class_type_info *from, Class_type_info *to,
  492.     char casting_to_reference);
  493.     SOMObject *som_dynamic_cast(
  494.     SOMObject *object, SOMClass *to_type, char casting_to_reference);
  495.     Class_type_info *get_typeid(Class_type_info *type);
  496.     pragma pop(mangle_fname_only);
  497.     typedef int (SOMObject::*true_dtor)(char dealloc, void *control);
  498.     extern struct SOM_info {
  499.     // These pointers are brought in if you link with -Hsom;
  500.     // otherwise they remain 0 (linker puts them in common).
  501.     boolean (SOMClass::*somDescendedFrom)(SOMClass* aClassObj);
  502.     // The default constructor:
  503.     int (SOMObject::*ctor)(void);
  504.     // The copy constructor:
  505.     int (SOMObject::*copy_ctor)(const SOMObject&);
  506.     // The destructor:
  507.     int (SOMObject::*dtor)();
  508.     // Make something an object:
  509.     SOMObject* (SOMClass::*somRenewNoInit)(void* obj);
  510.     // Destruct bases in a partially-constructed SOM object.
  511.     void (*destruct_SOM_bases)(
  512.         SOMObject *p, SOMClass *tor_type, int bases_constructed);
  513.     // Find starting address of local data.
  514.     void *(*local_data_start)(SOMObject *p);
  515.     // Ask if an object responds to methods.
  516.     boolean (SOMObject::*somIsA)(SOMClass* aClassObj);
  517.     long (SOMClass::*somGetInstanceSize)();
  518.     } SOM_ptrs;
  519.     void checkSOM();
  520.     }
  521. #endif
  522. namespace exceptions {
  523.     _CRTIMPCC extern void *error_file;      // Where to write exception errors; default stdout.
  524.     _CRTIMPCC extern int exception_tracing; // If you have tracing compiled in, turn
  525.                   // this on to start tracing.
  526.     _CRTIMPCC extern int abnormal_messages; // Default on; unexpected/terminate print
  527.                   // a message before doing their job.
  528.     typedef const typeinfo::Type_info TI;
  529.     typedef void (*pfv)();
  530.     struct exception_state;    // private.
  531.     pragma on(mangle_fname_only);
  532.     void enter(exception_state *p);
  533.     void exit(exception_state *p);
  534.     // Same as exit, but leave the current object count intact
  535.     // (it has to be passed to the callee).
  536.     void exit_ret(exception_state *p);
  537.     void exit_cnt(exception_state *p, int set_count_to_this_value);
  538.     int dyn_obj_count(TI *type);
  539.     void rethrow();
  540.     typedef void (*copy_ctor_ptr)(...);
  541.     void throwe(void *op, TI *tip, copy_ctor_ptr copyp);
  542.     void trace_throw(void *op, TI *tip, copy_ctor_ptr copyp,
  543.     const char *file_name, const char *func_name, int line_number);
  544.     void trace_rethrow(
  545.     const char *file_name, const char *func_name, int line_number);
  546.     void *array_type_and_inc(char *object_ptr, long offset_to_vp);
  547.     void catch_finish();
  548.     pragma pop(mangle_fname_only);
  549.     }
  550. // According to the ARM these have to be global; too bad they
  551. // can't be in the exceptions namespace.
  552. exceptions::pfv set_terminate(exceptions::pfv p);
  553. exceptions::pfv set_unexpected(exceptions::pfv p);
  554. void terminate();
  555. void unexpected();
  556.  
  557. #pragma pop(macro_substitution)
  558. ;
  559.  
  560. #endif /* _TYPEINFO_H */
  561.