home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 5.ddi / DOC.ZIP / H2ASH.TSM < prev    next >
Encoding:
Text File  |  1992-06-10  |  26.1 KB  |  756 lines

  1. +----------------------------------------------------------------------------+
  2. |    Online Documentation for H2ASH                                          |
  3. +----------------------------------------------------------------------------+
  4.  
  5. C/C++ modules within a program typically share definitions of types and data 
  6. structures among themselves. They do this by including small files called 
  7. header files, which contain type definitions and data structure definitions 
  8. used by more than one module. A C/C++ header file usually has a name ending 
  9. in H.  Similarly, assembly modules use header files with names that end in 
  10. .ASH (or .INC).
  11.  
  12. Programs containing modules written in both C or C++ and modules written 
  13. using Turbo Assembler must be able to share definitions of types and data
  14. structures.  The H2ASH converter utility lets this happen.
  15.  
  16. The converter has the following limitations:
  17.  
  18.   -- All executable statements are ignored; no code output is generated.
  19.  
  20.   -- #INCLUDEs are fully expanded in the output.
  21.  
  22.   -- Name conflicts can occur in the assembly output since C++ scoping
  23.      rules differ greatly from assembly rules; using Ideal mode output 
  24.      can help.
  25.  
  26.   -- Multiple Inheritance, Virtual Base Classes, and Templates are not
  27.      supported in this version of H2ASH.
  28.  
  29. The H2ASH converter not only smooths the interface between C/C++ and assembly 
  30. language, it also lets you write C++ base classes directly in assembly lang-
  31. uage (for maximum performance). H2ASH automatically converts base class 
  32. declarations in C++ into equivalent assembly object definitions, and defines 
  33. method names. We recommend that you use the following procedure for writing 
  34. base classes in assembly language:
  35.  
  36.   1) Write the class declaration in a C/C++ header file.
  37.  
  38.   2) Include the C header file in all descendant classes, and in the C/C++
  39.      modules that use the base class.
  40.  
  41.   3) Use the H2ASH converter on the header file to produce an assembly
  42.      object header file; you can automate this by setting up a makefile.
  43.  
  44.   4) Include the assembly object header file in the module where the
  45.      assembly language methods are written.
  46.  
  47.  
  48. +----------------------------------------------------------------------------+
  49. |    Command Line Interface for H2ASH                                        |
  50. +----------------------------------------------------------------------------+
  51.  
  52.   You can invoke H2ASH by typing the following command on the command line:
  53.  
  54.       H2ASH [[switches] <filename> [<filename> ... ]]
  55.  
  56. H2ASH triggers the printing of a help screen. By default, H2ASH accepts a 
  57. C/C++ header file, and produces a Turbo Assembler (TASM) 3.0 compatible 
  58. assembly include file with extension .ASH.  The resulting file is
  59. not a self-contained assembly language program; rather, it contains TASM
  60. type declarations and EQU statements that correspond to declarations in
  61. the original C/C++ header file.  H2ASH recognizes wild cards for filename
  62. matching.
  63.  
  64.    All H2ASH-specific command line switches are a submode of the -q switch, 
  65. that is they all have the following form:
  66.  
  67.      -q[<character>] [-]
  68.  
  69. H2ASH also recognizes a majority of the Borland C++ command-line switches.
  70. In particular, word-alignment (-a), force C++ compile (-P), set output file 
  71. name (-o), define symbol (-D), and the compilation model directives (-mt, 
  72. -ms, -ml, ...), are all supported.  For a definitive description of the BCC 
  73. command-line interface, see the Borland C++ User's Guide.
  74.  
  75. H2ASH allows the following switches:
  76.  
  77.   -q-           turn off the H2ASH converter
  78.                 <default is on>
  79.  
  80.   -qc        pass c/c++ comments into the .ASH file 
  81.                 <default is off>
  82.   
  83.   -qn           enable name-mangling 
  84.                 <default is on>
  85.  
  86.   -qf           a 'strict' mode that strips out all untranslatable source 
  87.                 code (as opposed to the default behavior of issuing a warning
  88.                 and partially translating the declaration in question)
  89.                 <default is off>
  90.  
  91.   -qi           generate Ideal mode code, as opposed to Masm mode code
  92.                 <default is off>
  93.  
  94.   -qd           generate EQUs for #DEFINE statements which appear on the
  95.                 command-line, in project configuration file, or in the 
  96.                 original source program
  97.                 <default is on>
  98.  
  99.   -qb           generate EQUs for #DEFINE statements which are normally 
  100.                 generated automatically by the compiler
  101.                 <default is off>
  102.  
  103.   -qt           generate Tasm directives as needed (H2ASH will emit .DATA 
  104.                 and .MODEL directives whenever static declarations appear 
  105.                 in the original C/C++ header file.  The IDEAL directive is 
  106.                 generated whenever Ideal mode is used)
  107.                 <default is on>
  108.  
  109.   -qs           pass original source code into the .ASH file
  110.                 <default is off>
  111.  
  112. +----------------------------------------------------------------------------+
  113. |    Processing #DEFINE directives and macros                                |
  114. +----------------------------------------------------------------------------+
  115.  
  116.     H2ASH accepts C preprocessor #DEFINE direcives and generates a corres-
  117. ponding EQU directive containing the symbol name and its associated value.
  118. Hexidecimal and octal constants force H2ASH to append an 'h' or 'q' radix 
  119. specifier onto the end of the constant value.  Decimal constants are passed 
  120. directly to the output stream, while floating point numbers are treated as 
  121. text literals. Here's an example of input and output:
  122.  
  123.                           ---- H2ASH input ----
  124.  
  125. #define        ONE         1
  126. #define        NEG_ONE           -1
  127. #define        OCTAL_ONE       01
  128. #define        HEX_ONE         0x1
  129. #define           FLOAT_ONE       1.000
  130.  
  131.                           ---- H2ASH output ----
  132.  
  133. ONE           EQU         1
  134. NEG_ONE           EQU         -1
  135. OCTAL_ONE      EQU             1q
  136. HEX_ONE        EQU             1h
  137. FLOAT_ONE      EQU             <1.000>
  138.  
  139.     All other macro #DEFINEs generate text EQUs into the H2ASH output 
  140. stream.  However, if the #DEFINE contains any macro arguments, a warning is 
  141. issued and the macro in question is not processed.  For example,
  142.  
  143.                           ---- H2ASH input ----
  144.  
  145. #define        PI              22/7
  146. #define        LOOP_FOREVER    while(1) {
  147. #define        seq(s,t)           strcmp(s,t)
  148.     
  149.                           ---- H2ASH output ----
  150.  
  151. PI             EQU             <22/7>
  152. LOOP_FOREVER   EQU           <while(1) {>
  153.  
  154.     H2ASH does not directly translate C preprocessor conditional 
  155. #IF/#ELSE/#ENDIF directives into their TASM equivalents. Rather, it evaluates 
  156. the constant-expression that is the argument to the conditional directive, and
  157. then passes the appropriate clause of the conditional into the output stream, 
  158. as follows:
  159.  
  160.                           ---- H2ASH input ----
  161.  
  162. #if 0
  163. #define     PI         3.14159
  164. #else
  165. #define     PI         22/7
  166. #endif
  167.  
  168.                           ---- H2ASH output ----
  169.  
  170. ZOO        PI        <22/7>
  171.  
  172. +----------------------------------------------------------------------------+
  173. |    Processing Simple Declarations                                          |
  174. +----------------------------------------------------------------------------+
  175.  
  176.     H2ASH does not process declarations that have storage class 'auto'; that 
  177. is, any C/C++ declarations contained in compound-blocks are ignored. However, 
  178. declarations that have static linkage are translated into TASM 'DB', 'DW', 
  179. 'DD', .... statements, depending on the size or type of the variable. Further-
  180. more, declarations that have external linkage are translated into TASM 
  181. 'GLOBAL' statements with an appropriate type specifier that is dependant on 
  182. the size of the C/C++ variable. H2ASH ignores all initializers for declara-
  183. tions if the initializer expression is not a constant expression. If this 
  184. situation occurs, H2ASH issues a warning message. For example,
  185.  
  186.                           ---- H2ASH input ----
  187.  
  188. char                char;
  189. unsigned char                  unsigned_char;
  190. signed char            signed_char;
  191. int                integer;
  192. unsigned int            unsigned_integer;
  193. signed int            signed_integer;
  194. long                long;
  195. unsigned long            unsigned_long;
  196. signed long            signed_long;
  197. float                float;
  198. double                double;
  199. long double            long_double;
  200.  
  201.                           ---- H2ASH output ----
  202.  
  203. GLOBAL    C                char:BYTE
  204. GLOBAL    C                       unsigned_char:BYTE
  205. GLOBAL    C                signed_char:BYTE
  206. GLOBAL    C                       integer:WORD
  207. GLOBAL    C                       unsigned_integer:WORD
  208. GLOBAL    C                signed_integer:WORD
  209. GLOBAL    C                       long:DWORD
  210. GLOBAL    C                       unsigned_long:DWORD
  211. GLOBAL    C                       signed_long:DWORD
  212. GLOBAL    C                       float:PWORD
  213. GLOBAL    C                       double:QWORD
  214. GLOBAL    C                       long_double:TBYTE
  215.  
  216.     H2ASH ignores the type modifiers 'const' and 'volatile'.  However, the
  217. linkage specifiers 'pascal' and 'cdecl', do generate the corresponding TASM
  218. equivalents.  Static variables, as required by the ANSI C standard, generate
  219. a default zero initializer expression of the appropriate width for the data 
  220. type in question.
  221.  
  222.                           ---- H2ASH input ----
  223.  
  224. const int const_int;
  225. volatile int volatile_int;
  226. static int static_int;
  227. static double static_double;
  228. extern int extern_int;
  229. int pascal int_pascal;
  230. int cdecl  int_cdecl;
  231.  
  232.                           ---- H2ASH output ----
  233.  
  234. GLOBAL          C            const_int   :WORD
  235. GLOBAL          C               volatile_int:WORD
  236.  
  237. .DATA
  238. static_int      DW              0 
  239. static_double   DQ              0.0
  240.  
  241. GLOBAL          C               extern_int  :WORD
  242. GLOBAL          PASCAL          int_pascal  :WORD
  243. GLOBAL          C               int_cdecl   :WORD
  244.  
  245.  
  246. +----------------------------------------------------------------------------+
  247. |    Processing Reference/Pointer/Array Declarations                         |
  248. +----------------------------------------------------------------------------+
  249.  
  250.     Reference and pointer declarations are handled in a similar manner to
  251. basic variable declarations, except that the 'PTR' type specifier is intro-
  252. duced for each level of pointer/reference indirection.  Note that any init-
  253. ializer that requires the creation of a temporary variable, or is not a 
  254. constant expression is ignored.  For example,
  255.  
  256.                           ---- H2ASH input ----
  257.  
  258. char      *v1;
  259. int      **v2;
  260. char far  *v3;
  261. char near *v4;
  262. int       &v5 = 1;
  263.  
  264.                           ---- H2ASH output ----
  265.  
  266. GLOBAL        C    v1:    PTR      BYTE
  267. GLOBAL        C    v2:    PTR  PTR WORD
  268. GLOBAL        C    v3:    FAR  PTR BYTE
  269. GLOBAL        C    v4:    NEAR PTR BYTE
  270. GLOBAL          C       v5:     PTR      WORD
  271.  
  272.     Arrays are treated like basic variable declarations, where the type 
  273. specifier consists of the element type of the array, followed by an optional 
  274. repetition field that contains the dimension of the array. If the array is an
  275. incomplete declaration, (that is, if it's dimension is not fully specified)
  276. the repetition field is not passed into the output stream.  For example,
  277.  
  278.                           ---- H2ASH input ----
  279.  
  280. extern char a1[];
  281. extern char a2[10];
  282. extern char a3[][10];
  283. extern char a4[10][20];
  284.  
  285.                           ---- H2ASH output ----
  286.  
  287. GLOBAL        C    a1:    BYTE
  288. GLOBAL        C    a2:    BYTE : 10
  289. GLOBAL        C       a3:    BYTE
  290. GLOBAL        C    a4:    BYTE : 200
  291.  
  292. +----------------------------------------------------------------------------+
  293. |    Processing TYPEDEF Declarations                                         |
  294. +----------------------------------------------------------------------------+
  295.  
  296.     C/C++ TYPEDEF declarations are mapped directly onto their equivalent TASM
  297. counterpart.  When the typedef alias (the name of the typedef) is used as the
  298. type specifier in another declaration, the actual type of the typedef, as op-
  299. posed to the typedef alias itself, is emitted into the output stream. For
  300. example,
  301.     
  302.                           ---- H2ASH input ----
  303.  
  304. typedef     unsigned long     ul;
  305. typedef     ul         alias_ul;
  306. alias_ul             ul_object;
  307.  
  308.                           ---- H2ASH output ----
  309.  
  310. ul        TYPEDEF        DWORD
  311. alias_ul    TYPEDEF        DWORD
  312. GLOBAL    C    ul_object      :DWORD
  313.  
  314. +----------------------------------------------------------------------------+
  315. |    Processing ENUM Declarations                                            |
  316. +----------------------------------------------------------------------------+
  317.  
  318.     C/C++ enumeration types are converted directly into TASM 'ENUM' defini-
  319. tions.  Each enumerator is given an explicit initializer if the value of the
  320. enumerator changes by more than one unit from the previously processed enum-
  321. erator, or if the enumerator already has an explicit initializer in the
  322. C/C++ source code.  As usual, this initializer must contain a constant-
  323. expression.
  324.  
  325.     H2ASH automatically synthesizes a tag name if the enumeration does not 
  326. contain a tag.  This generated name is always unique within the compilation 
  327. unit it occurs in, and can be in subsequent variable declarations. For 
  328. example,
  329.  
  330.                           ---- H2ASH input ----
  331.  
  332.  enum FOO    { a, b, c = -1, d = sizeof(enum FOO)};
  333.  enum           { north, east, south, west };
  334.  
  335.                           ---- H2ASH output ---- 
  336.  
  337.  FOO  enum \    
  338.    a = 0,  \
  339.    b,      \
  340.    c = -1, \
  341.    d = 2   \
  342.  
  343.  
  344.  tag$1 enum \
  345.    north,   \
  346.    east,    \
  347.    south,   \
  348.    west     \
  349.  
  350.     Finally, if the enumeration is not representable within a declaration
  351. of size BYTE, H2ASH generates an extra enumerator (which has a unique name),
  352. and appends it to the end of the enumeration list.  This enumerator is used 
  353. to induce TASM to pack the enumeration within a datatype of size WORD. This 
  354. situation can occur whenvever you use the -b option, or whenever the value 
  355. of an enumerator exceeds a value representable within a BYTE. For example,
  356.  
  357.  
  358.                           ---- H2ASH input ----
  359.  
  360.  enum direction  { north, east = 254, south, west };
  361.  enum color      { red, green = 256, blue };
  362.  
  363.                           ---- H2ASH output ----  
  364.  
  365.  direction enum \
  366.    north, \
  367.    east = 254, \
  368.    south, \
  369.    west, \
  370.    pad$0 = 256
  371.  
  372.  direction enum \
  373.    red, \
  374.    green = 256, \
  375.    blue  
  376.    
  377.  
  378. +----------------------------------------------------------------------------+
  379. |    Processing Simple Aggregate Declarations                                |
  380. +----------------------------------------------------------------------------+
  381.  
  382.  
  383.     Structures and unions are mapped by H2ASH onto their direct TASM STRUC 
  384. and UNION counterparts. If a tag is not present in the aggregate declaration, 
  385. H2ASH automatically generates one.  The GLOBAL directive is used to represent
  386. an instance of the structure, where the type-field contains that tag name of
  387. the structure or union in question.  For example,
  388.  
  389.  
  390.                           ---- H2ASH input ----
  391.  
  392.  struct S1 {
  393.    int field1;
  394.    int field2;
  395.    } S1_object;
  396.  
  397.  
  398.  union U1 {
  399.    int field1;
  400.    int field2;
  401.    int (*field3)(void); 
  402.    } U1_object;
  403.  
  404.                           ---- H2ASH output ----  
  405.  
  406.  S1        STRUC
  407.  S1@field1    DW        ?
  408.  S1@field2      DW        ?
  409.  S1        ENDS
  410.  
  411.  GLOBAL          C       S1_object:S1
  412.  
  413.  tag$0        UNION              ; tag name is synthesized
  414.  tag$0@field1   DW        ?
  415.  tag$0@field2   DW        ?
  416.  tag$0@field3   DD FAR PTR      ?  ; or NEAR PTR, depending on the model
  417.  tag$0          ENDS
  418.  
  419.  GLOBAL           C    U1_object:tag$0     
  420.  
  421.  
  422.     Using the word-alignment (-a) option lets H2ASH explicitly output
  423. appropriate padding.  For the exact structure-alignment rules, see the 
  424. C++ Programmer's Guilde.  For example,
  425.  
  426.  
  427.                           ---- H2ASH input ----  
  428.  
  429.  struct S2 {         
  430.    char field1;
  431.    int  field2;
  432.    };
  433.  
  434.                           ---- H2ASH output ----      
  435.  
  436.  S2             STRUC
  437.  S2@field1      DB              ?
  438.                 DB              ?  ; force word alignment (only if -a is used)
  439.  S2@field2      DW              ?
  440.  S2             ENDS
  441.  
  442.  
  443.     H2ASH treats nested structures as separate TASM STRUC declarations, and
  444. gives the nested structures specially mangled names. This is done because
  445. nested structures are not true members; they are merely in the lexical scope
  446. of the structure in which they are contained.  However, if a nested structure
  447. is instantiated (for example, an object of the type of that structure is 
  448. declared), the appropriate space is reserved in the enclosing structure as 
  449. in the following example:
  450.  
  451.                           ---- H2ASH input ----  
  452.  
  453. struct a {
  454.     int i;
  455.     struct b {
  456.         int j;
  457.     };
  458.         int k;
  459.         struct c {
  460.                 int l;
  461.     } c_instance;
  462. };
  463.  
  464.                           ---- H2ASH output ----  
  465.  
  466. a@b           STRUC   
  467. a@b@j         DW      ?
  468. a@b           ENDS
  469.  
  470. a@c           STRUC
  471. a@c@l         DW      ?
  472. a@c           ENDS
  473.  
  474. a             STRUC   
  475. a@i           DW      ?
  476. a@k           DW      ?
  477. a@c_instance  C       <>  ;this is an actual member, so reserve space for it
  478. a             ENDS
  479.  
  480.  
  481. +----------------------------------------------------------------------------+
  482. |    Processing Bitfield Declarations                                        |
  483. +----------------------------------------------------------------------------+
  484.  
  485.  
  486.     Bitfields are represented by H2ASH as TASM RECORD declarations.  In 
  487. general, it generates two kinds of RECORDS. First, if a STRUCT contains
  488. only bitfield declarations and if each of the bitfields are of the same type,
  489. and if this type is sufficiently large to contain all of the fields, H2ASH 
  490. generates a global RECORD declaration.  H2ASH inserts a uniquely named padding
  491. field at the top of the RECORD so that proper alignment is achieved.  For 
  492. example,
  493.  
  494.                           ---- H2ASH input ----
  495.  
  496.  struct S1 {
  497.    int field1: 1;
  498.    int field2: 4;
  499.    };
  500.  
  501.                           ---- H2ASH output ----
  502.  
  503.   S1    RECORD {
  504.  
  505.       S1@pad_0    :11,  ; 11+4+1 = sizeof(int);
  506.         S1@field21  :4,  
  507.         S1@field11  :1
  508.  
  509.         }
  510.  
  511.    If H2ASH is unable to generate a global RECORD declaration, a local one
  512. is emitted within the STRUC in which the original bitfield is declared. 
  513. Furthermore, a member with the type of the tag of the local RECORD declaration
  514. is declared to reserve the appropriate amount of storage. H2ASH attempts to 
  515. pack adjacent bitfields within a single record when adjacent bitfields are 
  516. of the same type, and whenever the type of the bitfield is large enough to 
  517. contain the adjacent fields.  For example,
  518.  
  519.                           ---- H2ASH input ----
  520.  
  521.  struct S1 {
  522.     int  field1;
  523.     char field2: 1;
  524.     char field3: 8; // NOTE: cannot be packed with field2
  525.     };
  526.  
  527.                           ---- H2ASH output ----
  528.  
  529.  S1        STRUC
  530.  S1@field1    DW    ?
  531.  
  532.  S1@REC_0       RECORD {
  533.                 S1@REC_0   :7 
  534.                 S1@field2  :1
  535.                 }
  536.  S1@BIT_0       S1@REC_0   <>  ; create an instance of this record
  537.  
  538.  S1@REC_1       RECORD {
  539.                 S1@field2  :8
  540.                 }
  541.  
  542.  S1@BIT_1       S1@REC_1   <>  ; create an instance of this record
  543.  S1             ENDS
  544.  
  545. +----------------------------------------------------------------------------+
  546. |    Processing Function/Operator Declarations                               |
  547. +----------------------------------------------------------------------------+
  548.  
  549.     File scope function declarations are emitted as GLOBAL declarations with
  550. type NEAR or FAR, depending on the model settings.  Prototypes for func-
  551. tions are ignored, because TASM does not support typed CALLs or typed PROTO
  552. statements.  However, the prototype is encrypted by the mangled name of the 
  553. function.  For example,
  554.  
  555.                           ---- H2ASH input ----
  556.  
  557.  void   fvv(void);
  558.  extern efvv(void);
  559.  int    fiii(int, int);
  560.  
  561.                           ---- H2ASH output ----
  562.  
  563.  GLOBAL     C     @fvv$qv     :NEAR  ;or far, depending on model
  564.  GLOBAL  C    @efvv$qv    :NEAR  ;or far, depending on model
  565.  GLOBAL  C    @fiii$qii    :NEAR  ;or far, depending on model
  566.  
  567.  
  568.     H2ASH ignores default arguments, as well as all function bodies. In both
  569. cases, H2ASH issues a warning and processes that declaration as if the default
  570. arguments and function bodies were not present.  H2ASH also ignores static 
  571. function declarations. In this case, the declaration is not emitted into the 
  572. output stream.  Here's an example:
  573.  
  574.  
  575.                           ---- H2ASH input ---- 
  576.  
  577.  static sfvv(void);
  578.  void   dfii(int i = 0, int = sizeof(foo));
  579.  int    fvv(int i) { return ++i; }
  580.  
  581.                           ---- H2ASH output ----
  582.  
  583.  ; warning, declaration of static function 'sfvv(...)' ignored 
  584.  
  585.  void   C       @dfii$qii      :NEAR   ; warning, default arguments ignored
  586.  void   C       @fvv$qi        :NEAR   ; warning, function body ignored
  587.  
  588.  
  589.     H2ASH supports function and operator overloading by encoding function 
  590. prototypes and operator names. Otherwise, H2ASH treats these declarations 
  591. in exactly the same manner as ordinary functions.  For example,
  592.  
  593.                           ---- H2ASH input ---- 
  594.  
  595.  int abs(int,  int);
  596.  int abs(int);
  597.  
  598.  struct alpha;
  599.  
  600.  int operator+(alpha, int); 
  601.  int operator+(int, alpha); 
  602.  
  603.                           ---- H2ASH output ----
  604.  
  605.  GLOBAL    C    @abs$qii        :NEAR
  606.  GLOBAL    C    @abs$qi         :NEAR
  607.  
  608.  GLOBAL    C    @$badd$q5alphai :NEAR
  609.  GLOBAL    C    @$badd$iq5alpha :NEAR
  610.  
  611. +----------------------------------------------------------------------------+
  612. |    Processing Classes                                                      |
  613. +----------------------------------------------------------------------------+
  614.  
  615.     C++ classes are mapped onto TASM STRUC declarations, just as C STRUCTS 
  616. are.  Nonstatic class data members are treated as ordinary STRUCT fields.
  617. Static class data members are treated as GLOBAL declarations, and are emitted
  618. after the class declaration in whcih they are declared. Nonvirtual function
  619. members are treated exactly like ordinary function definitions, except, that
  620. they recieve a mangled name that encodes the tagname of class in which they 
  621. are contained. Virtual function members are treated exactly like nonvirtual 
  622. functions, except that they force H2ASH to allocate space for a virtual-
  623. function-table-pointer.  This pointer has a mangled name containing the suffix
  624. 'vptr$', which is always unique throughout a single compilation unit. Finally,
  625. all 'special' member functions (constructors, copy constructors, assignment 
  626. operators), are treated as ordinary function declarations. However, if they 
  627. are compiler-synthesized members, H2ASH does not emit them.  For example,
  628.  
  629.  
  630.                           ---- H2ASH input ----
  631.  
  632.  class c {
  633.  
  634.  
  635.      static int static_member;
  636.              int normal_member;
  637.  
  638.  public:
  639.  
  640.      virtual void f1_virtual(void);
  641.      virtual void f2_virtual(void);
  642.              void f3_normal(void);
  643.  
  644.      void *operator ++();
  645.  
  646.      c();
  647.      c(int&);
  648.      ~c(); 
  649.  
  650.    };
  651.  
  652.                           ---- H2ASH output ----
  653.  
  654. c                   STRUC   
  655. @c@normal_member    DW      ?
  656. @c@vptr$0           DW      NEAR PTR ?
  657. c                   ENDS
  658.  
  659. GLOBAL C            @c@static_member    :WORD 
  660. GLOBAL C            @c@f1_virtual$qv    :FAR
  661. GLOBAL C            @c@f2_virtual$qv    :FAR
  662. GLOBAL C            @c@f3_normal$qv     :FAR
  663. GLOBAL C            @c@$binc$qv         :FAR
  664. GLOBAL C            @c@$bctr$qv         :FAR
  665. GLOBAL C            @c@$bctr$qmi        :FAR
  666. GLOBAL C            @c@$bdtr$qv         :FAR
  667.  
  668.  
  669.     H2ASH supports single inheritance. If a program using multiple inheri-
  670. tance is presented as input, or if virtual bases are present, H2ASH terminates
  671. and gives an appropriate error message. Within a derived class, a base class
  672. is represented as a member subobject, and is treated by H2ASH as if it were 
  673. an ordinary member with a specially synthesized name: 'subobject$' which has 
  674. the type of the base class in question.  Again, this name is always unique.
  675. Virtual function table pointers are shared between the base and derived class;
  676. hence, no further space is allocated for the virtual-pointer within the 
  677. derived class.  For example,
  678.  
  679.  
  680.                           ---- H2ASH input ---- 
  681.  
  682.  class d : c {
  683.  
  684.      int derived_member;
  685.  
  686.      virtual void f1_virtual(void); // virtual override of c::f1_virtual()
  687.      
  688.      d();
  689.     ~d();
  690.  
  691.  };
  692.  
  693.                           ---- H2ASH output ---- 
  694.  
  695. d                   STRUC   
  696. d@subobject$0       c       <>
  697. d@derived_member    DW      ?
  698. d                   ENDS
  699.  
  700. GLOBAL C            @d@f1_virtual$qv    :FAR
  701. GLOBAL C            @d@$bctr$qv         :FAR
  702. GLOBAL C            @d@$bdtr$qv         :FAR
  703.  
  704.  
  705.     There are two kinds of pointer to data members: SI/MI members, or VB 
  706. members, represented as a single WORD or as a STRUC of width two WORD's, 
  707. respectively.  Pointers to function members are either a single WORD, for 
  708. SI, a double WORD STRUC, for MI, or a triple WORD STRUC, for VB.  In each 
  709. case, a separate TASM TYPEDEF or STRUC name is used as an alias for the type
  710. of the appropriate width. For a further discussion of pointers to data 
  711. members, see the Borland C++ Programmer's Guilde.  Here's another example:
  712.  
  713.  
  714.                           ---- H2ASH input ---- 
  715.  
  716.  int  f::*pointer_to_data_member;
  717.  int (f::*pointer_to_function)(char *);
  718.  
  719.  
  720.                           ---- H2ASH output ---- 
  721.  
  722.   ; if a SI/MI data member is generated
  723.  
  724.  SIMIdataPtr$   TYPEDEF         WORD
  725.  
  726.  GLOBAL        C        pointer_to_data_member:SIMIdataPtr$
  727.  
  728.   ; if a SI function member pointer is generated
  729.  
  730.  SIfuncFPtr$    TYPEDEF         FAR PTR WORD
  731.  
  732.  GLOBAL        C        pointer_to_function_member:SIfuncFPtr$
  733.  
  734.   ; if a VB data member is generated
  735.  
  736.  VBdataPtr$     STRUC
  737.     VBdataPtr@memberOffset      WORD
  738.     VBdataPtr@vbcptrOffset      WORD
  739.  VBdataPtr$     ENDS
  740.  
  741.  GLOBAL        C        pointer_to_data_member:VBdataPtr$
  742.  
  743.   ; if a SI function member pointer is generated
  744.  
  745.  VBFuncFPtr$    STRUC
  746.     VBFuncFPtr@funcAddr         FAR PTR WORD
  747.     VBFuncFPtr@memberOffset     WORD
  748.     VBFuncFPtr@vbcptrOffset     WORD
  749.  VBdataFPtr$    ENDS
  750.  
  751.  GLOBAL        C        pointer_to_function_member:VBFuncFPtr$
  752.  
  753.    C++ Templates are not supported in this version of H2ASH. If a program 
  754. containing templates is given as input, H2ASH outputs an error and terminates 
  755. execution.
  756.