home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / parsedecl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  53.3 KB  |  1,990 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains part of the Harvest C parser.  The parser is hand written,
  35.  * recursive descent.  This file contains parser routines for declarations.
  36.  * 
  37.  * 
  38.  * 
  39.  */
  40.  
  41.  
  42. #include "conditcomp.h"
  43. #include <stdio.h>
  44. #include <ctype.h>
  45. #include <string.h>
  46.  
  47. #include "structs.h"
  48. #include "CHarvestDoc.h"
  49. #include "CHarvestOptions.h"
  50. #include "CErrorLog.h"
  51.  
  52. extern CErrorLog *gErrs;
  53. extern CHarvestDoc *gProject;
  54.  
  55. #pragma segment ParseDecl
  56.  
  57.  
  58. ParamRecVia_t
  59. FindParam(char *name)
  60. {
  61.     ParamRecVia_t                   tmp;
  62.     tmp = ParamList;
  63.     while (tmp) {
  64.     if (!strcmp(name, Via(tmp)->name))
  65.         return tmp;
  66.     tmp = Via(tmp)->next;
  67.     }
  68.     return 0;
  69. }
  70.  
  71. void
  72. FreeSymImage(SymImageVia_t head)
  73. {
  74.     if (head) {
  75.     FreeSymImage(Via(head)->next);
  76.     Efree(head);
  77.     }
  78. }
  79.  
  80. int
  81. Do_declaration(SymListVia_t table)
  82. {
  83.     /*
  84.      * declaration : declaration_specifiers ';' | declaration_specifiers
  85.      * init_declarator_list ';' ;
  86.      */
  87.  
  88.     TypeRecordVia_t                 typerec;
  89.     SymImageVia_t                   declared;
  90.     SymImageVia_t                   curdeclared;
  91.     int                             tmp;
  92.     int                             regf, staticf, extf;
  93.     enum StorageClassCode           stor_class;
  94.     int junk;
  95.     regf = staticf = extf = 0;
  96.     tmp = 0;
  97.     typerec = Do_declaration_specifiers(1, &stor_class, &junk);
  98.     if (typerec) {
  99.     if (stor_class == SCC_static) {
  100.         staticf = 1;
  101.     }
  102.     if (stor_class == SCC_extern) {
  103.         extf = 1;
  104.     }
  105.     if (stor_class == SCC_register) {
  106.         regf = 1;
  107.     }
  108.     if (NextIs(';')) {
  109.         /*
  110.          * This should have been a struct, union, enum or something like
  111.          * that. TODO Check this
  112.          */
  113.     } else {
  114.         if (stor_class == SCC_typedef) {
  115.         /* We should probably have local scope for typedef names. */
  116.         declared = Do_init_declarator_list(TP_defnames, typerec, 0);
  117.         } else {
  118.         declared = Do_init_declarator_list(table, typerec, stor_class);
  119.         }
  120.         if (declared) {
  121.         /* The declaration has already been inserted into table */
  122.         curdeclared = declared;
  123.         if (regf) {
  124.             while (declared) {
  125.             Via(Via(declared)->Symbol)->storage_class = SCC_register;
  126.             declared = Via(declared)->next;
  127.             }
  128.         } else if (staticf) {
  129.             while (declared) {
  130.             Via(Via(declared)->Symbol)->storage_class = SCC_static;
  131.             declared = Via(declared)->next;
  132.             }
  133.         } else if (extf) {
  134.             while (declared) {
  135.             Via(Via(declared)->Symbol)->storage_class = SCC_extern;
  136.             declared = Via(declared)->next;
  137.             }
  138.         } else {
  139.         /* We need to check the symbols here, and mark them as extern
  140.             if they are functions.  */
  141.             while (declared) {
  142.                 if (isFunctionType(Via(Via(declared)->Symbol)->TP)) {
  143.                 Via(Via(declared)->Symbol)->storage_class = SCC_extern;
  144.             }
  145.             declared = Via(declared)->next;
  146.             }
  147.         }
  148.         tmp = 1;
  149.         FreeSymImage(curdeclared);
  150.         } else {
  151.         SyntaxError("Expecting declarator");
  152.         }
  153.         if (!NextIs(';')) {
  154.         SyntaxError("Missing semicolon");
  155.         }
  156.     }
  157.     }
  158.     return tmp;
  159. }
  160.  
  161. TypeRecordVia_t
  162. Do_declaration_specifiers(int sc_legal, enum StorageClassCode * stor_class,
  163.      int *pascalFlag)
  164. {
  165.     /*
  166.      * declaration_specifiers : storage_class_specifier |
  167.      * storage_class_specifier declaration_specifiers | type_specifier |
  168.      * type_specifier declaration_specifiers | type_qualifier |
  169.      * type_qualifier declaration_specifiers ;
  170.      */
  171.  
  172.     TypeRecordVia_t                 result;
  173.     int                             done;
  174.     int                             sc_count;
  175.     int                             qu_count;
  176.     SYMVia_t                        name;
  177.     enum StorageClassCode           typequal;
  178.     short                           isinline, ispascal;
  179.     *stor_class = 0;
  180.     done = 0;
  181.     typequal = 0;
  182.     isinline = 0;
  183.     ispascal = 0;
  184.     sc_count = 0;
  185.     qu_count = 0;
  186.  
  187.     result = 0;
  188.     while (!done) {
  189.     FetchToken();
  190.     switch (LastTokenKind) {
  191.     case AUTO:
  192.         /* This is valid only within in a function. */
  193.         if (!sc_legal) {
  194.         SyntaxError("Storage class specifier not allowed here");
  195.         }
  196.         sc_count++;
  197.         if (sc_count >= 2) {
  198.         SyntaxError("Too many storage class specifiers");
  199.         } else {
  200.         if (!FunctionBeingDefined) {
  201.             SyntaxError("auto may not appear outside of a function");
  202.         }
  203.         *stor_class = SCC_auto;
  204.         }
  205.  
  206.         break;
  207.     case VOID:
  208.         /* Done.  Nothing else is legal after this. */
  209.         result = BuildTypeRecord(0, TRC_void, SGN_unknown);
  210.         done = 1;
  211.         break;
  212.     case CHAR:
  213.         /* Done.  Nothing else is legal after this. */
  214.         if (gProject->itsOptions->signedChars) {
  215.         result = BuildTypeRecord(0, TRC_char, SGN_signed);
  216.         } else {
  217.         result = BuildTypeRecord(0, TRC_char, SGN_unsigned);
  218.         }
  219.         done = 1;
  220.         break;
  221.     case INT:
  222.         /* Done.  Nothing else is legal after this. */
  223.         result = BuildTypeRecord(0, TRC_int, SGN_signed);
  224.         done = 1;
  225.         break;
  226.     case STRUCT:
  227.         result = Do_struct_or_union_specifier(STRUCT);
  228.         done = 1;
  229.         break;
  230.     case TYPEDEF_NAME:
  231.         name = TableSearch(TP_defnames, (LastToken));
  232.         result = GetSymTP(name);
  233.         /*
  234.          * This means that the type returned is actually some other type,
  235.          * through a typedef.  In reality, this makes little difference,
  236.          * but was done to have more complete information.
  237.          */
  238.         SetTPFlags(result, GetTPFlags(result) | SIZEDONE);
  239. #ifdef Undefined
  240.         SetTypeSize(result);
  241. #endif
  242.         break;
  243.     case EXTERN:
  244.         if (!sc_legal) {
  245.         SyntaxError("Storage class specifier not allowed here");
  246.         }
  247.         sc_count++;
  248.         if (sc_count >= 2) {
  249.         SyntaxError("Too many storage class specifiers");
  250.         } else {
  251.         *stor_class = SCC_extern;
  252.         } break;
  253.     case REGISTER:
  254.         if (!sc_legal) {
  255.         SyntaxError("Storage class specifier not allowed here");
  256.         }
  257.         /* This is valid only within in a function. */
  258.         sc_count++;
  259.         if (sc_count >= 2) {
  260.         SyntaxError("Too many storage class specifiers");
  261.         } else {
  262.         if (!FunctionBeingDefined) {
  263.             SyntaxError("register may not appear outside of a function");
  264.         }
  265.         *stor_class = SCC_register;
  266.         } break;
  267.     case STATIC:
  268.         if (!sc_legal) {
  269.         SyntaxError("Storage class specifier not allowed here");
  270.         }
  271.         sc_count++;
  272.         if (sc_count >= 2) {
  273.         SyntaxError("Too many storage class specifiers");
  274.         } else {
  275.         *stor_class = SCC_static;
  276.         } break;
  277.     case PASCAL:
  278.         UserWarning(WARN_pascal);
  279.         ispascal = 1;
  280.         break;
  281.     case TYPEDEF:
  282.         if (!sc_legal) {
  283.         SyntaxError("typedef not allowed here");
  284.         }
  285.         sc_count++;
  286.         if (sc_count >= 2) {
  287.         SyntaxError("Too many storage class specifiers");
  288.         } else {
  289.         /* Special case... */
  290.         *stor_class = SCC_typedef;
  291.         } break;
  292.     case SHORT:
  293.         /*
  294.          * After this, only signed, unsigned, or int are legal, but none
  295.          * are required.
  296.          */
  297.         if (NextIs(SIGNED)) {
  298.         NextIs(INT);
  299.         result = BuildTypeRecord(0, TRC_short, SGN_signed);
  300.         done = 1;
  301.         } else if (NextIs(UNSIGNED)) {
  302.         NextIs(INT);
  303.         result = BuildTypeRecord(0, TRC_short, SGN_unsigned);
  304.         done = 1;
  305.         } else if (NextIs(INT)) {
  306.         result = BuildTypeRecord(0, TRC_short, SGN_signed);
  307.         done = 1;
  308.         } else {
  309.         result = BuildTypeRecord(0, TRC_short, SGN_signed);
  310.         done = 1;
  311.         } break;
  312.     case COMP:
  313.         /* Warning - non-ANSI keyword */
  314.         result = BuildTypeRecord(0, TRC_comp, SGN_signed);
  315.         done = 1;
  316.         break;
  317.     case EXTENDED:
  318.         /* Warning - non-ANSI keyword */
  319.         result = BuildTypeRecord(0, TRC_longdouble, SGN_unknown);
  320.         done = 1;
  321.         break;
  322.     case LONG:
  323.         /*
  324.          * After this, only signed, unsigned, double, or int are legal,
  325.          * but none are required.  Of these four, double may only appear
  326.          * if it is alone.
  327.          */
  328.         if (NextIs(DOUBLE)) {
  329.         result = BuildTypeRecord(0, TRC_longdouble, SGN_unknown);
  330.         done = 1;
  331.         } else if (NextIs(SIGNED)) {
  332.         NextIs(INT);
  333.         result = BuildTypeRecord(0, TRC_long, SGN_signed);
  334.         done = 1;
  335.         } else if (NextIs(UNSIGNED)) {
  336.         NextIs(INT);
  337.         result = BuildTypeRecord(0, TRC_long, SGN_unsigned);
  338.         done = 1;
  339.         } else if (NextIs(INT)) {
  340.         result = BuildTypeRecord(0, TRC_long, SGN_signed);
  341.         done = 1;
  342.         } else {
  343.         result = BuildTypeRecord(0, TRC_long, SGN_signed);
  344.         done = 1;
  345.         } break;
  346.     case FLOAT:
  347.         /* Done.  Nothing else is legal after this. */
  348.         result = BuildTypeRecord(0, TRC_float, SGN_unknown);
  349.         done = 1;
  350.         break;
  351.     case DOUBLE:
  352.         /* Done.  Nothing else is legal after this. */
  353.         result = BuildTypeRecord(0, TRC_double, SGN_unknown);
  354.         done = 1;
  355.         break;
  356.     case SIGNED:
  357.         /*
  358.          * After this, only char, short, long, or int are legal, but none
  359.          * are required.
  360.          */
  361.         if (NextIs(SHORT)) {
  362.         NextIs(INT);
  363.         result = BuildTypeRecord(0, TRC_short, SGN_signed);
  364.         done = 1;
  365.         } else if (NextIs(CHAR)) {
  366.         result = BuildTypeRecord(0, TRC_char, SGN_signed);
  367.         done = 1;
  368.         } else if (NextIs(LONG)) {
  369.         NextIs(INT);
  370.         result = BuildTypeRecord(0, TRC_long, SGN_signed);
  371.         done = 1;
  372.         } else if (NextIs(INT)) {
  373.         result = BuildTypeRecord(0, TRC_int, SGN_signed);
  374.         done = 1;
  375.         } else {
  376.         result = BuildTypeRecord(0, TRC_int, SGN_signed);
  377.         done = 1;
  378.         } break;
  379.     case UNSIGNED:
  380.         /*
  381.          * After this, only short, long, char, or int are legal, but none
  382.          * are required.
  383.          */
  384.         if (NextIs(SHORT)) {
  385.         NextIs(INT);
  386.         result = BuildTypeRecord(0, TRC_short, SGN_unsigned);
  387.         done = 1;
  388.         } else if (NextIs(CHAR)) {
  389.         result = BuildTypeRecord(0, TRC_char, SGN_unsigned);
  390.         done = 1;
  391.         } else if (NextIs(LONG)) {
  392.         NextIs(INT);
  393.         result = BuildTypeRecord(0, TRC_long, SGN_unsigned);
  394.         done = 1;
  395.         } else if (NextIs(INT)) {
  396.         result = BuildTypeRecord(0, TRC_int, SGN_unsigned);
  397.         done = 1;
  398.         } else {
  399.         result = BuildTypeRecord(0, TRC_int, SGN_unsigned);
  400.         done = 1;
  401.         } break;
  402.     case CONST:
  403.         qu_count++;
  404.         if (qu_count >= 2) {
  405.         SyntaxError("Too many type qualifiers");
  406.         } else {
  407.         typequal = SCC_const;
  408.         } break;
  409.     case VOLATILE:
  410.         qu_count++;
  411.         if (qu_count >= 2) {
  412.         SyntaxError("Too many type qualifiers");
  413.         } else {
  414.         UserWarning(WARN_novolatile);
  415.         typequal = SCC_volatile;
  416.         } break;
  417.     case UNION:
  418.         result = Do_struct_or_union_specifier(UNION);
  419.         done = 1;
  420.         break;
  421.     case ENUM:
  422.         result = Do_enum_specifier();
  423.         done = 1;
  424.         break;
  425.     default:
  426.         UnFetchToken();
  427.         done = 1;
  428.     }
  429.     }
  430.     if (typequal) {
  431.     TypeRecordVia_t                 other;
  432.     other = CopyTypeRecord(result);
  433.     SetTPQual(other, typequal);
  434.     result = other;
  435.     }
  436.     if (isinline) {
  437.     TypeRecordVia_t                 other;
  438.     other = CopyTypeRecord(result);
  439.     SetTPFlags(other, GetTPFlags(other) | ISINLINEMASK);
  440.     result = other;
  441.     }
  442.     if (ispascal) {
  443.     TypeRecordVia_t                 other;
  444.     other = CopyTypeRecord(result);
  445.     SetTPFlags(other, GetTPFlags(other) | ISPASCALMASK);
  446.     result = other;
  447.     }
  448.     *pascalFlag = ispascal;
  449.     return result;
  450. }
  451.  
  452. SymImageVia_t
  453. Do_init_declarator_list(SymListVia_t table, TypeRecordVia_t typerec,
  454.             enum StorageClassCode stor_class)
  455. {
  456.     /*
  457.      * init_declarator_list : init_declarator | init_declarator_list ','
  458.      * init_declarator ;
  459.      */
  460.  
  461.     SYMVia_t                        result;
  462.     SYMVia_t                        others;
  463.     int                             donelisting;
  464.     SymImageVia_t                   list;
  465.     list = NULL;
  466.     result = Do_init_declarator(table, typerec, stor_class);
  467.     if (result) {
  468.     list = ListAdd(list, result);
  469.     donelisting = 0;
  470.     while (!donelisting) {
  471.         if (NextIs(',')) {
  472.         others = Do_init_declarator(table, typerec, stor_class);
  473.         /* The symbol has been inserted into table. */
  474.         if (others) {
  475.             list = ListAdd(list, others);
  476.         } else {
  477.             SyntaxError("Expecting declarator");
  478.         }
  479.         } else {
  480.         donelisting = 1;
  481.         }
  482.     }
  483.     }
  484.     return list;
  485. }
  486.  
  487. SYMVia_t
  488. Do_init_declarator(SymListVia_t table, TypeRecordVia_t typerec,
  489.            enum StorageClassCode stor_class)
  490. {
  491.     /*
  492.      * init_declarator : declarator | declarator '=' initializer ;
  493.      */
  494.  
  495.     SYMVia_t                        SymbolRec;
  496.     TypeRecordVia_t                 newtype;
  497.     SymbolRec = Do_declarator(table, typerec, &newtype);
  498.     if (SymbolRec) {
  499.     Via(SymbolRec)->storage_class = stor_class;
  500.     if (NextIs('=')) {
  501.         Via(SymbolRec)->Definition.Initializer = Do_initializer();
  502.         if (!Via(SymbolRec)->Definition.Initializer) {
  503.         SyntaxError("Expecting initializer");
  504.         }
  505.     } else {
  506.         if (isArrayType(GetSymTP(SymbolRec))) {
  507.         if (isIncompleteType(GetTPBase(GetSymTP(SymbolRec)))) {
  508.             DeclError("Array of incomplete type");
  509.         }
  510.         }
  511.     }
  512.     }
  513.     return SymbolRec;
  514. }
  515.  
  516. TypeRecordVia_t
  517. Do_struct_or_union_specifier(Codigo_t keyword_code)
  518. {
  519.     /*
  520.      * struct_or_union_specifier : struct_or_union IDENTIFIER '{'
  521.      * struct_declaration_list '}' | struct_or_union '{'
  522.      * struct_declaration_list '}' | struct_or_union IDENTIFIER ;
  523.      */
  524.  
  525.     char                            TagName[200];
  526.     int                             tmp;
  527.     TypeRecordVia_t                 result;
  528.     SYMVia_t                        tagsym;
  529.     int                             prevNextStructOffset;
  530.     int                             prevCurFieldOffset;
  531.     int                             prevCurStructSize;
  532.     int                             prevCurFieldBit;
  533.     result = 0;
  534.     prevNextStructOffset = NextStructOffset;
  535.     prevCurFieldOffset = CurFieldOffset;
  536.     prevCurStructSize = CurStructSize;
  537.     prevCurFieldBit = CurFieldBit;
  538.     NextStructOffset = 0;
  539.     CurStructSize = 0;
  540.     CurFieldOffset = -1;
  541.     CurFieldBit = 0;
  542.  
  543.     if (keyword_code) {
  544.     if (GetIDENTIFIER()) {
  545.         strcpy(TagName, LastToken);
  546.         if (NextIs('{')) {
  547.         tagsym = LookUpTag(TagName);
  548.         if (tagsym) {
  549.             result = GetSymTP(tagsym);
  550.         } else {
  551.             if (keyword_code == STRUCT) {
  552.             result = BuildTagTypeRecord(0, TRC_struct, TagName);
  553.             } else {
  554.             result = BuildTagTypeRecord(0, TRC_union, TagName);
  555.             }
  556.             tagsym = TableAdd(CurrentTags(), TagName);
  557.             SetSymTP(tagsym, result);
  558.         }
  559.         if (GetTPMembers(result)) {
  560.             DeclError2("Redeclaration of struct tag ", TagName);
  561.         } else {
  562.             SetTPMembers(result, RawTable(11));
  563.         }
  564.         tmp = Do_struct_declaration_list(GetTPMembers(result));
  565.         if (!tmp) {
  566.             SyntaxError("Expecting struct declaration list");
  567.         }
  568.         if (CurStructSize % 2) {
  569.             CurStructSize++;
  570.         }
  571.         if (CurStructSize) {
  572.             SetTPSize(result, CurStructSize);
  573.         } else {
  574.             DeclError("No zero sized structs allowed");
  575.         }
  576.         if (keyword_code != STRUCT) {
  577.             SetTPSize(result, MaxSizes(GetTPMembers(result)));
  578.         }
  579.         if (!NextIs('}')) {
  580.             SyntaxError("Missing right brace");
  581.         }
  582.         } else {
  583.         if (NextIs(';')) {
  584.             PutBackToken(";", ';');
  585.             if (keyword_code == STRUCT) {
  586.             result = BuildTagTypeRecord(0, TRC_struct, TagName);
  587.             } else {
  588.             result = BuildTagTypeRecord(0, TRC_union, TagName);
  589.             }
  590.             tagsym = TableAdd(CurrentTags(), TagName);
  591.             SetSymTP(tagsym, result);
  592.         } else {
  593.             tagsym = LookUpTag(TagName);
  594.             if (tagsym) {
  595.             result = GetSymTP(tagsym);
  596.             } else {
  597.             if (keyword_code == STRUCT) {
  598.                 result = BuildTagTypeRecord(0, TRC_struct, TagName);
  599.             } else {
  600.                 result = BuildTagTypeRecord(0, TRC_union, TagName);
  601.             }
  602.             tagsym = TableAdd(CurrentTags(), TagName);
  603.             SetSymTP(tagsym, result);
  604.             }
  605.         }
  606.         }
  607.     } else if (NextIs('{')) {
  608.         if (keyword_code == STRUCT) {
  609.         result = BuildTagTypeRecord(0, TRC_struct, NULL);
  610.         } else {
  611.         result = BuildTagTypeRecord(0, TRC_union, NULL);
  612.         }
  613.         SetTPMembers(result, RawTable(11));
  614.         tmp = Do_struct_declaration_list(GetTPMembers(result));
  615.         if (CurStructSize % 2) {
  616.         CurStructSize++;
  617.         }
  618.         if (CurStructSize) {
  619.         SetTPSize(result, CurStructSize);
  620.         } else {
  621.         DeclError("No zero sized structs allowed");
  622.         }
  623.         if (!tmp) {
  624.         /*
  625.          * This is an error because empty structs are not allowed,
  626.          * are they ?
  627.          */
  628.         SyntaxError("Expecting struct declaration list");
  629.         }
  630.         if (keyword_code != STRUCT) {
  631.         SetTPSize(result, MaxSizes(GetTPMembers(result)));
  632.         }
  633.         if (!NextIs('}')) {
  634.         SyntaxError("Missing right brace");
  635.         }
  636.     } else {
  637.         SyntaxError("Expecting either tag or left brace");
  638.     }
  639.     } else {
  640.     result = 0;
  641.     }
  642.     NextStructOffset = prevNextStructOffset;
  643.     CurFieldOffset = prevCurFieldOffset;
  644.     CurStructSize = prevCurStructSize;
  645.     CurFieldBit = prevCurFieldBit;
  646.     return result;
  647. }
  648.  
  649. int
  650. Do_struct_declaration_list(SymListVia_t table)
  651. {
  652.     /*
  653.      * struct_declaration_list : struct_declaration | struct_declaration_list
  654.      * struct_declaration ;
  655.      */
  656.  
  657.     int                             notdone;
  658.     int                             one;
  659.     one = 0;
  660.     notdone = 1;
  661.     while (notdone) {
  662.     notdone = Do_struct_declaration(table);
  663.     if (notdone)
  664.         one++;
  665.     else {
  666.         notdone = NextIs(atPUBLIC);
  667.         if (notdone) {
  668.         /* Handle this TODO */
  669.         }
  670.     }
  671.     }
  672.     return one;
  673. }
  674.  
  675. int
  676. Do_struct_declaration(SymListVia_t table)
  677. {
  678.     /*
  679.      * struct_declaration : specifier_qualifier_list struct_declarator_list
  680.      * ';' ;
  681.      */
  682.  
  683.     int                             tmp;
  684.     enum StorageClassCode           nope;
  685.     TypeRecordVia_t                 typerec;
  686.     int junk;
  687.     tmp = 0;
  688.     typerec = Do_declaration_specifiers(0, &nope,&junk);    /* The 0 indicates that
  689.                              * storage class
  690.                              * specifiers are not
  691.                              * legal, thus making
  692.                              * this a specifier
  693.                              * qualifer list. */
  694.     if (typerec) {
  695.     tmp = Do_struct_declarator_list(table, typerec);
  696.     if (!tmp) {
  697.         SyntaxError("Expecting declarator");
  698.     }
  699.     if (!NextIs(';')) {
  700.         SyntaxError("Missing semicolon");
  701.     }
  702.     }
  703.     return tmp;
  704. }
  705.  
  706. int
  707. Do_struct_declarator_list(SymListVia_t table, TypeRecordVia_t typerec)
  708. {
  709.     /*
  710.      * struct_declarator_list : struct_declarator | struct_declarator_list
  711.      * ',' struct_declarator ;
  712.      */
  713.  
  714.     int                             result;
  715.     int                             donedecl;
  716.     result = Do_struct_declarator(table, typerec);
  717.     if (result) {
  718.     donedecl = 0;
  719.     while (!donedecl) {
  720.         if (NextIs(',')) {
  721.         result = Do_struct_declarator(table, typerec);
  722.         if (!result) {
  723.             SyntaxError("Expecting declarator");
  724.         }
  725.         } else {
  726.         donedecl = 1;
  727.         }
  728.     }
  729.     }
  730.     return result;
  731. }
  732.  
  733. int
  734. Do_struct_declarator(SymListVia_t table, TypeRecordVia_t typerec)
  735. {
  736.     /*
  737.      * struct_declarator : declarator | ':' constant_expr | declarator ':'
  738.      * constant_expr ;
  739.      */
  740.     /*
  741.      * The colons above are used to specify bit fields.
  742.      */
  743.  
  744.     SYMVia_t                        result;
  745.     ParseTreeVia_t                  tmp;
  746.     int                             funcres;
  747.     funcres = 0;
  748.     if (NextIs(':')) {
  749.     tmp = Do_constant_expr();
  750.     if (tmp) {
  751.         int                             constvalue;
  752.         constvalue = GetIntValue(tmp);
  753.         FreeTree(tmp);
  754.         funcres = 1;
  755.         if (constvalue) {
  756.         CurFieldBit += constvalue;
  757.         while (CurFieldBit >= BITFIELDUNIT) {
  758.             CurFieldBit -= BITFIELDUNIT;
  759.             NextStructOffset += BITFIELDUNIT / 8;
  760.         }
  761.         } else {
  762.         CurFieldBit = 0;
  763.         NextStructOffset += BITFIELDUNIT / 8;
  764.         }
  765.     } else {
  766.         SyntaxError("Expecting constant expression for bit field width");
  767.     }
  768.     } else {
  769.     TypeRecordVia_t                 newtype;
  770.     result = Do_declarator(table, typerec, &newtype);
  771.     if (result) {
  772.         funcres = 1;
  773.         if (NextIs(':')) {
  774.         tmp = Do_constant_expr();
  775.         if (tmp) {
  776.             int                             constvalue;
  777.             constvalue = GetIntValue(tmp);
  778.             FreeTree(tmp);
  779.             funcres = 1;
  780.             if (constvalue) {
  781.             /* Modify result to represent a bit field. */
  782.             int                             bitstart, bitend;
  783.             if (constvalue > BITFIELDUNIT) {
  784.                 DeclError("A field cannot be that wide.");
  785.             }
  786.             if (CurFieldOffset != -1) {
  787.                 /*
  788.                  * Here, we are already in the middle of a field.
  789.                  * We may not need to increase the struct size.
  790.                  */
  791.                 if (CurFieldBit + constvalue >= BITFIELDUNIT) {
  792.                 CurFieldOffset = NextStructOffset;
  793.                 NextStructOffset += BITFIELDUNIT / 8;
  794.                 bitstart = 0;
  795.                 bitend = constvalue - 1;
  796.                 CurStructSize += BITFIELDUNIT / 8;
  797.                 CurFieldBit = constvalue;
  798.                 } else {
  799.                 bitstart = CurFieldBit;
  800.                 CurFieldBit += constvalue;
  801.                 bitend = CurFieldBit - 1;
  802.                 }
  803.             } else {
  804.                 CurFieldOffset = NextStructOffset;
  805.                 NextStructOffset += BITFIELDUNIT / 8;
  806.                 bitstart = 0;
  807.                 bitend = constvalue - 1;
  808.                 CurStructSize += BITFIELDUNIT / 8;
  809.                 CurFieldBit = constvalue;
  810.             }
  811.             Via(result)->Definition.StartEndBits.StartBit = bitstart;
  812.             Via(result)->Definition.StartEndBits.EndBit = bitend;
  813.             SetSymTP(result, BuildTypeRecord(Via(result)->TP, TRC_bitfield, GetTPSign(Via(result)->TP)));
  814.             Via(result)->numbers.structoffset = CurFieldOffset;
  815.             } else {
  816.             /* Should we issue a warning ? */
  817.             CurFieldBit = 0;
  818.             NextStructOffset += BITFIELDUNIT / 8;
  819.             Via(result)->TP = BuildTypeRecord(Via(result)->TP, TRC_bitfield, GetTPSign(Via(result)->TP));
  820.             Via(result)->numbers.structoffset = CurFieldOffset;
  821.             Via(result)->Definition.StartEndBits.StartBit = 0;
  822.             Via(result)->Definition.StartEndBits.EndBit = 0;
  823.             }
  824.         } else {
  825.             SyntaxError("Expecting constant expression for bit field width");
  826.         }
  827.         } else {
  828.         /*
  829.          * Here we calculate the offset of the member, and update the
  830.          * struct size.
  831.          */
  832.         CurFieldBit = 0;
  833.         CurFieldOffset = -1;
  834.         if (isIncompleteType(Via(result)->TP)) {
  835.             DeclError("Struct member with incomplete type");
  836.         }
  837.         if (isCharType(Via(result)->TP)) {
  838.             Via(result)->numbers.structoffset = NextStructOffset++;
  839.             CurStructSize++;
  840.         } else {
  841.             if (NextStructOffset % 2) {
  842.             NextStructOffset++;
  843.             CurStructSize++;
  844.             }
  845.             Via(result)->numbers.structoffset = NextStructOffset;
  846.             NextStructOffset += GetTPSize(Via(result)->TP);
  847.             CurStructSize += GetTPSize(Via(result)->TP);
  848.         }
  849.         }
  850.     }
  851.     }
  852.     return funcres;
  853. }
  854.  
  855. TypeRecordVia_t
  856. Do_enum_specifier(void)
  857. {
  858.     /*
  859.      * enum_specifier : ENUM '{' enumerator_list '}' | ENUM IDENTIFIER '{'
  860.      * enumerator_list '}' | ENUM IDENTIFIER ;
  861.      */
  862.  
  863.     TypeRecordVia_t                 result;
  864.     SYMVia_t                        tagsym;
  865.     int                             tmp;
  866.     char                            holdid[64];
  867.     int                             wasid = 0;
  868.     wasid = 0;
  869.     result = 0;
  870.     tagsym = 0;
  871.     if (NextIs(IDENTIFIER)) {
  872.     strcpy(holdid, LastToken);
  873.     wasid = 1;
  874.     tagsym = LookUpTag(holdid);
  875.     if (tagsym) {
  876.         result = Via(tagsym)->TP;
  877.     } else {
  878.         result = BuildTagTypeRecord(0, TRC_enum, holdid);
  879.         SetTPMembers(result, RawTable(53));
  880.         EnumBeingDeclared = result;
  881.         if (gProject->itsOptions->int2byte)
  882.         SetTPSize(EnumBeingDeclared, 2);
  883.         else
  884.         SetTPSize(EnumBeingDeclared, 4);
  885.         CurrentEnumK = 0;
  886.         tagsym = TableAdd(CurrentTags(), holdid);
  887.         Via(tagsym)->TP = result;
  888.     }
  889.     } else {
  890.     result = BuildTagTypeRecord(0, TRC_enum, holdid);
  891.     SetTPMembers(result, RawTable(53));
  892.     EnumBeingDeclared = result;
  893.     if (gProject->itsOptions->int2byte)
  894.         SetTPSize(EnumBeingDeclared, 2);
  895.     else
  896.         SetTPSize(EnumBeingDeclared, 4);
  897.     CurrentEnumK = 0;
  898.     }
  899.     if (NextIs('{')) {
  900.     PushEnumTable(GetTPMembers(result));
  901.     tmp = Do_enumerator_list();
  902.     if (!tmp) {
  903.         SyntaxError("Expecting enumerator list");
  904.     }
  905.     if (!NextIs('}')) {
  906.         SyntaxError("Missing right brace");
  907.     }
  908.     } else {
  909.     if (!wasid) {
  910.         SyntaxError("Expected either tag or left brace");
  911.     }
  912.     }
  913.     return result;
  914. }
  915.  
  916. int
  917. Do_enumerator_list(void)
  918. {
  919.     /*
  920.      * enumerator_list : enumerator | enumerator_list ',' enumerator ;
  921.      */
  922.  
  923.     int                             result;
  924.     int                             doneenumerating;
  925.     result = Do_enumerator();
  926.     if (result) {
  927.     doneenumerating = 0;
  928.     while (!doneenumerating) {
  929.         if (NextIs(',')) {
  930.         result = Do_enumerator();
  931.         if (!result) {
  932.             /*
  933.              * Note that this fragment allows an enumerator list to
  934.              * end in a comma.  I don't know if this should be this
  935.              * way or not.
  936.              */
  937.             doneenumerating = 1;
  938.             result = 1;
  939.         }
  940.         } else {
  941.         doneenumerating = 1;
  942.         }
  943.     }
  944.     }
  945.     return result;
  946. }
  947.  
  948. int
  949. Do_enumerator(void)
  950. {
  951.     /*
  952.      * enumerator : IDENTIFIER | IDENTIFIER '=' constant_expr ;
  953.      */
  954.  
  955.     int                             result;
  956.     ParseTreeVia_t                  exprtree;
  957.     SYMVia_t                        enumerator;
  958.     enumerator = 0;
  959.     if (NextIs(IDENTIFIER)) {
  960.     if ((enumerator = LookUpSymbol(LastToken)) != 0) {
  961.         DeclErrorSYM("enum constant has previous definition", enumerator);
  962.     }
  963.     enumerator = TableAdd(CurrentEnums(), (LastToken));
  964.     Via(enumerator)->TP = EnumBeingDeclared;
  965.     Via(enumerator)->storage_class = SCC_enum;
  966.     Via(enumerator)->numbers.EnumVal = CurrentEnumK++;
  967.     if (!EnumBeingDeclared) {
  968.         VeryBadParseError("EnumBeingDeclared == NULL in Do_enumerator");
  969.     }
  970.     result = 1;
  971.     if (NextIs('=')) {
  972.         int                             constvalue;
  973.         constvalue = 1;
  974.         exprtree = Do_constant_expr();
  975.         if (!exprtree) {
  976.         SyntaxError("Expected constant expression for enum initializer");
  977.         result = 0;
  978.         } else {
  979.         constvalue = GetIntValue(exprtree);
  980.         FreeTree(exprtree);
  981.         Via(enumerator)->numbers.EnumVal = CurrentEnumK = constvalue;
  982.         CurrentEnumK++;
  983.         }
  984.     }
  985.     } else {
  986.     result = 0;
  987.     }
  988.     return result;
  989. }
  990.  
  991. SYMVia_t
  992. Do_declarator(SymListVia_t table, TypeRecordVia_t typerec, TypeRecordVia_t * newtype)
  993. {
  994.     /*
  995.      * declarator : direct_declarator | pointer direct_declarator ;
  996.      */
  997.  
  998.     TypeRecordVia_t                 result;
  999.     SYMVia_t                        tmp;
  1000.     result = Do_pointer(typerec);
  1001.     if (newtype)
  1002.     *newtype = result;
  1003.     tmp = Do_direct_declarator(table, result);
  1004.     return tmp;
  1005. }
  1006.  
  1007. void
  1008. RecurseSetSize(TypeRecordVia_t TP)
  1009. {
  1010.     if (TP) {
  1011.     if (GetTPFlags(TP) & SIZEDONE)
  1012.         return;
  1013.     if (GetTPKind(TP) == TRC_array) {
  1014.         if (isArrayType(GetTPBase(TP))) {
  1015.         RecurseSetSize(GetTPBase(TP));
  1016.         }
  1017.         SetTPSize(TP, GetTPSize(TP) * GetTPSize(GetTPBase(TP)));
  1018.         SetTPFlags(TP, GetTPFlags(TP) | SIZEDONE);
  1019.     } else if (GetTPKind(TP) == TRC_typedef) {
  1020.         RecurseSetSize(GetTPBase(TP));
  1021.         SetTPSize(TP, GetTPSize(GetTPBase(TP)));
  1022.         SetTPFlags(TP, GetTPFlags(TP) | SIZEDONE);
  1023.     }
  1024.     }
  1025. }
  1026.  
  1027. void
  1028. SetArraySizes(TypeRecordVia_t TP)
  1029. {
  1030.     if (GetTPKind(TP) == TRC_typedef) {
  1031.     SetArraySizes(GetTPBase(TP));
  1032.     SetTPSize(TP, GetTPSize(GetTPBase(TP)));
  1033.     } else {
  1034.     assert(GetTPKind(TP) == TRC_array);
  1035.     if (isArrayType(GetTPBase(TP))) {
  1036.         int                             stack[MAXARRAYDIMS];
  1037.         int                             sp;
  1038.         TypeRecordVia_t                 tp2;
  1039.         sp = 0;
  1040.         tp2 = TP;
  1041.  
  1042.         while (isArrayType(tp2)) {
  1043.         if (GetTPFlags(tp2) & SIZEDONE)
  1044.             break;
  1045.         if (GetTPKind(tp2) == TRC_array) {
  1046.             stack[sp++] = GetTPSize(tp2);
  1047.         }
  1048.         tp2 = GetTPBase(tp2);
  1049.         }
  1050.         tp2 = TP;
  1051.  
  1052.         while (isArrayType(tp2)) {
  1053.         if (GetTPFlags(tp2) & SIZEDONE)
  1054.             break;
  1055.         if (GetTPKind(tp2) == TRC_array) {
  1056.             SetTPSize(tp2, stack[--sp]);
  1057.         }
  1058.         tp2 = GetTPBase(tp2);
  1059.         }
  1060.         RecurseSetSize(TP);
  1061.     } else {
  1062.         if (GetTPFlags(TP) & SIZEDONE)
  1063.         return;
  1064.         SetTPSize(TP, GetTPSize(TP) * GetTPSize(GetTPBase(TP)));
  1065.         SetTPFlags(TP, GetTPFlags(TP) | SIZEDONE);
  1066.     }
  1067.     }
  1068. }
  1069.  
  1070. SYMVia_t                        FirstSym(SymListVia_t tbl);
  1071.  
  1072. SYMVia_t
  1073. Do_direct_declarator(SymListVia_t table, TypeRecordVia_t typerec)
  1074. {
  1075.     /*
  1076.      * direct_declarator : IDENTIFIER | '(' declarator ')' |
  1077.      * direct_declarator '[' ']' | direct_declarator '[' constant_expr ']' |
  1078.      * direct_declarator '(' ')' | direct_declarator '(' parameter_type_list
  1079.      * ')' | direct_declarator '(' identifier_list ')' ;
  1080.      */
  1081.  
  1082.     SYMVia_t                        result;
  1083.     int                             donedirecting;
  1084.     TypeRecordVia_t                 already;
  1085.     int                             OldNoArgs;
  1086.     int                             redefTypedef;
  1087.     TypeRecordVia_t                 newtype = 0;
  1088.     TypeRecordVia_t                 oldtype = 0;
  1089.     OldNoArgs = 0;
  1090.     result = 0;
  1091.     already = 0;
  1092.     if ((redefTypedef = GetIDENTIFIER()) != 0) {
  1093.     /*
  1094.      * We add id to table now, keeping the result for later changes.
  1095.      */
  1096.     /*
  1097.      * Check here to see if the token already exists.  If so, check that
  1098.      * the types are the same.
  1099.      */
  1100.     CurrentSRC.CountIdentifiers++;
  1101.     CurrentSRC.TotalIdentifierLength += strlen(LastToken);
  1102.     if (redefTypedef == 2) {
  1103.         if (!FunctionBeingDefined) {
  1104.         DeclError("redefinition of typedef names at global scope not allowed");
  1105.         }
  1106.     }
  1107.     result = TableSearch(table, (LastToken));
  1108.     if (result) {
  1109.         already = Via(result)->TP;
  1110.         Via(result)->TP = typerec;
  1111.     } else {
  1112.         result = TableAdd(table, (LastToken));
  1113.         Via(result)->storage_class = SCC_auto;    /* QQQQ WHy ? */
  1114.         /*
  1115.          * QQQQ Here, is table == Via(Via(CurrentBlock)->block)->Symbols
  1116.          * ?
  1117.          */
  1118.         Via(result)->TP = typerec;
  1119.     }
  1120.     } else if (NextIs('(')) {
  1121.     result = Do_declarator(table, 0, &newtype);
  1122.     newtype = Via(result)->TP;
  1123.     if (result) {
  1124.         newtype = Via(result)->TP;
  1125.         Via(result)->TP = oldtype = typerec;
  1126.         if (!NextIs(')')) {
  1127.         SyntaxError("Missing right parenthesis");
  1128.         }
  1129.     } else {
  1130.         SyntaxError("Expected declarator");
  1131.     }
  1132.     } else {
  1133.     result = 0;
  1134.     }
  1135.  
  1136.     if (result) {
  1137.     donedirecting = 0;
  1138.     while (!donedirecting) {
  1139.         if (NextIs('[')) {
  1140.         if (NextIs(']')) {
  1141.             Via(result)->TP = BuildTypeRecord(Via(result)->TP, TRC_array, SGN_unknown);
  1142.             SetTPFlags(Via(result)->TP, GetTPFlags(Via(result)->TP) | INCOMPLETEMASK);
  1143.             SetTPFlags(Via(result)->TP, GetTPFlags(Via(result)->TP) & (!SIZEDONE));
  1144.             SetTPSize(Via(result)->TP, 0);
  1145.             /*
  1146.              * Generally, when a typerecord is an array, the typesize
  1147.              * field indicates the size of the array in bytes.
  1148.              */
  1149.             /*
  1150.              * The type of an object of incomplete type is completed
  1151.              * by another, complete, declaration for the object
  1152.              * (A10.2), or by initializing it (A8.7). - K&R ][,
  1153.              * A8.6.2
  1154.              */
  1155.         } else {
  1156.             ParseTreeVia_t                  tmp;
  1157.             int                             constantvalue;
  1158.             tmp = Do_constant_expr();
  1159.             if (tmp) {
  1160.             constantvalue = GetIntValue(tmp);
  1161.             FreeTree(tmp);
  1162.             Via(result)->TP = BuildTypeRecord(Via(result)->TP, TRC_array, SGN_unknown);
  1163.             SetTPFlags(Via(result)->TP, GetTPFlags(Via(result)->TP) & (!SIZEDONE));
  1164.             SetTPSize(Via(result)->TP, constantvalue);
  1165.             /* This will be fixed later... */
  1166.             if (!NextIs(']')) {
  1167.                 SyntaxError("Expected right bracket");
  1168.             }
  1169.             } else {
  1170.             SyntaxError("Expected constant expr for array size");
  1171.             }
  1172.         }
  1173.         } else if (NextIs('(')) {
  1174.         if (NextIs(')')) {
  1175.             if (gProject->itsOptions->requireProtos) {
  1176.             TypeError("Prototypes required");
  1177.             }
  1178.             Via(result)->TP = BuildTypeRecord(Via(result)->TP, TRC_OLDfunction, SGN_unknown);
  1179.             SetTPMembers(Via(result)->TP, RawTable(11));
  1180.             OldNoArgs = 1;
  1181.             /*
  1182.              * ALL functions are either ANSI or not.  If ANSI, then
  1183.              * args are type checked.  If not, args are not type
  1184.              * checked, but promoted according to specific rules.
  1185.              * NOARGS is simply a special case of ANSI, and
  1186.              * INCOMPLETE is treated as old style.
  1187.              */
  1188.         } else {
  1189.             int                             listresult;
  1190.             SymListVia_t                    templist, tagslist,
  1191.                                             lablist;
  1192.             templist = RawTable(11);
  1193.             tagslist = RawTable(11);
  1194.             lablist = RawTable(11);
  1195.             PushSpaces(templist, tagslist, lablist);
  1196.             listresult = Do_parameter_type_list(templist);    /* A proto */
  1197.             PopBlock();
  1198.             if (Via(tagslist)->count) {
  1199.             UserMesgCR("Tag(s) in proto being lost");
  1200.             }
  1201.             FreeSymbolList(tagslist, 0);
  1202.             FreeSymbolList(lablist, 0);
  1203.             /*
  1204.              * Perhaps we should check
  1205.              * Via(Via(CurrentBlock)->block)->Tags to see if some
  1206.              * struct/enum declaration is getting lost.
  1207.              */
  1208.             if (listresult) {
  1209.             /*
  1210.              * If the parameter type list is simply void, then
  1211.              * this should really be a noargs function.
  1212.              */
  1213.             enum TypeRecordCode             FuncTRC;
  1214.             FuncTRC = TRC_ANSIfunction;
  1215.             if (listresult == ELLIPSIS) {
  1216.                 FuncTRC = TRC_ANSIELLIPSISfunction;
  1217.             } else if (Via(templist)->count == 1) {
  1218.                 if (isVoidType(Via(FirstSym(templist))->TP)) {
  1219.                 FuncTRC = TRC_NOARGSfunction;
  1220.                 }
  1221.             }
  1222.             /*
  1223.              * Also, this parameter type list must have valid
  1224.              * declarators within it, if this is a function
  1225.              * definition and not merely a prototype.  Also, if
  1226.              * this is a function definition, the parameter type
  1227.              * list symbol table should be entered into current
  1228.              * scope.
  1229.              * 
  1230.              */
  1231.             Via(result)->TP = BuildTypeRecord(Via(result)->TP, FuncTRC, SGN_unknown);
  1232.             SetTPMembers(Via(result)->TP, templist);
  1233.             if (!NextIs(')')) {
  1234.                 SyntaxError("Missing right parenthesis");
  1235.             }
  1236.             } else {
  1237.             templist = RawTable(11);
  1238.             listresult = Do_identifier_list(templist);
  1239.             /*
  1240.              * QQQQ Shouldn't this be identifier list with
  1241.              * ellipsis ?
  1242.              */
  1243.             if (listresult) {
  1244.                 if (gProject->itsOptions->requireProtos) {
  1245.                 TypeError("Prototypes required");
  1246.                 }
  1247.                 Via(result)->TP = BuildTypeRecord(Via(result)->TP, TRC_OLDfunction, SGN_unknown);
  1248.                 SetTPMembers(Via(result)->TP, templist);
  1249.                 if (!NextIs(')')) {
  1250.                 SyntaxError("Missing right parenthesis");
  1251.                 }
  1252.             } else {
  1253.                 SyntaxError("Expecting identifier list or prototype");
  1254.             }
  1255.             }
  1256.         }
  1257.         } else {
  1258.         donedirecting = 1;
  1259.         }
  1260.     }
  1261.     if (isArrayType(Via(result)->TP)) {
  1262.         SetArraySizes(Via(result)->TP);
  1263.     }
  1264.     }
  1265.     if (oldtype && newtype && result) {
  1266.     TypeRecordVia_t                 curtype;
  1267.     curtype = newtype;
  1268.     while (GetTPBase(curtype)) {
  1269.         curtype = GetTPBase(curtype);
  1270.     }
  1271.     SetTPBase(curtype, Via(result)->TP);
  1272.     Via(result)->TP = newtype;
  1273.     }
  1274.     if (already) {
  1275.     int                             preapproved;
  1276.     preapproved = 0;
  1277.     if (!SameType(already, Via(result)->TP)) {
  1278.         if (isFunctionType(already)) {
  1279.         if (isFunctionType(Via(result)->TP)) {
  1280.             if (GetTPKind(already) == TRC_OLDfunction) {
  1281.             if (!CountFuncArgs(already)) {
  1282.                 preapproved = 1;
  1283.             }
  1284.             }
  1285.             if (GetTPKind(Via(result)->TP) == TRC_OLDfunction) {
  1286.             if (!CountFuncArgs(Via(result)->TP)) {
  1287.                 preapproved = 1;
  1288.             }
  1289.             }
  1290.             if (!preapproved) {
  1291.             switch (GetTPKind(already)) {
  1292.             case TRC_OLDfunction:
  1293.                 switch (GetTPKind(Via(result)->TP)) {
  1294.                 case TRC_ANSIfunction:
  1295.                 if (!SameType(isFunctionType(already), isFunctionType(Via(result)->TP))) {
  1296.                     DeclErrorSYM("Conflicting function redeclaration of ", result);
  1297.                 }
  1298.                 break;
  1299.                 case TRC_NOARGSfunction:
  1300.                 if (CountFuncArgs(already)) {
  1301.                     DeclErrorSYM("Conflicting function redeclaration of ", result);
  1302.                 }
  1303.                 break;
  1304.                 default:
  1305.                 DeclErrorSYM("Conflicting function redeclaration of ", result);
  1306.                 break;
  1307.                 }
  1308.                 break;
  1309.             case TRC_ANSIfunction:
  1310.                 switch (GetTPKind(Via(result)->TP)) {
  1311.                 case TRC_OLDfunction:
  1312.                 if (!SameType(isFunctionType(already), isFunctionType(Via(result)->TP))) {
  1313.                     DeclErrorSYM("Conflicting function redeclaration of ", result);
  1314.                 }
  1315.                 if (Via(GetTPMembers(already))->count !=
  1316.                 Via(GetTPMembers(Via(result)->TP))->count) {
  1317.                     DeclErrorSYM("Conflicting function redeclaration of ", result);
  1318.                 }
  1319.                 /*
  1320.                  * QQQQ Here, should we set Via(result)->TP
  1321.                  * to already ?
  1322.                  */
  1323.                 /*
  1324.                  * We can't check further because the old
  1325.                  * style declaration list has not been read.
  1326.                  * This level of checking will occur in
  1327.                  * Do_function_body(void)
  1328.                  */
  1329.                 break;
  1330.                 default:
  1331.                 DeclErrorSYM("Conflicting function redeclaration of ", result);
  1332.                 break;
  1333.                 }
  1334.                 break;
  1335.             case TRC_NOARGSfunction:
  1336.                 if (!((GetTPKind(Via(result)->TP) == TRC_OLDfunction) && (OldNoArgs))) {
  1337.                 DeclErrorSYM("Conflicting function redeclaration of ", result);
  1338.                 }
  1339.                 break;
  1340.             default:
  1341.                 DeclErrorSYM("Conflicting function redeclaration of ", result);
  1342.                 break;
  1343.             }
  1344.             }
  1345.         } else {
  1346.             DeclErrorSYM("Conflicting function redeclaration of ", result);
  1347.         }
  1348.         } else if (isIncompleteType(already)) {
  1349.         /*
  1350.          * TODO Do something here.
  1351.          */
  1352.         } else {
  1353.         DeclErrorSYM("Conflicting redeclaration of ", result);
  1354.         }
  1355.     }
  1356.     }
  1357.     return result;
  1358. }
  1359.  
  1360. TypeRecordVia_t
  1361. Do_pointer(TypeRecordVia_t base)
  1362. {
  1363.     /*
  1364.      * pointer : '*' | '*' type_qualifier_list | '*' pointer | '*'
  1365.      * type_qualifier_list pointer ;
  1366.      */
  1367.  
  1368.     /*
  1369.      * This routine is only called from within do_declarator and
  1370.      * do_abstract_declarator.  The information in it is only used to
  1371.      * modify/construct type records.
  1372.      */
  1373.  
  1374.     TypeRecordVia_t                 result;
  1375.     int                             done;
  1376.     result = base;
  1377.     if (NextIs('*')) {
  1378.     result = BuildTypeRecord(result, TRC_pointer, SGN_unknown);
  1379.     done = 0;
  1380.     while (!done) {
  1381.         if (NextIs(CONST)) {
  1382.         TypeRecordVia_t                 other;
  1383.         other = CopyTypeRecord(result);
  1384.         SetTPQual(other, SCC_const);
  1385.         result = other;
  1386.         } else if (NextIs(VOLATILE)) {
  1387.         TypeRecordVia_t                 other;
  1388.         other = CopyTypeRecord(result);
  1389.         SetTPQual(other, SCC_volatile);
  1390.         result = other;
  1391.         UserWarning(WARN_novolatile);
  1392.         } else if (NextIs('*')) {
  1393.         result = BuildTypeRecord(result, TRC_pointer, SGN_unknown);
  1394.         } else {
  1395.         done = 1;
  1396.         }
  1397.     }
  1398.     }
  1399.     return result;
  1400. }
  1401.  
  1402. int
  1403. Do_parameter_identifier_list(SymListVia_t table)
  1404. /* What happened to this function ?!  It's not used anywhere ? */
  1405. {
  1406.     /*
  1407.      * parameter_identifier_list : identifier_list | identifier_list ','
  1408.      * ELLIPSIS ;
  1409.      */
  1410.  
  1411.     int                             result;
  1412.     result = Do_identifier_list(table);
  1413.     if (result) {
  1414.     if (result == ELLIPSIS) {
  1415.         /*
  1416.          * TODO What here ?  Modify table to indicate a vararg function ?
  1417.          */
  1418.     }
  1419.     }
  1420.     return result;
  1421. }
  1422.  
  1423. int
  1424. Do_identifier_list(SymListVia_t table)
  1425. {
  1426.     /*
  1427.      * identifier_list : IDENTIFIER | identifier_list ',' IDENTIFIER ;
  1428.      */
  1429.  
  1430.     int                             result = 0;
  1431.     int                             donelisting;
  1432.     if (NextIs(IDENTIFIER)) {
  1433.     donelisting = 0;
  1434.     result = 1;
  1435.     TableAdd(table, (LastToken));
  1436.     while (!donelisting) {
  1437.         if (NextIs(',')) {
  1438.         if (NextIs(IDENTIFIER)) {
  1439.             TableAdd(table, (LastToken));
  1440.         } else {
  1441.             if (NextIs(ELLIPSIS)) {
  1442.             result = ELLIPSIS;
  1443.             } else {
  1444.             SyntaxError("Extra comma");
  1445.             }
  1446.             donelisting = 1;
  1447.         }
  1448.         } else {
  1449.         donelisting = 1;
  1450.         }
  1451.     }
  1452.     } else {
  1453.     result = 0;
  1454.     }
  1455.     return result;
  1456. }
  1457.  
  1458. int
  1459. Do_parameter_type_list(SymListVia_t table)
  1460. {
  1461.     /*
  1462.      * parameter_type_list : parameter_list | parameter_list ',' ELLIPSIS ;
  1463.      */
  1464.  
  1465.     /* Note that the ELLIPSIS is now handled in Do_parameter_list() */
  1466.     int                             result;
  1467.     result = Do_parameter_list(table);
  1468.     if (result) {
  1469.     if (result == ELLIPSIS) {
  1470.         /*
  1471.          * TODO What here ?  Modify table to indiciate proto with vararg
  1472.          * ?
  1473.          */
  1474.     }
  1475.     }
  1476.     return result;
  1477. }
  1478.  
  1479. int
  1480. Do_parameter_list(SymListVia_t table)
  1481. {
  1482.     /*
  1483.      * parameter_list : parameter_declaration | parameter_list ','
  1484.      * parameter_declaration ;
  1485.      */
  1486.  
  1487.     int                             result;
  1488.     int                             donelisting;
  1489.     result = Do_parameter_declaration(table);
  1490.     if (result) {
  1491.     result = 1;
  1492.     donelisting = 0;
  1493.     while (!donelisting) {
  1494.         if (NextIs(',')) {
  1495.         int                             tmp;
  1496.         tmp = Do_parameter_declaration(table);
  1497.         if (!tmp) {
  1498.             if (NextIs(ELLIPSIS)) {
  1499.             result = ELLIPSIS;
  1500.             } else {
  1501.             SyntaxError("Extra comma");
  1502.             }
  1503.             donelisting = 1;
  1504.         }
  1505.         } else {
  1506.         donelisting = 1;
  1507.         }
  1508.     }
  1509.     }
  1510.     return result;
  1511. }
  1512.  
  1513. int
  1514. Do_parameter_declaration(SymListVia_t table)
  1515. {
  1516.     /*
  1517.      * parameter_declaration : declaration_specifiers declarator |
  1518.      * declaration_specifiers abstract_declarator | declaration_specifiers ;
  1519.      */
  1520.  
  1521.     int                             result;
  1522.     enum StorageClassCode           stor_class;
  1523.     TypeRecordVia_t                 typerec;
  1524.     SYMVia_t                        tmp;
  1525.     int junk;
  1526.     tmp = 0;
  1527.     result = 0;
  1528.     typerec = Do_declaration_specifiers(1, &stor_class, &junk);
  1529.     /*
  1530.      * QQQQ Is a storage class really legal here, or just const/volatile ?
  1531.      */
  1532.     if (typerec) {
  1533.     TypeRecordVia_t                 newtype;
  1534.     result = 1;
  1535.     newtype = 0;
  1536.     tmp = Do_declarator(table, typerec, &newtype);
  1537.     if (!tmp) {
  1538.         /*
  1539.          * In this case, we need to insert a fake name (which we can
  1540.          * recognize as fake later !) because the type STILL must go into
  1541.          * the symbol table.  This is a proto we are parsing.
  1542.          */
  1543.         SYMVia_t                        fake;
  1544.         fake = TableAdd(table, ("-fake-"));
  1545.         newtype = Do_abstract_declarator(newtype);
  1546.         Via(fake)->TP = newtype;
  1547.         tmp = fake;
  1548.     }
  1549.     }
  1550.     if (tmp) {
  1551.     if (isArrayType(Via(tmp)->TP)) {
  1552.         Via(tmp)->TP =
  1553.         BuildTypeRecord(isArrayType(Via(tmp)->TP), TRC_pointer, SGN_unknown);
  1554.     }
  1555.     if (isFunctionType(Via(tmp)->TP)) {
  1556.         Via(tmp)->TP = BuildTypeRecord(Via(tmp)->TP, TRC_pointer, SGN_unknown);
  1557.     }
  1558.     }
  1559.     return result;
  1560. }
  1561.  
  1562. TypeRecordVia_t
  1563. Do_type_name(void)
  1564. {
  1565.     /*
  1566.      * type_name : specifier_qualifier_list | specifier_qualifier_list
  1567.      * abstract_declarator ;
  1568.      */
  1569.     /*
  1570.      * This routine is called for type casts.  It should return a type
  1571.      * record.  Abstract declarators are declarators which do not go into the
  1572.      * symbol table, therefore no table is needed here.  The
  1573.      * abstract_declarator routines only modify the type record they receive.
  1574.      */
  1575.     TypeRecordVia_t                 result;
  1576.     enum StorageClassCode           nope;
  1577.     int junk;
  1578.     result = Do_declaration_specifiers(0, &nope, &junk);
  1579.     if (result) {
  1580.     result = Do_abstract_declarator(result);
  1581.     }
  1582.     return result;
  1583. }
  1584.  
  1585. TypeRecordVia_t
  1586. Do_abstract_declarator(TypeRecordVia_t typerec)
  1587. {
  1588.     /*
  1589.      * abstract_declarator : pointer | direct_abstract_declarator | pointer
  1590.      * direct_abstract_declarator ;
  1591.      */
  1592.     /*
  1593.      * This routine is only called for parameter type lists (for protos) and
  1594.      * type casts...
  1595.      */
  1596.  
  1597.     typerec = Do_pointer(typerec);
  1598.     typerec = Do_direct_abstract_declarator(typerec);
  1599.     return typerec;
  1600. }
  1601.  
  1602. TypeRecordVia_t
  1603. Do_direct_abstract_declarator(TypeRecordVia_t typerec)
  1604. {
  1605.     /*
  1606.      * direct_abstract_declarator : '(' abstract_declarator ')' | '[' ']' |
  1607.      * '[' constant_expr ']' | direct_abstract_declarator '[' ']' |
  1608.      * direct_abstract_declarator '[' constant_expr ']' | '(' ')' | '('
  1609.      * parameter_type_list ')' | direct_abstract_declarator '(' ')' |
  1610.      * direct_abstract_declarator '(' parameter_type_list ')' ;
  1611.      */
  1612.  
  1613.     int                             result;
  1614.     ParseTreeVia_t                  tmp;
  1615.     int                             donedecl;
  1616.     result = 0;
  1617.     if (NextIs('(')) {
  1618.     result = 1;
  1619.     if (NextIs(')')) {
  1620.         typerec = BuildTypeRecord(typerec, TRC_OLDfunction, SGN_unknown);
  1621.     } else {
  1622.         typerec = Do_abstract_declarator(typerec);
  1623.         if (typerec) {
  1624.         if (!NextIs(')')) {
  1625.             SyntaxError("Missing right parenthesis");
  1626.         }
  1627.         } else {
  1628.         SyntaxError("Expected abstract declarator");
  1629.         }
  1630.     }
  1631.     } else if (NextIs('[')) {
  1632.     result = 1;
  1633.     if (NextIs(']')) {
  1634.         typerec = BuildTypeRecord(typerec, TRC_array, SGN_unknown);
  1635.     } else {
  1636.         tmp = Do_constant_expr();
  1637.         if (tmp) {
  1638.         int                             constvalue;
  1639.         constvalue = GetIntValue(tmp);
  1640.         FreeTree(tmp);
  1641.         typerec = BuildTypeRecord(typerec, TRC_array, SGN_unknown);
  1642.         SetTPSize(typerec, constvalue);
  1643.         if (!NextIs(']'))
  1644.             SyntaxError("Missing right bracket");
  1645.         } else {
  1646.         SyntaxError("Expected constant expression for array size");
  1647.         }
  1648.     }
  1649.     }
  1650.     if (result) {
  1651.     donedecl = 0;
  1652.     while (!donedecl) {
  1653.         if (NextIs('[')) {
  1654.         if (NextIs(']')) {
  1655.             typerec = BuildTypeRecord(typerec, TRC_array, SGN_unknown);
  1656.             SetTPFlags(typerec, GetTPFlags(typerec) | INCOMPLETEMASK);
  1657.             SetTPSize(typerec, 0);
  1658.         } else {
  1659.             tmp = Do_constant_expr();
  1660.             if (tmp) {
  1661.             int                             constvalue;
  1662.             constvalue = GetIntValue(tmp);
  1663.             FreeTree(tmp);
  1664.             typerec = BuildTypeRecord(typerec, TRC_array, SGN_unknown);
  1665.             SetTPSize(typerec, constvalue);
  1666.             if (!NextIs(']'))
  1667.                 SyntaxError("Missing right bracket");
  1668.             } else {
  1669.             SyntaxError("Expected constant expression for array size");
  1670.             }
  1671.         }
  1672.         } else if (NextIs('(')) {
  1673.         SymListVia_t                    prot = NULL;
  1674.         if (NextIs(')')) {
  1675.             if (gProject->itsOptions->requireProtos) {
  1676.             TypeError("Prototypes required");
  1677.             }
  1678.             typerec = BuildTypeRecord(typerec, TRC_OLDfunction, SGN_unknown);
  1679.         } else {
  1680.             prot = RawTable(11);
  1681.             result = Do_parameter_type_list(prot);
  1682.             if (result) {
  1683.             typerec = BuildTypeRecord(typerec, TRC_ANSIfunction, SGN_unknown);
  1684.             SetTPMembers(typerec, prot);
  1685.             if (!NextIs(')'))
  1686.                 SyntaxError("Missing right parenthesis");
  1687.             } else {
  1688.             SyntaxError("Expected parameter type list");
  1689.             FreeSymbolList(prot, 0);
  1690.             }
  1691.         }
  1692.         } else {
  1693.         donedecl = 1;
  1694.         }
  1695.     }
  1696.     if (isArrayType(typerec)) {
  1697.         SetArraySizes(typerec);
  1698.     }
  1699.     }
  1700.     return typerec;
  1701. }
  1702.  
  1703. ParseTreeVia_t
  1704. Do_initializer(void)
  1705. {
  1706.     /*
  1707.      * initializer : assignment_expr | '{' initializer_list '}' | '{'
  1708.      * initializer_list ',' '}' ;
  1709.      */
  1710.  
  1711.     ParseTreeVia_t                  result;
  1712.     int                             tmp;
  1713.     result = Do_assignment_expr();
  1714.     tmp = 0;
  1715.     if (result) {
  1716.     PtrGenerate(&result);
  1717.     }
  1718.     if (!result) {
  1719.     if (NextIs('{')) {
  1720.         result = Do_initializer_list();
  1721.         if (result) {
  1722.         NextIs(',');
  1723.         result = BuildTreeNode(PTF_multi_initializer, result, NULL, NULL);
  1724.         if (!NextIs('}')) {
  1725.             SyntaxError("Missing right bracket");
  1726.         }
  1727.         } else {
  1728.             SyntaxError("Expected initializer list");
  1729.         }
  1730.     } else {
  1731.         result = 0;
  1732.     }
  1733.     }
  1734.     return result;
  1735. }
  1736.  
  1737. ParseTreeVia_t
  1738. Do_initializer_list(void)
  1739. {
  1740.     /*
  1741.      * initializer_list : initializer | initializer_list ',' initializer ;
  1742.      */
  1743.  
  1744.     ParseTreeVia_t                  result;
  1745.     int                             donelisting;
  1746.     result = Do_initializer();
  1747.     if (result) {
  1748.         donelisting = 0;
  1749.         while (!donelisting) {
  1750.             if (NextIs(',')) {
  1751.                 ParseTreeVia_t                  tmp;
  1752.                 tmp = Do_initializer();
  1753.                 if (tmp) {
  1754.                     result = BuildTreeNode(PTF_initializer_list, tmp, result, NULL);
  1755.                 } else {
  1756.                     donelisting = 1;
  1757.                 }
  1758.             } else {
  1759.                 donelisting = 1;
  1760.             }
  1761.         }
  1762.     }
  1763.     return result;
  1764. }
  1765.  
  1766. int
  1767. Do_declaration_list(SymListVia_t table)
  1768. {
  1769.     /*
  1770.      * declaration_list : declaration | declaration_list declaration ;
  1771.      */
  1772.  
  1773.     int                             result;
  1774.     int                             donelisting;
  1775.     int                             count;
  1776.     count = 0;
  1777.     result = Do_declaration(table);
  1778.     if (result) {
  1779.     count = 1;
  1780.     donelisting = 0;
  1781.     while (!donelisting) {
  1782.         result = Do_declaration(table);
  1783.         if (result) {
  1784.         count++;
  1785.         } else {
  1786.         donelisting = 1;
  1787.         }
  1788.     }
  1789.     }
  1790.     return count;
  1791. }
  1792.  
  1793. SymImageVia_t
  1794. Do_external_declaration(short filenum)
  1795. {
  1796.     /*
  1797.      * external_declaration : declarator function_body |
  1798.      * declaration_specifiers declarator function_body |
  1799.      * declaration_specifiers ';' | declaration_specifiers
  1800.      * init_declarator_list ';' | @interface | @implementation ;
  1801.      */
  1802.  
  1803.     TypeRecordVia_t                 typerec;
  1804.     ParseTreeVia_t                  result = 0;
  1805.     SymImageVia_t                   declared = 0;
  1806.     SymImageVia_t                   cursym;
  1807.     SYMVia_t                        thesym;
  1808.     int                             funcresult = 0;
  1809.     int pascalFlag;
  1810.     enum StorageClassCode           stor_class;
  1811.     typerec = Do_declaration_specifiers(1, &stor_class, &pascalFlag);
  1812.     if (typerec) {
  1813.         funcresult = 1;
  1814.         if (NextIs(';')) {
  1815.         /*
  1816.          * What is a declaration specifier without a declarator ? It
  1817.          * is a struct, union, enum, or something like that. In this
  1818.          * case, we check the type record to see if it really was
  1819.          * something that made a table entry.  We want to disallow
  1820.          * declarations such as int;
  1821.          */
  1822.         if (!(isStructUnionType(typerec) || isEnumType(typerec) ||
  1823.               isFunctionType(typerec))) {
  1824.             SyntaxError("Empty declarator");
  1825.         }
  1826.         } else {
  1827.         if (stor_class == SCC_typedef) {
  1828.             char                            nm[64];
  1829.             declared = Do_init_declarator_list(TP_defnames, typerec, stor_class);
  1830.             GetSymName(Via(declared)->Symbol, nm);
  1831.             Via(Via(declared)->Symbol)->TP = BuildTagTypeRecord(Via(Via(declared)->Symbol)->TP, TRC_typedef,
  1832.                                     nm);
  1833.             SetTPFlags(Via(Via(declared)->Symbol)->TP, GetTPFlags(Via(Via(declared)->Symbol)->TP) | SIZEDONE);
  1834.             SetTypeSize(Via(Via(declared)->Symbol)->TP);
  1835.         } else {
  1836.             declared = Do_init_declarator_list(GlobalSymbolTable, typerec, stor_class);
  1837.             if (declared) {
  1838.             char                            thename[64];
  1839.             cursym = declared;
  1840.             while (cursym) {
  1841.                 thesym = Via(cursym)->Symbol;
  1842.                 GetSymName(thesym, thename);
  1843.                 if (GetTPFlags(Via(thesym)->TP) & ISPASCALMASK) {
  1844.                     int                             ndx = 0;
  1845.                     while (thename[ndx]) {
  1846.                         if (islower(thename[ndx]))
  1847.                         thename[ndx] = toupper(thename[ndx]);
  1848.                         ndx++;
  1849.                     }
  1850.                 }
  1851.                 if (gProject->itsOptions->bigGlobals) {
  1852.                     Via(thesym)->M68kDef.Loc = BuildLargeGlobal(MakeUserLabel(thename));
  1853.                     MakeLocGlobal(Via(thesym)->M68kDef.Loc);
  1854.                 } else {
  1855.                     Via(thesym)->M68kDef.Loc = BuildARegLabelDisplace(5, MakeUserLabel(thename));
  1856.                     MakeLocGlobal(Via(thesym)->M68kDef.Loc);
  1857.                 }
  1858.                 SetLocSZ(Via(thesym)->M68kDef.Loc, M68_TypeSize(Via(thesym)->TP));
  1859.                 if (isFloatingType(Via(thesym)->TP))
  1860.                 SetLocIsFloat(Via(thesym)->M68kDef.Loc, 1);
  1861.                 cursym = Via(cursym)->next;
  1862.             }
  1863.             }
  1864.         }
  1865.         if (declared) {
  1866.             if (NextIs(';')) {
  1867.             /*
  1868.              * Here, this could have been any number of things.
  1869.              * One possibility is that it was a prototype. Of
  1870.              * course, it could also have been a normal variable
  1871.              * declaration or something like that.  Or a direct
  1872.              * function.
  1873.              */
  1874.             cursym = declared;
  1875.             while (cursym) {
  1876.                 if (isFunctionType(Via(Via(cursym)->Symbol)->TP)) {
  1877.                 if (Via(Via(cursym)->Symbol)->Definition.Initializer) {
  1878.                     /* This is a direct function */
  1879.                     char                            nm[64];
  1880.                     SetTPTrap(Via(Via(cursym)->Symbol)->TP, Via(Via(cursym)->Symbol)->Definition.Initializer);
  1881.                     GetSymName(Via(cursym)->Symbol, nm);
  1882.                     SetTPParam(Via(Via(cursym)->Symbol)->TP, FindParam(nm));
  1883.                     if (GetTPParam(Via(Via(cursym)->Symbol)->TP))
  1884.                     Via(Via(cursym)->Symbol)->SymbolFlags |= 512;
  1885.                     /* Danger UNNAMED FLAG */
  1886.                 }
  1887.                 Via(Via(cursym)->Symbol)->storage_class = SCC_extern;
  1888.                 }
  1889.                 cursym = Via(cursym)->next;
  1890.             }
  1891.             } else {
  1892.             ParseTreeVia_t                  tmp2;
  1893.             if (Via(declared)->count > 1) {
  1894.                 SyntaxError("You may not define more than one function at once");
  1895.             }
  1896.             tmp2 = Do_function_body(Via(declared)->Symbol);
  1897.             if (!tmp2) {
  1898.                 SyntaxError("Expected function body");
  1899.             }
  1900.             }
  1901.         } else {
  1902.             SyntaxError("Expected declarator");
  1903.         }
  1904.         }
  1905.     } else {        /* No typerec */
  1906.         TypeRecordVia_t                 newtype;
  1907.         typerec = BuildTypeRecord(0, TRC_int, SGN_signed);
  1908.         /*
  1909.          * This means the type of the function is missing.
  1910.          */
  1911.         if (pascalFlag) {
  1912.         TypeRecordVia_t                 other;
  1913.         other = CopyTypeRecord(typerec);
  1914.         SetTPFlags(other, GetTPFlags(other) | ISPASCALMASK);
  1915.         typerec = other;
  1916.         }
  1917.         thesym = Do_declarator(GlobalSymbolTable, typerec, &newtype);
  1918.         if (thesym) {
  1919.         ParseTreeVia_t                  tmptree;
  1920.         char                            thename[64];
  1921.         Via(thesym)->storage_class = stor_class;
  1922.         UserWarning(WARN_missingreturntype);
  1923.         GetSymName(thesym, thename);
  1924.         if (GetTPFlags(Via(thesym)->TP) & ISPASCALMASK) {
  1925.             int                             ndx = 0;
  1926.             while (thename[ndx]) {
  1927.             if (islower(thename[ndx]))
  1928.                 thename[ndx] = toupper(thename[ndx]);
  1929.             ndx++;
  1930.             }
  1931.         }
  1932.         if (gProject->itsOptions->bigGlobals) {
  1933.             Via(thesym)->M68kDef.Loc = BuildLargeGlobal(MakeUserLabel(thename));
  1934.             MakeLocGlobal(Via(thesym)->M68kDef.Loc);
  1935.         } else {
  1936.             Via(thesym)->M68kDef.Loc = BuildARegLabelDisplace(5, MakeUserLabel(thename));
  1937.             MakeLocGlobal(Via(thesym)->M68kDef.Loc);
  1938.         }
  1939.         SetLocSZ(Via(thesym)->M68kDef.Loc, M68_TypeSize(Via(thesym)->TP));
  1940.         if (NextIs(';')) {
  1941.             funcresult = 1;
  1942.         } else {
  1943.             tmptree = Do_function_body(thesym);
  1944.             if (tmptree) {
  1945.                 funcresult = 1;
  1946.             } else {
  1947.                 SyntaxError("Expected function body");
  1948.             }
  1949.         }
  1950.         if (Via(thesym)->storage_class != SCC_extern) {
  1951.             if (Via(thesym)->storage_class != SCC_typedef) {
  1952.                 GenSymbol(thesym, GlobalCodes);
  1953.             }
  1954.         }
  1955.         } else {
  1956.             if (stor_class) {
  1957.                 DeclError("Just a storage class ?! What are you declaring ?");
  1958.             }
  1959.         }
  1960.     }
  1961.     if (declared) {
  1962.         cursym = declared;
  1963.         while (cursym) {
  1964.         if (isVoidType(Via(Via(cursym)->Symbol)->TP)) {
  1965.             DeclError("There are no void objects !");
  1966.         }
  1967.             if (Via(Via(cursym)->Symbol)->storage_class != SCC_typedef) {
  1968.             if (Via(Via(cursym)->Symbol)->storage_class != SCC_extern) {
  1969.                 GenSymbol(Via(cursym)->Symbol, GlobalCodes);
  1970.             }
  1971.             }
  1972.         cursym = Via(cursym)->next;
  1973.         }
  1974.     } else {
  1975.         declared = ListAdd(declared, thesym);
  1976.     }
  1977.     GenSegments(GlobalCodes);
  1978.     GenStringLits(GlobalCodes);
  1979.     GenFloatLits(GlobalCodes);
  1980.     GenStatics(GlobalCodes);
  1981. #ifdef nomore
  1982.     Optimize68(GlobalCodes);
  1983.     DumpCodeList(GlobalCodes, GlobalRecords);
  1984.     FlushOMF(filenum);
  1985.     KillCodesList(GlobalCodes);
  1986.     KillSomeLocations();
  1987. #endif
  1988.     return declared;
  1989. }
  1990.