home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / smc / symbol.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  56.6 KB  |  2,123 lines

  1. /*****************************************************************************/
  2.  
  3. #include "smcPCH.h"
  4. #pragma hdrstop
  5.  
  6. /*****************************************************************************/
  7.  
  8. #include "comp.h"
  9. #include "alloc.h"
  10. #include "hash.h"
  11. #include "symbol.h"
  12. #include "error.h"
  13.  
  14. /*****************************************************************************/
  15. #ifdef  DEBUG
  16. #define SYMALLOC_DISP   0
  17. #else
  18. #define SYMALLOC_DISP   0
  19. #endif
  20. /*****************************************************************************/
  21. #ifndef __SMC__
  22. SymDef              symTab::stErrSymbol;
  23. #endif
  24. /*****************************************************************************
  25.  *
  26.  *  Initialize a symbol table.
  27.  */
  28.  
  29. void                symTab::stInit(Compiler             comp,
  30.                                    norls_allocator    * alloc,
  31.                                    HashTab              hash,
  32.                                    unsigned             ownerx)
  33. {
  34.     assert(comp);
  35.     assert(alloc);
  36.  
  37.     /* Create a hash table if the caller didn't supply one */
  38.  
  39.     if  (!hash)
  40.     {
  41. #if MGDDATA
  42.         hash = new HashTab;
  43. #else
  44.         hash =    (HashTab)alloc->nraAlloc(sizeof(*hash));
  45. #endif
  46.         if  (!hash)
  47.             comp->cmpFatal(ERRnoMemory);
  48.         if  (hash->hashInit(comp, HASH_TABLE_SIZE, ownerx, alloc))
  49.             comp->cmpFatal(ERRnoMemory);
  50.     }
  51.  
  52.     stAllocPerm = alloc;
  53. #ifdef  DEBUG
  54.     stAllocTemp = NULL;
  55. #endif
  56.  
  57.     if  (!stErrSymbol)
  58.         stErrSymbol = stDeclareSym(NULL, SYM_ERR, NS_HIDE, NULL);
  59.  
  60.     stComp      = comp;
  61.     stHash      = hash;
  62.     stOwner     = ownerx;
  63.  
  64.     /* This is just an awful hack for GetType() */
  65.  
  66.     stDollarClsMode = false;
  67.  
  68.     /* Create the intrinsic types and so on */
  69.  
  70.     stInitTypes();
  71. }
  72.  
  73. /*****************************************************************************
  74.  *
  75.  *  Collect and display stats about symbol table allocations.
  76.  */
  77.  
  78. #if SYMALLOC_DISP
  79.  
  80. unsigned            totSymSize;
  81. unsigned            totDefSize;
  82.  
  83. void                dispSymTabAllocStats()
  84. {
  85.     printf("A total of %7u bytes allocated for symbol  entries\n", totSymSize);
  86.     printf("A total of %7u bytes allocated for def/dcl entries\n", totDefSize);
  87. }
  88.  
  89. #endif
  90.  
  91. /*****************************************************************************/
  92. #ifdef  DEBUG
  93. /*****************************************************************************
  94.  *
  95.  *  Display the specified qualified name.
  96.  */
  97.  
  98. void                symTab::stDumpQualName(QualName name)
  99. {
  100.     unsigned        i = 0;
  101.     unsigned        c = name->qnCount;
  102.  
  103.     assert(c);
  104.  
  105.     for (;;)
  106.     {
  107.         printf("%s", hashTab::identSpelling(name->qnTable[i]));
  108.  
  109.         if  (++i == c)
  110.             break;
  111.  
  112.         printf(".");
  113.     }
  114.  
  115.     if  (name->qnEndAll)
  116.         printf(".*");
  117. }
  118.  
  119. /*****************************************************************************
  120.  *
  121.  *  Display the specified "using" list.
  122.  */
  123.  
  124. void                symTab::stDumpUsings(UseList uses, unsigned indent)
  125. {
  126.     if  (!uses)
  127.         return;
  128.  
  129.     printf("\n");
  130.  
  131.     do
  132.     {
  133.         if  (!uses->ulAnchor)
  134.         {
  135.             printf("%*c Using '", 3+4*indent, ' ');
  136.  
  137.             if  (uses->ulBound)
  138.             {
  139.                 printf("%s", uses->ul.ulSym->sdSpelling());
  140.             }
  141.             else
  142.                 stDumpQualName(uses->ul.ulName);
  143.  
  144.             printf("'\n");
  145.         }
  146.  
  147.         uses = uses->ulNext;
  148.     }
  149.     while (uses);
  150. }
  151.  
  152. /*****************************************************************************
  153.  *
  154.  *  Display the specified definition point.
  155.  */
  156.  
  157. void                symTab::stDumpSymDef(DefSrc def, SymDef comp)
  158. {
  159.     printf("[def@%06X]", def->dsdBegPos);
  160.  
  161.     assert(comp);
  162.     assert(comp->sdSymKind == SYM_COMPUNIT);
  163.  
  164.     printf(" %s(%u)", hashTab::identSpelling(comp->sdName), def->dsdSrcLno);
  165. }
  166.  
  167. /*****************************************************************************/
  168.  
  169. void                symTab::stDumpSymbol(SymDef sym, int     indent,
  170.                                                      bool    recurse,
  171.                                                      bool    members)
  172. {
  173.     SymDef          child;
  174.     bool            scopd;
  175.  
  176.     if  (sym->sdIsImport && sym->sdSymKind != SYM_NAMESPACE && stComp->cmpConfig.ccVerbose < 2)
  177.         return;
  178.  
  179.     switch  (sym->sdSymKind)
  180.     {
  181.     case SYM_NAMESPACE:
  182.     case SYM_COMPUNIT:
  183.     case SYM_CLASS:
  184.         printf("\n");
  185.         scopd = true;
  186.         break;
  187.     default:
  188.         scopd = false;
  189.         break;
  190.     }
  191.  
  192.     printf("%*c [%08X] ", 1+4*indent, ' ', sym);
  193.  
  194.     switch  (sym->sdSymKind)
  195.     {
  196.         const   char *  nm;
  197.  
  198.     case SYM_ERR:
  199.         NO_WAY(!"get out of here");
  200.  
  201.     case SYM_VAR:
  202.         if  (sym->sdParent->sdSymKind == SYM_CLASS)
  203.             printf("Field    ");
  204.         else
  205.             printf("Variable  ");
  206.         if  (sym->sdType)
  207.             printf("'%s'", stTypeName(sym->sdType, sym));
  208.         else
  209.             printf("'%s'", hashTab::identSpelling(sym->sdName));
  210.         break;
  211.  
  212.     case SYM_PROP:
  213.         printf("Property  '%s' [", stTypeName(sym->sdType, sym));
  214.         if  (sym->sdProp.sdpGetMeth) printf("get");
  215.         if  (sym->sdProp.sdpSetMeth) printf("set");
  216.         printf("]");
  217.         break;
  218.  
  219.     case SYM_ENUM:
  220.         printf("Enum      '%s'", hashTab::identSpelling(sym->sdName));
  221.         break;
  222.  
  223.     case SYM_ENUMVAL:
  224.         printf("Enumval   '%s'", hashTab::identSpelling(sym->sdName));
  225.         printf(" = %d", sym->sdEnumVal.sdEV.sdevIval);
  226.         break;
  227.  
  228.     case SYM_CLASS:
  229.         switch (sym->sdClass.sdcFlavor)
  230.         {
  231.         case STF_NONE    : nm = "Record"   ; break;
  232.         case STF_CLASS   : nm = "Class"    ; break;
  233.         case STF_UNION   : nm = "Union"    ; break;
  234.         case STF_STRUCT  : nm = "Struct"   ; break;
  235.         case STF_INTF    : nm = "Interface"; break;
  236.         case STF_DELEGATE: nm = "Delegate" ; break;
  237.                   default: nm = "<oops>"   ; break;
  238.         }
  239.         printf("%-9s '%s'", nm,  hashTab::identSpelling(sym->sdName));
  240.  
  241.         if  (sym->sdType->tdClass.tdcBase)
  242.         {
  243.             printf(" inherits %s", sym->sdType->tdClass.tdcBase->tdClass.tdcSymbol->sdSpelling());
  244.         }
  245.         if  (sym->sdType->tdClass.tdcIntf)
  246.         {
  247.             TypList         intf;
  248.  
  249.             printf(" includes ");
  250.  
  251.             for (intf = sym->sdType->tdClass.tdcIntf;
  252.                  intf;
  253.                  intf = intf->tlNext)
  254.             {
  255.                 printf("%s", intf->tlType->tdClass.tdcSymbol->sdSpelling());
  256.                 if  (intf->tlNext)
  257.                     printf(", ");
  258.             }
  259.         }
  260.         break;
  261.  
  262.     case SYM_LABEL:
  263.         printf("Label     '%s'", hashTab::identSpelling(sym->sdName));
  264.         break;
  265.  
  266.     case SYM_NAMESPACE:
  267.         printf("Namespace '%s'", hashTab::identSpelling(sym->sdName));
  268.         break;
  269.  
  270.     case SYM_TYPEDEF:
  271.         printf("Typedef   ");
  272.         if  (sym->sdType)
  273.             printf("%s", stTypeName(NULL, sym));
  274.         else
  275.             printf("'%s'", hashTab::identSpelling(sym->sdName));
  276.         break;
  277.  
  278.     case SYM_FNC:
  279.         if  (sym->sdParent->sdSymKind == SYM_CLASS)
  280.             printf("Method   ");
  281.         else
  282.             printf("Function ");
  283.         if  (sym->sdType)
  284.             printf("%s", stTypeName(sym->sdType, sym));
  285.         else
  286.             printf("'%s'", hashTab::identSpelling(sym->sdName));
  287.         break;
  288.  
  289.     case SYM_SCOPE:
  290.         printf("Scope");
  291.         break;
  292.  
  293.     case SYM_COMPUNIT:
  294.         printf("Comp-unit '%s'", sym->sdName ? hashTab::identSpelling(sym->sdName)
  295.                                              : "<NONAME>");
  296.         break;
  297.  
  298.     default:
  299.         assert(!"unexpected symbol kind");
  300.     }
  301.     printf("\n");
  302.  
  303.     /* Does this symbol have any known definitions? */
  304.  
  305.     if  (sym->sdSrcDefList)
  306.     {
  307.         DefList         defs;
  308.  
  309.         for (defs = sym->sdSrcDefList; defs; defs = defs->dlNext)
  310.         {
  311.             printf("%*c Defined in ", 3+4*indent, ' ');
  312.  
  313.             stDumpSymDef(&defs->dlDef, defs->dlComp);
  314.             printf("\n");
  315.  
  316.             if  (defs->dlUses)
  317.             {
  318.                 switch (sym->sdSymKind)
  319.                 {
  320.                 case SYM_FNC:
  321.                 case SYM_ENUM:
  322.                 case SYM_CLASS:
  323.                 case SYM_NAMESPACE:
  324.                     stDumpUsings(defs->dlUses, indent);
  325.                     printf("\n");
  326.                     break;
  327.                 }
  328.             }
  329.         }
  330.     }
  331.  
  332.     if  (!recurse)
  333.         return;
  334.  
  335.     if  (!members && sym->sdSymKind == SYM_CLASS)
  336.         return;
  337.  
  338.     if  (sym->sdSymKind == SYM_NAMESPACE && sym->sdNS.sdnDeclList)
  339.     {
  340.         ExtList         decl;
  341.  
  342.         printf("\n");
  343.  
  344.         for (decl = sym->sdNS.sdnDeclList; decl; decl = (ExtList)decl->dlNext)
  345.         {
  346.             printf("%*c File decl.   '", 3+4*indent, ' ');
  347.  
  348.             if  (decl->dlQualified)
  349.                 stDumpQualName(decl->mlQual);
  350.             else
  351.                 printf("%s", hashTab::identSpelling(decl->mlName));
  352.  
  353.             printf("'\n");
  354.  
  355.             printf("%*c Defined in ", 5+4*indent, ' ');
  356.             stDumpSymDef(&decl->dlDef, decl->dlComp);
  357.             printf("'\n");
  358.         }
  359.     }
  360.  
  361.     if (sym->sdHasScope() && sym->sdScope.sdScope.sdsChildList)
  362.     {
  363.         if  (sym->sdSymKind == SYM_CLASS)
  364.             printf("\n");
  365.  
  366.         for (child = sym->sdScope.sdScope.sdsChildList;
  367.              child;
  368.              child = child->sdNextInScope)
  369.         {
  370.             if  (sym->sdSymKind != SYM_CLASS && child != sym->sdScope.sdScope.sdsChildList
  371.                                              && child->sdHasScope() == false)
  372.                 printf("\n");
  373.  
  374.             stDumpSymbol(child, indent + 1, recurse, members);
  375.         }
  376.     }
  377.  
  378.     if  (sym->sdSymKind == SYM_CLASS && sym->sdIsImport == false
  379.                                      && sym->sdClass.sdcMemDefList)
  380.     {
  381.         ExtList         mems;
  382.  
  383.         /* Display the members, if any are present */
  384.  
  385.         printf("\n");
  386.  
  387.         for (mems = sym->sdClass.sdcMemDefList;
  388.              mems;
  389.              mems = (ExtList)mems->dlNext)
  390.         {
  391.             printf("%*c Member '", 3+4*indent, ' ');
  392.  
  393.             if  (mems->dlQualified)
  394.                 stDumpQualName(mems->mlQual);
  395.             else
  396.                 printf("%s", hashTab::identSpelling(mems->mlName));
  397.  
  398.             printf("'\n");
  399.  
  400.             printf("%*c Defined in ", 5+4*indent, ' ');
  401.             stDumpSymDef(&mems->dlDef, mems->dlComp);
  402.             printf("\n");
  403.         }
  404.     }
  405. }
  406.  
  407. /*****************************************************************************/
  408. #endif
  409. /*****************************************************************************/
  410.  
  411. #if!MGDDATA
  412.  
  413. inline
  414. size_t              symbolSize(symbolKinds kind)
  415. {
  416.     static
  417.     unsigned char       symSizes[] =
  418.     {
  419.         symDef_size_err,        // SYM_ERR
  420.         symDef_size_var,        // SYM_VAR
  421.         symDef_size_fnc,        // SYM_FNC
  422.         symDef_size_prop,       // SYM_PROP
  423.         symDef_size_label,      // SYM_LABEL
  424.         symDef_size_using,      // SYM_USING
  425.         symDef_size_genarg,     // SYM_GENARG
  426.         symDef_size_enumval,    // SYM_ENUMVAL
  427.         symDef_size_typedef,    // SYM_TYPEDEF
  428.         symDef_size_comp,       // SYM_COMPUNIT
  429.         symDef_size_enum,       // SYM_ENUM
  430.         symDef_size_scope,      // SYM_SCOPE
  431.         symDef_size_class,      // SYM_CLASS
  432.         symDef_size_NS,         // SYM_NAMESPACE
  433.     };
  434.  
  435.     assert(kind < sizeof(symSizes)/sizeof(symSizes[0]));
  436.  
  437.     assert(symSizes[SYM_ERR      ] == symDef_size_err    );
  438.     assert(symSizes[SYM_VAR      ] == symDef_size_var    );
  439.     assert(symSizes[SYM_FNC      ] == symDef_size_fnc    );
  440.     assert(symSizes[SYM_PROP     ] == symDef_size_prop   );
  441.     assert(symSizes[SYM_LABEL    ] == symDef_size_label  );
  442.     assert(symSizes[SYM_USING    ] == symDef_size_using  );
  443.     assert(symSizes[SYM_GENARG   ] == symDef_size_genarg );
  444.     assert(symSizes[SYM_ENUMVAL  ] == symDef_size_enumval);
  445.     assert(symSizes[SYM_TYPEDEF  ] == symDef_size_typedef);
  446.     assert(symSizes[SYM_COMPUNIT ] == symDef_size_comp   );
  447.     assert(symSizes[SYM_ENUM     ] == symDef_size_enum   );
  448.     assert(symSizes[SYM_SCOPE    ] == symDef_size_scope  );
  449.     assert(symSizes[SYM_CLASS    ] == symDef_size_class  );
  450.     assert(symSizes[SYM_NAMESPACE] == symDef_size_NS     );
  451.  
  452.     assert(kind < sizeof(symSizes)/sizeof(symSizes[0]));
  453.  
  454.     return  symSizes[kind];
  455. }
  456.  
  457. #endif
  458.  
  459. /*****************************************************************************
  460.  *
  461.  *  The cmpDeclareSym() function creates a symbol descriptor, inserts it
  462.  *  in the appropriate scope, and makes it visible via the hash table.
  463.  *
  464.  *  IMPORTANT:  This method should only be used to declare symbols outside
  465.  *              of local (block) scopes. Local symbols should be declared
  466.  *              via stDeclareLcl().
  467.  */
  468.  
  469. SymDef              symTab::stDeclareSym(Ident       name,
  470.                                          symbolKinds kind,
  471.                                          name_space  nspc,
  472.                                          SymDef      parent)
  473. {
  474.     SymDef          sym;
  475. #if!MGDDATA
  476.     size_t          siz;
  477. #endif
  478.  
  479.     /* HACK: set the 'type' bit for classes and enums */
  480.  
  481.     switch (kind)
  482.     {
  483.     case SYM_ENUM:
  484.     case SYM_CLASS:
  485.         if  (nspc != NS_HIDE)
  486.             nspc = NS_TYPE;
  487.         break;
  488.  
  489.     case SYM_TYPEDEF:
  490.     case SYM_NAMESPACE:
  491.         nspc = (name_space)(nspc | NS_TYPE);
  492.         break;
  493.     }
  494.  
  495.     if  (SymDefRec::sdHasScope(kind))
  496.         nspc = (name_space)(nspc | NS_CONT);
  497.  
  498.     /* Allocate the symbol and fill in some basic information */
  499.  
  500. #if MGDDATA
  501.  
  502.     sym = new SymDef;
  503.  
  504. #else
  505.  
  506.     siz = symbolSize(kind);
  507.     sym = (SymDef)stAllocPerm->nraAlloc(siz);
  508.  
  509. #if SYMALLOC_DISP
  510.     totSymSize += siz;
  511. #endif
  512.  
  513.     memset(sym, 0, siz);        // ISSUE: is this a good idea?
  514.  
  515. #endif
  516.  
  517.     sym->sdName         = name;
  518.     sym->sdSymKind      = kind;
  519.     sym->sdNameSpace    = nspc;
  520.     sym->sdParent       = parent;
  521.     sym->sdCompileState = CS_KNOWN;
  522.  
  523.     /* Insert the symbol into the hash table, unless name == 0 */
  524.  
  525.     if  (name && !(nspc & NS_HIDE))
  526.     {
  527.         /* Hook the symbol into the symbol definition list */
  528.  
  529.         sym->sdNextDef = hashTab::getIdentSymDef(name);
  530.                          hashTab::setIdentSymDef(name, sym);
  531.     }
  532.  
  533.     /* Add the symbol to the parent's list of children (if there is a parent) */
  534.  
  535.     if  (parent)
  536.     {
  537.         if  (parent->sdScope.sdScope.sdsChildLast)
  538.             parent->sdScope.sdScope.sdsChildLast->sdNextInScope  = sym;
  539.         else
  540.             parent->sdScope.sdScope.sdsChildList                 = sym;
  541.  
  542.         parent->sdScope.sdScope.sdsChildLast = sym;
  543.     }
  544.  
  545. //  if  (name && !strcmp(name->idSpelling(), "<whatever>")) forceDebugBreak();
  546. //  if  ((int)sym == 0xADDRESS                            ) forceDebugBreak();
  547.  
  548.     return sym;
  549. }
  550.  
  551. /*****************************************************************************
  552.  *
  553.  *  Declare a nested class type.
  554.  */
  555.  
  556. SymDef              symTab::stDeclareNcs(Ident        name,
  557.                                          SymDef       scope,
  558.                                          str_flavors  flavor)
  559. {
  560.     SymDef          sym;
  561.     TypDef          typ;
  562.  
  563.     assert(scope && scope->sdSymKind == SYM_CLASS);
  564.  
  565.     sym                    = stDeclareSym(name, SYM_CLASS, NS_NORM, scope);
  566.     typ = sym->sdType      = stNewClsType(sym);
  567.  
  568.     sym->sdClass.sdcFlavor = flavor;
  569.     typ->tdClass.tdcFlavor = flavor;
  570.  
  571.     return  sym;
  572. }
  573.  
  574. /*****************************************************************************
  575.  *
  576.  *  Declare a new overloaded function and add it to the overload list of the
  577.  *  given function symbol.
  578.  */
  579.  
  580. SymDef              symTab::stDeclareOvl(SymDef fnc)
  581. {
  582.     SymDef          sym;
  583. #if!MGDDATA
  584.     size_t          siz;
  585. #endif
  586.  
  587.     assert(fnc);
  588.  
  589.     if  (fnc->sdSymKind == SYM_FNC)
  590.     {
  591.         /* Allocate the symbol and fill in some basic information */
  592.  
  593. #if MGDDATA
  594.  
  595.         sym = new SymDef;
  596.  
  597. #else
  598.  
  599.         siz = symbolSize(SYM_FNC);
  600.         sym = (SymDef)stAllocPerm->nraAlloc(siz);
  601.  
  602. #if SYMALLOC_DISP
  603.         totSymSize += siz;
  604. #endif
  605.  
  606.         memset(sym, 0, siz);        // ISSUE: is this a good idea?
  607.  
  608. #endif
  609.  
  610.         sym->sdSymKind         = SYM_FNC;
  611.  
  612.         /* Add the symbol to the overload list */
  613.  
  614.         sym->sdFnc.sdfNextOvl  = fnc->sdFnc.sdfNextOvl;
  615.         fnc->sdFnc.sdfNextOvl  = sym;
  616.  
  617.         /* Copy a few attributes from the old symbol */
  618.  
  619.         sym->sdIsManaged       = fnc->sdIsManaged;
  620.         sym->sdFnc.sdfOper     = fnc->sdFnc.sdfOper;
  621.         sym->sdFnc.sdfConvOper = fnc->sdFnc.sdfConvOper;
  622.     }
  623.     else
  624.     {
  625.         assert(fnc->sdSymKind == SYM_PROP);
  626.  
  627.         /* Allocate the symbol and fill in some basic information */
  628.  
  629. #if MGDDATA
  630.  
  631.         sym = new SymDef;
  632.  
  633. #else
  634.  
  635.         siz = symbolSize(SYM_PROP);
  636.         sym = (SymDef)stAllocPerm->nraAlloc(siz);
  637.  
  638. #if SYMALLOC_DISP
  639.         totSymSize += siz;
  640. #endif
  641.  
  642.         memset(sym, 0, siz);        // ISSUE: is this a good idea?
  643.  
  644. #endif
  645.  
  646.         sym->sdSymKind         = SYM_PROP;
  647.  
  648.         sym->sdProp.sdpNextOvl = fnc->sdProp.sdpNextOvl;
  649.         fnc->sdProp.sdpNextOvl = sym;
  650.     }
  651.  
  652.     /* Copy over the fields that should be identical */
  653.  
  654.     sym->sdName            = fnc->sdName;
  655.     sym->sdNameSpace       = fnc->sdNameSpace;
  656.     sym->sdParent          = fnc->sdParent;
  657.     sym->sdCompileState    = CS_KNOWN;
  658.  
  659.     return sym;
  660. }
  661.  
  662. /*****************************************************************************
  663.  *
  664.  *  The cmpDeclareLcl() function creates a symbol descriptor and inserts it
  665.  *  in the given *local* function scope.
  666.  */
  667.  
  668. SymDef              symTab::stDeclareLcl(Ident              name,
  669.                                          symbolKinds        kind,
  670.                                          name_space         nspc,
  671.                                          SymDef             parent,
  672.                                          norls_allocator *  alloc)
  673. {
  674.     SymDef          sym;
  675. #if!MGDDATA
  676.     size_t          siz;
  677. #endif
  678.  
  679.     /* For now force the caller to choose which allocator to use */
  680.  
  681.     assert(alloc);
  682.  
  683.     /* Make sure the scope looks reasonable */
  684.  
  685.     assert(parent == NULL || parent->sdSymKind == SYM_SCOPE);
  686.  
  687.     /* Allocate the symbol and fill in some basic information */
  688.  
  689. #if MGDDATA
  690.  
  691.     sym = new SymDef;
  692.  
  693. #else
  694.  
  695.     siz = symbolSize(kind);
  696.     sym = (SymDef)alloc->nraAlloc(siz);
  697.  
  698.     memset(sym, 0, siz);        // ISSUE: is this a good idea?
  699.  
  700. #endif
  701.  
  702.     sym->sdName         = name;
  703.     sym->sdSymKind      = kind;
  704.     sym->sdNameSpace    = nspc;
  705.     sym->sdParent       = parent;
  706.     sym->sdCompileState = CS_KNOWN;
  707.  
  708.     /* Add the symbol to the parent's list of children (if there is a parent) */
  709.  
  710.     if  (parent)
  711.     {
  712.         if  (parent->sdScope.sdScope.sdsChildLast)
  713.             parent->sdScope.sdScope.sdsChildLast->sdNextInScope  = sym;
  714.         else
  715.             parent->sdScope.sdScope.sdsChildList                 = sym;
  716.  
  717.         parent->sdScope.sdScope.sdsChildLast = sym;
  718.     }
  719.  
  720.     return sym;
  721. }
  722.  
  723. /*****************************************************************************
  724.  *
  725.  *  Allocate a label symbol from the specified allocator and stick it in
  726.  *  the given scope.
  727.  */
  728.  
  729. SymDef              symTab::stDeclareLab(Ident  name,
  730.                                          SymDef scope, norls_allocator*alloc)
  731. {
  732.     SymDef          sym;
  733. #if!MGDDATA
  734.     size_t          siz;
  735. #endif
  736.  
  737.     /* Make sure the scope looks reasonable */
  738.  
  739.     assert(scope && scope->sdSymKind == SYM_SCOPE);
  740.  
  741.     /* Allocate the symbol and fill in some basic information */
  742.  
  743. #if MGDDATA
  744.     sym = new SymDef;
  745. #else
  746.     siz = symbolSize(SYM_LABEL);
  747.     sym = (SymDef)alloc->nraAlloc(siz);
  748. #endif
  749.  
  750.     sym->sdName         = name;
  751. #ifdef  DEBUG
  752.     sym->sdType         = NULL;
  753. #endif
  754.     sym->sdSymKind      = SYM_LABEL;
  755.     sym->sdNameSpace    = NS_HIDE;
  756.     sym->sdParent       = scope;
  757. //  sym->sdCompileState = CS_KNOWN;
  758.  
  759.     /* Insert the symbol into the hash table */
  760.  
  761.     sym->sdNextDef = hashTab::getIdentSymDef(name);
  762.                      hashTab::setIdentSymDef(name, sym);
  763.  
  764.     return sym;
  765. }
  766.  
  767. /*****************************************************************************
  768.  *
  769.  *  Remove the given symbol from the symbol table.
  770.  */
  771.  
  772. void                symTab::stRemoveSym(SymDef sym)
  773. {
  774.     Ident           symName = sym->sdName;
  775.  
  776.     SymDef          defList;
  777.  
  778.     assert(symName);
  779.  
  780.     /* Remove the symbol from the linked list of definitions */
  781.  
  782.     defList = hashTab::getIdentSymDef(symName);
  783.     if  (defList == sym)
  784.     {
  785.         /* The symbol is at the very front of the list */
  786.  
  787.         hashTab::setIdentSymDef(symName, defList->sdNextDef);
  788.     }
  789.     else
  790.     {
  791.         /* Locate the symbol in the linked list and remove it */
  792.  
  793.         for (;;)
  794.         {
  795.             SymDef      defLast = defList; assert(defLast);
  796.  
  797.             defList = defList->sdNextDef;
  798.  
  799.             if  (defList == sym)
  800.             {
  801.                 defLast->sdNextDef = defList->sdNextDef;
  802.                 return;
  803.             }
  804.         }
  805.     }
  806. }
  807.  
  808. /*****************************************************************************
  809.  *
  810.  *  Record a definition for the given symbol in the current comp-unit at the
  811.  *  specified source offsets.
  812.  */
  813.  
  814. DefList             symTab::stRecordSymSrcDef(SymDef  sym,
  815.                                               SymDef  cmp,
  816.                                               UseList uses, scanPosTP dclFpos,
  817.                                                             unsigned  dclLine,
  818.                                               bool    ext)
  819. {
  820.     DefList         defRec;
  821.     ExtList         extRec;
  822.  
  823.     if  (ext)
  824.     {
  825. #if MGDDATA
  826.         extRec = new ExtList;
  827. #else
  828.         extRec =    (ExtList)stAllocPerm->nraAlloc(sizeof(*extRec));
  829.         memset(extRec, 0, sizeof(*extRec));
  830. #endif
  831.  
  832.         extRec->dlQualified = false;
  833.         extRec->mlName      = sym->sdName;
  834.  
  835.         defRec = extRec;
  836.     }
  837.     else
  838.     {
  839. #if MGDDATA
  840.         defRec = new DefList;
  841. #else
  842.         defRec =    (DefList)stAllocPerm->nraAlloc(sizeof(*defRec));
  843.         memset(defRec, 0, sizeof(*defRec));
  844. #endif
  845.     }
  846.  
  847. #if!MGDDATA
  848. #if SYMALLOC_DISP
  849.     totDefSize += ext ? sizeof(*extRec) : sizeof(*defRec);
  850. #endif
  851. #endif
  852.  
  853.     defRec->dlNext = sym->sdSrcDefList;
  854.                      sym->sdSrcDefList = defRec;
  855.  
  856.     defRec->dlDef.dsdBegPos = dclFpos;
  857.     defRec->dlDef.dsdSrcLno = dclLine;
  858.  
  859.     defRec->dlDeclSkip      = 0;
  860.  
  861.     defRec->dlComp          = cmp;
  862.     defRec->dlUses          = uses;
  863.  
  864. #ifdef  DEBUG
  865.     defRec->dlExtended      = ext;
  866. #endif
  867.  
  868.     return  defRec;
  869. }
  870.  
  871. /*****************************************************************************
  872.  *
  873.  *  Create a definition record for the given member.
  874.  */
  875.  
  876. ExtList             symTab::stRecordMemSrcDef(Ident    name,
  877.                                               QualName qual,
  878.                                               SymDef   comp,
  879.                                               UseList  uses, scanPosTP dclFpos,
  880.                                                              unsigned  dclLine)
  881. {
  882.     ExtList         defRec;
  883.  
  884. #if MGDDATA
  885.     defRec = new ExtList;
  886. #else
  887.     defRec =    (ExtList)stAllocPerm->nraAlloc(sizeof(*defRec));
  888.     memset(defRec, 0, sizeof(*defRec));
  889. #endif
  890.  
  891.     assert((name != NULL) != (qual != NULL));
  892.  
  893.     if  (name)
  894.     {
  895.         defRec->dlQualified = false;
  896.         defRec->mlName      = name;
  897.     }
  898.     else
  899.     {
  900.         defRec->dlQualified = true;
  901.         defRec->mlQual      = qual;
  902.     }
  903.  
  904. #if SYMALLOC_DISP
  905.     totDefSize += sizeof(*defRec);
  906. #endif
  907.  
  908.     defRec->dlDef.dsdBegPos = dclFpos;
  909.     defRec->dlDef.dsdSrcLno = dclLine;
  910.  
  911.     defRec->dlComp          = comp;
  912.     defRec->dlUses          = uses;
  913.  
  914. #ifdef  DEBUG
  915.     defRec->dlExtended      = true;
  916. #endif
  917.  
  918.     assert(defRec->dlDeclSkip == 0);    // should be cleared above
  919.  
  920.     return  defRec;
  921. }
  922.  
  923. /*****************************************************************************
  924.  *
  925.  *  Lookup a name in the given namespace scope.
  926.  */
  927.  
  928. SymDef              symTab::stLookupNspSym(Ident       name,
  929.                                            name_space  symNS,
  930.                                            SymDef      scope)
  931. {
  932.     SymDef          sym;
  933.  
  934.     // ISSUE: May have to rehash into the appropriate hash table
  935.  
  936.     assert(name);
  937.     assert(scope && (scope->sdSymKind == SYM_NAMESPACE ||
  938.                      scope->sdSymKind == SYM_SCOPE));
  939.  
  940.     /* Walk the symbol definitions, looking for a matching one */
  941.  
  942.     for (sym = hashTab::getIdentSymDef(name); sym; sym = sym->sdNextDef)
  943.     {
  944.         assert(sym->sdName == name);
  945.  
  946.         /* Does the symbol belong to the desired scope? */
  947.  
  948.         if  (sym->sdParent == scope)
  949.             return  sym;
  950.     }
  951.  
  952.     return sym;
  953. }
  954.  
  955. /*****************************************************************************
  956.  *
  957.  *  Lookup a member in the given class/enum.
  958.  */
  959.  
  960. SymDef              symTab::stLookupClsSym(Ident name, SymDef scope)
  961. {
  962.     SymDef          sym;
  963.  
  964.     // ISSUE: May have to rehash into the appropriate hash table
  965.  
  966.     assert(name);
  967.     assert(scope && (scope->sdSymKind == SYM_ENUM ||
  968.                      scope->sdSymKind == SYM_CLASS));
  969.  
  970.     /* Make sure the class/enum is at least in 'declared' state */
  971.  
  972.     if  (scope->sdCompileState < CS_DECLSOON)
  973.     {
  974.         // ISSUE: This is a little expensive, isn't it?
  975.  
  976.         if  (stComp->cmpDeclSym(scope))
  977.             return  NULL;
  978.     }
  979.  
  980.     /* Walk the symbol definitions, looking for a matching one */
  981.  
  982.     for (sym = hashTab::getIdentSymDef(name); sym; sym = sym->sdNextDef)
  983.     {
  984.         SymDef          parent = sym->sdParent;
  985.  
  986.         assert(sym->sdName == name);
  987.  
  988.         /* Does the symbol belong to the desired scope? */
  989.  
  990.         if  (parent == scope)
  991.             return sym;
  992.  
  993.         /* Special case: a member of a nested anonymous union */
  994.  
  995.         while (parent->sdSymKind == SYM_CLASS && parent->sdClass.sdcAnonUnion)
  996.         {
  997.             parent = parent->sdParent; assert(parent);
  998.  
  999.             if  (parent == scope)
  1000.                 return  sym;
  1001.         }
  1002.     }
  1003.  
  1004.     return  sym;
  1005. }
  1006.  
  1007. /*****************************************************************************
  1008.  *
  1009.  *  Find a property member in the given class type.
  1010.  */
  1011.  
  1012. SymDef              symTab::stLookupProp(Ident name, SymDef scope)
  1013. {
  1014.     SymDef          sym;
  1015.  
  1016.     // ISSUE: May have to rehash into the appropriate hash table
  1017.  
  1018.     assert(name);
  1019.     assert(scope && scope->sdSymKind == SYM_CLASS);
  1020.  
  1021.     /* Make sure the class is at least in 'declared' state */
  1022.  
  1023.     assert(scope->sdCompileState >= CS_DECLSOON);
  1024.  
  1025.     /* Walk the symbol definitions, looking for a matching one */
  1026.  
  1027.     for (sym = hashTab::getIdentSymDef(name); sym; sym = sym->sdNextDef)
  1028.     {
  1029.         SymDef          parent = sym->sdParent;
  1030.  
  1031.         assert(sym->sdName == name);
  1032.  
  1033.         /* Does the symbol belong to the desired scope? */
  1034.  
  1035.         if  (parent == scope)
  1036.             return sym;
  1037.     }
  1038.  
  1039.     return  sym;
  1040. }
  1041.  
  1042. /*****************************************************************************
  1043.  *
  1044.  *  Lookup a name in the given non-namespace scope.
  1045.  */
  1046.  
  1047. SymDef              symTab::stLookupScpSym(Ident name, SymDef scope)
  1048. {
  1049.     SymDef          sym;
  1050.  
  1051.     // ISSUE: May have to rehash into the appropriate hash table
  1052.  
  1053.     assert(name);
  1054.     assert(scope && (scope->sdSymKind == SYM_ENUM  ||
  1055.                      scope->sdSymKind == SYM_CLASS ||
  1056.                      scope->sdSymKind == SYM_SCOPE));
  1057.  
  1058.     /* Walk the symbol definitions, looking for a matching one */
  1059.  
  1060.     for (sym = hashTab::getIdentSymDef(name); sym; sym = sym->sdNextDef)
  1061.     {
  1062.         assert(sym->sdName == name);
  1063.  
  1064.         /* Does the symbol belong to the desired scope? */
  1065.  
  1066.         if  (sym->sdParent == scope)
  1067.             return  sym;
  1068.     }
  1069.  
  1070.     return sym;
  1071. }
  1072.  
  1073. /*****************************************************************************
  1074.  *
  1075.  *  Perform a full lookup of the given name in the specified class. This looks
  1076.  *  in the base classes and all that. An ambiguous reference is reported as an
  1077.  *  error (and 'stErrSymbol' is returned in that case).
  1078.  */
  1079.  
  1080. SymDef              symTab::stFindInClass(Ident name, SymDef scp, name_space nsp)
  1081. {
  1082.     SymDef          sym;
  1083.     SymDef          nts;
  1084.     TypDef          typ;
  1085.  
  1086.     // ISSUE: May have to rehash into the appropriate hash table
  1087.  
  1088.     assert(name);
  1089.     assert(scp && (scp->sdSymKind == SYM_ENUM ||
  1090.                    scp->sdSymKind == SYM_CLASS));
  1091.  
  1092.     assert(scp->sdCompileState >= CS_DECLSOON);
  1093.  
  1094.     /* Walk the symbol definitions, looking for a matching one */
  1095.  
  1096.     for (sym = hashTab::getIdentSymDef(name), nts = NULL;
  1097.          sym;
  1098.          sym = sym->sdNextDef)
  1099.     {
  1100.         SymDef          parent = sym->sdParent;
  1101.  
  1102.         assert(sym->sdName == name);
  1103.  
  1104.         /* Does the symbol belong to the desired scope? */
  1105.  
  1106.         if  (parent == scp)
  1107.         {
  1108.             /* Does the symbol belong to the desired namespace ? */
  1109.  
  1110.             if  (!(sym->sdNameSpace & nsp))
  1111.             {
  1112.                 /* Special case: are we looking for types? */
  1113.  
  1114.                 if  (nsp == NS_TYPE)
  1115.                 {
  1116.                     /* Remember any non-type symbol we encounter */
  1117.  
  1118.                     if  (sym->sdNameSpace & NS_NORM)
  1119.                         nts = sym;
  1120.                 }
  1121.  
  1122.                 continue;
  1123.             }
  1124.  
  1125.             return sym;
  1126.         }
  1127.  
  1128.         /* Special case: a member of a nested anonymous union */
  1129.  
  1130.         while (parent && symTab::stIsAnonUnion(parent))
  1131.         {
  1132.             parent = parent->sdParent; assert(parent);
  1133.  
  1134.             if  (parent == scp)
  1135.                 return  sym;
  1136.         }
  1137.     }
  1138.  
  1139.     /* Did we find a non-type symbol that matched ? */
  1140.  
  1141.     if  (nts)
  1142.         return  nts;
  1143.  
  1144.     /* Does the name match the class name itself? */
  1145.  
  1146.     if  (name == scp->sdName)
  1147.         return  scp;
  1148.  
  1149.     /* No luck, time to check the base class and interfaces */
  1150.  
  1151.     if  (scp->sdSymKind != SYM_CLASS)
  1152.         return  NULL;
  1153.  
  1154.     typ = scp->sdType;
  1155.  
  1156.     /* Is there a base class? */
  1157.  
  1158.     if  (typ->tdClass.tdcBase)
  1159.     {
  1160.         /* Look in the base class (recursively) and return if we find something */
  1161.  
  1162.         scp = typ->tdClass.tdcBase->tdClass.tdcSymbol;
  1163.         sym = stLookupAllCls(name, scp, nsp, CS_DECLSOON);
  1164.         if  (sym)
  1165.             return  sym;
  1166.     }
  1167.  
  1168.     /* Does the class include any interfaces? */
  1169.  
  1170.     if  (typ->tdClass.tdcIntf)
  1171.     {
  1172.         TypList         ifl = typ->tdClass.tdcIntf;
  1173.  
  1174.         do
  1175.         {
  1176.             SymDef          tmp;
  1177.             SymDef          tsc;
  1178.  
  1179.             /* Look in the interface and bail if that triggers an error */
  1180.  
  1181.             tsc = ifl->tlType->tdClass.tdcSymbol;
  1182.             tmp = stLookupAllCls(name, tsc, nsp, CS_DECLSOON);
  1183.             if  (tmp == stErrSymbol)
  1184.                 return  tmp;
  1185.  
  1186.             if  (tmp)
  1187.             {
  1188.                 /* We have a match, do we already have a different match? */
  1189.  
  1190.                 if  (sym && sym != tmp && !stArgsMatch(sym->sdType, tmp->sdType))
  1191.                 {
  1192.                     stComp->cmpError(ERRambigMem, name, scp, tsc);
  1193.                     return  stErrSymbol;
  1194.                 }
  1195.  
  1196.                 /* This is the first match, record it and continue */
  1197.  
  1198.                 sym = tmp;
  1199.                 scp = tsc;
  1200.             }
  1201.  
  1202.             ifl = ifl->tlNext;
  1203.         }
  1204.         while (ifl);
  1205.     }
  1206.  
  1207.     return  sym;
  1208. }
  1209.  
  1210. /*****************************************************************************
  1211.  *
  1212.  *  Look for a matching method/property in the given class. If the 'baseOnly'
  1213.  *  argument is non-zero we don't look in the class itself, only in its base
  1214.  *  (and any interfaces it includes).
  1215.  */
  1216.  
  1217. SymDef              symTab::stFindBCImem(SymDef clsSym, Ident       name,
  1218.                                                         TypDef      type,
  1219.                                                         symbolKinds kind,
  1220.                                                   INOUT SymDef  REF matchFN,
  1221.                                                         bool        baseOnly)
  1222. {
  1223.     TypDef          clsType = clsSym->sdType;
  1224.     SymDef          sym;
  1225.  
  1226.     assert(kind == SYM_FNC || kind == SYM_PROP);
  1227.  
  1228.     /* Try the class itself if we're supposed to */
  1229.  
  1230.     if  (!baseOnly)
  1231.     {
  1232.         sym = clsSym;
  1233.     }
  1234.     else if  (clsType->tdClass.tdcBase)
  1235.     {
  1236.         sym = clsType->tdClass.tdcBase->tdClass.tdcSymbol;
  1237.     }
  1238.     else
  1239.         goto TRY_INTF;
  1240.  
  1241.     // UNDONE: This call may cause ambiguity errors to be issued, which is inappropriate here, right?
  1242.  
  1243.     sym = stLookupAllCls(name, sym, NS_NORM, CS_DECLARED);
  1244.  
  1245.     if  (sym && (BYTE)sym->sdSymKind == (BYTE)kind)
  1246.     {
  1247.         SymDef          ovl;
  1248.  
  1249.         /* Tell the caller about a possibly hidden base method */
  1250.  
  1251.         matchFN = sym;
  1252.  
  1253.         /* Look for an exact match on signature */
  1254.  
  1255.         if  (kind == SYM_FNC)
  1256.             ovl = stFindOvlFnc (sym, type);
  1257.         else
  1258.             ovl = stFindOvlProp(sym, type);
  1259.  
  1260.         if  (ovl)
  1261.             return  ovl;
  1262.     }
  1263.  
  1264. TRY_INTF:
  1265.  
  1266.     /* Now try all the interfaces */
  1267.  
  1268.     if  (clsType->tdClass.tdcIntf)
  1269.     {
  1270.         TypList         ifl = clsType->tdClass.tdcIntf;
  1271.  
  1272.         do
  1273.         {
  1274.             SymDef          tmp;
  1275.  
  1276.             /* Look in the interface (recursively) */
  1277.  
  1278.             tmp = stFindBCImem(ifl->tlType->tdClass.tdcSymbol, name, type, kind, matchFN, false);
  1279.             if  (tmp)
  1280.                 return  tmp;
  1281.  
  1282.             ifl = ifl->tlNext;
  1283.         }
  1284.         while (ifl);
  1285.     }
  1286.  
  1287.     return  NULL;
  1288. }
  1289.  
  1290. /*****************************************************************************
  1291.  *
  1292.  *  See if the given method has a matching definition in the given class or
  1293.  *  any of it base classes (note that we ignore interfaces).
  1294.  */
  1295.  
  1296. SymDef              symTab::stFindInBase(SymDef fnc, SymDef scp)
  1297. {
  1298.     SymDef          sym;
  1299.     Ident           name = fnc->sdName;
  1300.  
  1301.     // ISSUE: May have to rehash into the appropriate hash table
  1302.  
  1303.     assert(fnc);
  1304.     assert(fnc->sdSymKind == SYM_FNC);
  1305.     assert(fnc->sdParent->sdSymKind == SYM_CLASS);
  1306.  
  1307.     for (;;)
  1308.     {
  1309.         assert(scp && scp->sdSymKind == SYM_CLASS);
  1310.  
  1311.         if  (scp->sdCompileState < CS_DECLSOON)
  1312.             stComp->cmpDeclSym(scp);
  1313.  
  1314.         /* Look for a definition of the method in the given class */
  1315.  
  1316.         if  (fnc->sdFnc.sdfOper != OVOP_NONE)
  1317.         {
  1318.             UNIMPL("");
  1319.         }
  1320.         else
  1321.         {
  1322.             /* Walk the symbol definitions, looking for a matching one */
  1323.  
  1324.             for (sym = hashTab::getIdentSymDef(name); sym; sym = sym->sdNextDef)
  1325.             {
  1326.                 SymDef          parent = sym->sdParent;
  1327.  
  1328.                 assert(sym->sdName == name);
  1329.  
  1330.                 /* Does the symbol belong to the desired scope? */
  1331.  
  1332.                 if  (parent == scp)
  1333.                     return sym;
  1334.             }
  1335.         }
  1336.  
  1337.         /* Is there a base class? */
  1338.  
  1339.         if  (!scp->sdType->tdClass.tdcBase)
  1340.             break;
  1341.  
  1342.         /* Look in the base class */
  1343.  
  1344.         scp = scp->sdType->tdClass.tdcBase->tdClass.tdcSymbol;
  1345.     }
  1346.  
  1347.     return  sym;
  1348. }
  1349.  
  1350. /*****************************************************************************
  1351.  *
  1352.  *  Lookup a name in the given local (block) scope.
  1353.  */
  1354.  
  1355. SymDef              symTab::stLookupLclSym(Ident name, SymDef scope)
  1356. {
  1357.     SymDef          sym;
  1358.  
  1359.     for (sym = scope->sdScope.sdScope.sdsChildList;
  1360.          sym;
  1361.          sym = sym->sdNextInScope)
  1362.     {
  1363.         if  (sym->sdName == name)
  1364.             break;
  1365.     }
  1366.  
  1367.     return  sym;
  1368. }
  1369.  
  1370. /*****************************************************************************
  1371.  *
  1372.  *  Look inside the given "using" section for an unambiguous definition of
  1373.  *  the given name. If an error occurs, 'stErrSymbol' is returned. If no
  1374.  *  definition is found, NULL is returned. Otherwise the one and only symbol
  1375.  *  found is returned.
  1376.  */
  1377.  
  1378. SymDef              symTab::stSearchUsing(INOUT UseList REF useRef, Ident      name,
  1379.                                                                     name_space nsp)
  1380. {
  1381.     UseList         uses;
  1382.  
  1383.     SymDef          oneSym  = NULL;
  1384.  
  1385.     SymDef          allSym1 = NULL;
  1386.     SymDef          allSym2 = NULL;
  1387.  
  1388.     assert(useRef && useRef->ulAnchor);
  1389.  
  1390.     /*
  1391.         Keep track of any matching symbols we find - if we get a match against
  1392.         an import of an individual name, we remember it in "oneSym". Matches
  1393.         within imports of entire namespaces are kept in "allSym1"/"allSym2".
  1394.      */
  1395.  
  1396.     for (uses = useRef->ulNext; uses && !uses->ulAnchor; uses = uses->ulNext)
  1397.     {
  1398.         SymDef          use;
  1399.  
  1400.         assert(uses->ulBound); use = uses->ul.ulSym;
  1401.  
  1402.         if  (!use)
  1403.             continue;
  1404.  
  1405.         if  (uses->ulAll)
  1406.         {
  1407.             SymDef          sym;
  1408.  
  1409.             /* Look for the name in the used namespace */
  1410.  
  1411.             sym = stLookupNspSym(name, nsp, use);
  1412.  
  1413.             if  (sym)
  1414.             {
  1415.                 /* HACK!!!!!!!!!!!!!!!!!! prefer a class symbol */
  1416.  
  1417.                 if  (stComp->cmpConfig.ccAmbigHack)
  1418.                 {
  1419.                     if  (sym->sdSymKind == SYM_CLASS)
  1420.                         return  sym;
  1421.  
  1422.                     allSym1 = allSym2 = NULL;
  1423.                 }
  1424.  
  1425.                 if  (sym != allSym1 &&
  1426.                      sym != allSym2)
  1427.                 {
  1428.                     if      (allSym1 == NULL)
  1429.                         allSym1 = sym;
  1430.                     else if (allSym2 == NULL)
  1431.                         allSym2 = sym;
  1432.                 }
  1433.             }
  1434.         }
  1435.         else
  1436.         {
  1437.             if  (use->sdName == name)
  1438.             {
  1439.                 if  (oneSym && oneSym != use)
  1440.                 {
  1441.                     /* The name is ambiguous */
  1442.  
  1443.                     stComp->cmpErrorQSS(ERRambigUse, oneSym, use);
  1444.  
  1445.                     return  stErrSymbol;
  1446.                 }
  1447.  
  1448.                 oneSym = use;
  1449.             }
  1450.         }
  1451.     }
  1452.  
  1453.     useRef = uses;
  1454.  
  1455.     /* Did we find one specific import? */
  1456.  
  1457.     if  (oneSym)
  1458.         return  oneSym;
  1459.  
  1460.     /* Did we find zero or one names from namespace-wide imports? */
  1461.  
  1462.     if  (allSym2 == NULL)
  1463.         return  allSym1;
  1464.  
  1465.     /* The name is ambiguous */
  1466.  
  1467.     stComp->cmpErrorQSS(ERRambigUse, allSym1, allSym2);
  1468.  
  1469.     return  stErrSymbol;
  1470. }
  1471.  
  1472. /*****************************************************************************
  1473.  *
  1474.  *  Lookup a name in the current context.
  1475.  */
  1476.  
  1477. SymDef              symTab::stLookupSym(Ident name, name_space symNS)
  1478. {
  1479.     Compiler        ourComp = stComp;
  1480.  
  1481.     SymDef          curCls;
  1482.     SymDef          curNS;
  1483.     UseList         uses;
  1484.     SymDef          sym;
  1485.  
  1486. AGAIN:
  1487.  
  1488.     /* Check the local scope first, if we're in one */
  1489.  
  1490.     if  (ourComp->cmpCurScp)
  1491.     {
  1492.         SymDef          lclScp;
  1493.  
  1494.         for (lclScp = ourComp->cmpCurScp;
  1495.              lclScp;
  1496.              lclScp = lclScp->sdParent)
  1497.         {
  1498.             /* Check for an implicit class scope */
  1499.  
  1500.             sym = stLookupLclSym(name, lclScp);
  1501.             if  (sym)
  1502.                 return  sym;
  1503.         }
  1504.     }
  1505.  
  1506.     /* Now check the current class, if we're in one */
  1507.  
  1508.     for (curCls = ourComp->cmpCurCls; curCls; curCls = curCls->sdParent)
  1509.     {
  1510.         if  (curCls->sdSymKind == SYM_CLASS)
  1511.         {
  1512.             if  (curCls->sdName == name && (symNS & NS_TYPE))
  1513.                 return  curCls;
  1514.  
  1515.             sym = stLookupAllCls(name, curCls, symNS, CS_DECLSOON);
  1516.             if  (sym)
  1517.             {
  1518.                 if  (sym->sdNameSpace & symNS)
  1519.                     return  sym;
  1520.             }
  1521.         }
  1522.         else
  1523.         {
  1524.             if  (curCls->sdSymKind != SYM_ENUM)
  1525.                 break;
  1526.             if  (symNS & NS_NORM)
  1527.             {
  1528.                 sym = stLookupScpSym(name, curCls);
  1529.                 if  (sym)
  1530.                     return  sym;
  1531.             }
  1532.         }
  1533.     }
  1534.  
  1535.     /* Look in the current namespace and its parents (along with "using"'s) */
  1536.  
  1537.     for (curNS = ourComp->cmpCurNS, uses = ourComp->cmpCurUses;
  1538.          curNS;
  1539.          curNS = curNS->sdParent)
  1540.     {
  1541.         /* Look in the namespace itself */
  1542.  
  1543.         sym = stLookupNspSym(name, symNS, curNS);
  1544.         if  (sym)
  1545.         {
  1546.             if  (sym->sdNameSpace & symNS)
  1547.             {
  1548.                 // BIZARRE HACK: If we've found a namespace symbol, look
  1549.                 //               in the "using" scope also, and if we
  1550.                 //               find a symbol there choose it instead.
  1551.  
  1552.                 if  (sym->sdSymKind == SYM_NAMESPACE)
  1553.                 {
  1554.                     SymDef          use;
  1555.  
  1556.                     assert(uses && uses->ulAnchor && uses->ul.ulSym == curNS);
  1557.  
  1558.                     use = stSearchUsing(uses, name, symNS);
  1559.                     if  (use)
  1560.                         return  use;
  1561.                 }
  1562.  
  1563.                 return  sym;
  1564.             }
  1565.         }
  1566.  
  1567.         /* Each NS level should have its "using" anchor point */
  1568.  
  1569.         assert(uses && uses->ulAnchor && uses->ul.ulSym == curNS);
  1570.  
  1571.         sym = stSearchUsing(uses, name, symNS);
  1572.         if  (sym)
  1573.         {
  1574.             if  ((sym->sdNameSpace & symNS) || sym == stErrSymbol)
  1575.                 return  sym;
  1576.  
  1577.             while (!uses->ulAnchor)
  1578.             {
  1579.                 uses = uses->ulNext; assert(uses);
  1580.             }
  1581.         }
  1582.  
  1583.         /* Does the namespace itself match the name we're looking for? */
  1584.  
  1585.         if  (curNS->sdName == name && (symNS & NS_NORM))
  1586.             return  curNS;
  1587.     }
  1588.  
  1589.     /* There might be "using" clauses in effect at global scope */
  1590.  
  1591.     if  (uses)
  1592.     {
  1593.         sym = stSearchUsing(uses, name, symNS);
  1594.         if  (sym)
  1595.             return  sym;
  1596.     }
  1597.  
  1598. #if 0
  1599.  
  1600.     /* Are there any implicit outer scopes ? */
  1601.  
  1602.     for (curScp = ourComp->cmpOuterScp; curScp; curScp = curScp->sdParent)
  1603.     {
  1604.         assert(curScp->sdSymKind == SYM_SCOPE);
  1605.  
  1606.         sym = stLookupScpSym(name, curScp);
  1607.         if  (sym)
  1608.         {
  1609.             if  (sym->sdNameSpace & symNS)
  1610.                 return  sym;
  1611.         }
  1612.     }
  1613.  
  1614. #endif
  1615.  
  1616.     /*
  1617.         Here we have exhausted all the scopes. The last thing we try is to
  1618.         check whether we should look in the non-type namespace - if we're
  1619.         looking for a type we first try the type namespace and then the
  1620.         other one.
  1621.      */
  1622.  
  1623.     if  (symNS == NS_TYPE)
  1624.     {
  1625.         symNS = NS_NORM;
  1626.         goto AGAIN;
  1627.     }
  1628.  
  1629.     return  NULL;
  1630. }
  1631.  
  1632. /*****************************************************************************
  1633.  *
  1634.  *  Given a symbol, locate the symbol table it belongs to.
  1635.  */
  1636.  
  1637. SymTab              SymDefRec::sdOwnerST()
  1638. {
  1639.     SymDef          sym;
  1640.  
  1641.     // UNDONE: How the heck do we figure out which symbol table this symbol
  1642.     // UNDONE: belongs to? For now, just use the global one ....
  1643.  
  1644.     for (sym = this; sym->sdSymKind != SYM_NAMESPACE; sym = sym->sdParent)
  1645.     {
  1646.         assert(sym);
  1647.     }
  1648.  
  1649.     return  sym->sdNS.sdnSymtab;
  1650. }
  1651.  
  1652. /*****************************************************************************
  1653.  *
  1654.  *  Given a symbol that represents a type name, return its type (these are
  1655.  *  created in a "lazy" as-needed fashion).
  1656.  */
  1657.  
  1658. TypDef              SymDefRec::sdTypeMake()
  1659. {
  1660.     assert(this);
  1661.  
  1662.     if  (!sdType)
  1663.     {
  1664.         SymTab          stab;
  1665.         TypDef          type;
  1666.  
  1667.         stab = sdOwnerST();
  1668.  
  1669.         switch (sdSymKind)
  1670.         {
  1671.         case SYM_TYPEDEF:
  1672.             type = stab->stNewTdefType(this);
  1673.             break;
  1674.  
  1675.         case SYM_ENUM:
  1676.             type = stab->stNewEnumType(this);
  1677.             break;
  1678.  
  1679.         case SYM_CLASS:
  1680.             type = stab->stNewClsType(this);
  1681.             break;
  1682.  
  1683.         default:
  1684.             NO_WAY(!"unexpected type kind in sdTypeMake()");
  1685.         }
  1686.  
  1687.         sdType = type;
  1688.     }
  1689.  
  1690.     return  sdType;
  1691. }
  1692.  
  1693. /*****************************************************************************
  1694.  *
  1695.  *  Look for an overloaded function with a matching argument list.
  1696.  */
  1697.  
  1698. SymDef              symTab::stFindOvlFnc(SymDef fsym, TypDef type)
  1699. {
  1700.     while (fsym)
  1701.     {
  1702.         TypDef          ftyp;
  1703.  
  1704.         assert(fsym->sdSymKind == SYM_FNC);
  1705.  
  1706.         ftyp = fsym->sdType;
  1707.         assert(ftyp && ftyp->tdTypeKind == TYP_FNC);
  1708.  
  1709.         /* Do the argument lists match? */
  1710.  
  1711.         if  (stArgsMatch(ftyp, type))
  1712.         {
  1713.             /* For conversion operators the return types must match as well */
  1714.  
  1715.             if  (fsym->sdFnc.sdfConvOper)
  1716.             {
  1717.                 assert(fsym->sdFnc.sdfOper == OVOP_CONV_IMP ||
  1718.                        fsym->sdFnc.sdfOper == OVOP_CONV_EXP);
  1719.  
  1720.                 if  (stMatchTypes(ftyp->tdFnc.tdfRett, type->tdFnc.tdfRett))
  1721.                     break;
  1722.             }
  1723.             else
  1724.             {
  1725.                 assert(fsym->sdFnc.sdfOper != OVOP_CONV_IMP &&
  1726.                        fsym->sdFnc.sdfOper != OVOP_CONV_EXP);
  1727.  
  1728.                 break;
  1729.             }
  1730.         }
  1731.  
  1732.         fsym = fsym->sdFnc.sdfNextOvl;
  1733.     }
  1734.  
  1735.     return fsym;
  1736. }
  1737.  
  1738. /*****************************************************************************
  1739.  *
  1740.  *  Look for an overloaded property with a matching type.
  1741.  */
  1742.  
  1743. SymDef              symTab::stFindOvlProp(SymDef psym, TypDef type)
  1744. {
  1745.     while (psym)
  1746.     {
  1747.         TypDef          ptyp = psym->sdType;
  1748.  
  1749.         assert(psym->sdSymKind == SYM_PROP);
  1750.  
  1751.         /* Are both indexed/non-indexed properties? */
  1752.  
  1753.         if  (ptyp->tdTypeKind != TYP_FNC &&
  1754.              type->tdTypeKind != TYP_FNC)
  1755.              break;
  1756.  
  1757.         if  (ptyp->tdTypeKind == type->tdTypeKind && stArgsMatch(ptyp, type))
  1758.             break;
  1759.  
  1760.         psym = psym->sdProp.sdpNextOvl;
  1761.     }
  1762.  
  1763.     return psym;
  1764. }
  1765.  
  1766. /*****************************************************************************
  1767.  *
  1768.  *  Look for an overloaded property with a matching type.
  1769.  */
  1770.  
  1771. SymDef              symTab::stFindSameProp(SymDef psym, TypDef type)
  1772. {
  1773.     while (psym)
  1774.     {
  1775.         assert(psym->sdSymKind == SYM_PROP);
  1776.  
  1777.         if  (stMatchTypes(psym->sdType, type))
  1778.             break;
  1779.  
  1780.         psym = psym->sdProp.sdpNextOvl;
  1781.     }
  1782.  
  1783.     return psym;
  1784. }
  1785.  
  1786. /*****************************************************************************
  1787.  *
  1788.  *  Convert an overloaded operator / constructor name into an index.
  1789.  */
  1790.  
  1791. ovlOpFlavors        symTab::stOvlOperIndex(tokens token, unsigned argCnt)
  1792. {
  1793.     /* For now we do a pretty lame thing here */
  1794.  
  1795.     if  (token < tkComma)
  1796.     {
  1797.         switch (token)
  1798.         {
  1799.         case OPNM_CTOR_INST: return OVOP_CTOR_INST;
  1800.         case OPNM_CTOR_STAT: return OVOP_CTOR_STAT;
  1801.  
  1802.         case OPNM_FINALIZER: return OVOP_FINALIZER;
  1803.  
  1804.         case OPNM_CONV_IMP:  return OVOP_CONV_IMP;
  1805.         case OPNM_CONV_EXP:  return OVOP_CONV_EXP;
  1806.  
  1807.         case OPNM_EQUALS:    return OVOP_EQUALS;
  1808.         case OPNM_COMPARE:   return OVOP_COMPARE;
  1809.  
  1810.         case OPNM_PROP_GET:  return OVOP_PROP_GET;
  1811.         case OPNM_PROP_SET:  return OVOP_PROP_SET;
  1812.         }
  1813.     }
  1814.     else
  1815.     {
  1816.         switch (token)
  1817.         {
  1818.         case tkAdd:          return (argCnt == 2) ? OVOP_ADD : OVOP_NOP;
  1819.         case tkSub:          return (argCnt == 2) ? OVOP_SUB : OVOP_NEG;
  1820.         case tkMul:          return OVOP_MUL;
  1821.         case tkDiv:          return OVOP_DIV;
  1822.         case tkPct:          return OVOP_MOD;
  1823.  
  1824.         case tkOr:           return OVOP_OR;
  1825.         case tkXor:          return OVOP_XOR;
  1826.         case tkAnd:          return OVOP_AND;
  1827.  
  1828.         case tkLsh:          return OVOP_LSH;
  1829.         case tkRsh:          return OVOP_RSH;
  1830.         case tkRsz:          return OVOP_RSZ;
  1831.  
  1832.         case tkConcat:       return OVOP_CNC;
  1833.  
  1834.         case tkEQ:           return OVOP_EQ;
  1835.         case tkNE:           return OVOP_NE;
  1836.  
  1837.         case tkLT:           return OVOP_LT;
  1838.         case tkLE:           return OVOP_LE;
  1839.         case tkGE:           return OVOP_GE;
  1840.         case tkGT:           return OVOP_GT;
  1841.  
  1842.         case tkLogAnd:       return OVOP_LOG_AND;
  1843.         case tkLogOr:        return OVOP_LOG_OR;
  1844.  
  1845.         case tkBang:         return OVOP_LOG_NOT;
  1846.         case tkTilde:        return OVOP_NOT;
  1847.  
  1848.         case tkInc:          return OVOP_INC;
  1849.         case tkDec:          return OVOP_DEC;
  1850.  
  1851.         case tkAsg:          return OVOP_ASG;
  1852.  
  1853.         case tkAsgAdd:       return OVOP_ASG_ADD;
  1854.         case tkAsgSub:       return OVOP_ASG_SUB;
  1855.         case tkAsgMul:       return OVOP_ASG_MUL;
  1856.         case tkAsgDiv:       return OVOP_ASG_DIV;
  1857.         case tkAsgMod:       return OVOP_ASG_MOD;
  1858.  
  1859.         case tkAsgAnd:       return OVOP_ASG_AND;
  1860.         case tkAsgXor:       return OVOP_ASG_XOR;
  1861.         case tkAsgOr:        return OVOP_ASG_OR;
  1862.  
  1863.         case tkAsgLsh:       return OVOP_ASG_LSH;
  1864.         case tkAsgRsh:       return OVOP_ASG_RSH;
  1865.         case tkAsgRsz:       return OVOP_ASG_RSZ;
  1866.  
  1867.         case tkAsgCnc:       return OVOP_ASG_CNC;
  1868.         }
  1869.     }
  1870.  
  1871. #ifdef  DEBUG
  1872.     printf("Unexpected operator name: '%s'\n", stComp->cmpGlobalHT->tokenToIdent(token)->idSpelling());
  1873.     NO_WAY(!"bad oper name");
  1874. #endif
  1875.  
  1876.     return  OVOP_NONE;
  1877. }
  1878.  
  1879. /*****************************************************************************
  1880.  *
  1881.  *  Convert an overloaded operator / constructor index to a name.
  1882.  */
  1883.  
  1884. Ident               symTab::stOvlOperIdent(ovlOpFlavors oper)
  1885. {
  1886.     static
  1887.     tokens          optoks[] =
  1888.     {
  1889.         tkNone,             // OVOP_NONE
  1890.  
  1891.         tkAdd,              // OVOP_ADD
  1892.         tkSub,              // OVOP_SUB
  1893.         tkMul,              // OVOP_MUL
  1894.         tkDiv,              // OVOP_DIV
  1895.         tkPct,              // OVOP_MOD
  1896.  
  1897.         tkOr,               // OVOP_OR
  1898.         tkXor,              // OVOP_XOR
  1899.         tkAnd,              // OVOP_AND
  1900.  
  1901.         tkLsh,              // OVOP_LSH
  1902.         tkRsh,              // OVOP_RSH
  1903.         tkRsz,              // OVOP_RSZ
  1904.  
  1905.         tkConcat,           // OVOP_ASG_CNC
  1906.  
  1907.         tkEQ,               // OVOP_EQ
  1908.         tkNE,               // OVOP_NE
  1909.  
  1910.         tkLT,               // OVOP_LT
  1911.         tkLE,               // OVOP_LE
  1912.         tkGE,               // OVOP_GE
  1913.         tkGT,               // OVOP_GT
  1914.  
  1915.         tkLogAnd,           // OVOP_AND
  1916.         tkLogOr,            // OVOP_OR
  1917.  
  1918.         tkBang,             // OVOP_NOT
  1919.         tkTilde,            // OVOP_LOG_NOT
  1920.  
  1921.         tkAdd,              // OVOP_NOP
  1922.         tkSub,              // OVOP_NEG
  1923.  
  1924.         tkInc,              // OVOP_INC
  1925.         tkDec,              // OVOP_DEC
  1926.  
  1927.         tkAsg,              // OVOP_ASG
  1928.  
  1929.         tkAsgAdd,           // OVOP_ASG_ADD
  1930.         tkAsgSub,           // OVOP_ASG_SUB
  1931.         tkAsgMul,           // OVOP_ASG_MUL
  1932.         tkAsgDiv,           // OVOP_ASG_DIV
  1933.         tkAsgMod,           // OVOP_ASG_MOD
  1934.  
  1935.         tkAsgAnd,           // OVOP_ASG_AND
  1936.         tkAsgXor,           // OVOP_ASG_XOR
  1937.         tkAsgOr,            // OVOP_ASG_OR
  1938.  
  1939.         tkAsgLsh,           // OVOP_ASG_LSH
  1940.         tkAsgRsh,           // OVOP_ASG_RSH
  1941.         tkAsgRsz,           // OVOP_ASG_RSZ
  1942.  
  1943.         tkAsgCnc,           // OVOP_ASG_CNC
  1944.  
  1945.         OPNM_CTOR_INST,     // OVOP_CTOR_INST
  1946.         OPNM_CTOR_STAT,     // OVOP_CTOR_STAT
  1947.  
  1948.         OPNM_FINALIZER,     // OVOP_FINALIZER
  1949.  
  1950.         OPNM_CONV_IMP,      // OVOP_CONV_IMP
  1951.         OPNM_CONV_EXP,      // OVOP_CONV_EXP
  1952.  
  1953.         OPNM_EQUALS,        // OVOP_EQUALS
  1954.         OPNM_COMPARE,       // OVOP_COMPARE
  1955.  
  1956.         OPNM_PROP_GET,      // OVOP_PROP_GET
  1957.         OPNM_PROP_SET,      // OVOP_PROP_SET
  1958.     };
  1959.  
  1960.     assert(oper < arraylen(optoks));
  1961.  
  1962.     assert(optoks[OVOP_ADD      ] == tkAdd         );
  1963.     assert(optoks[OVOP_SUB      ] == tkSub         );
  1964.     assert(optoks[OVOP_MUL      ] == tkMul         );
  1965.     assert(optoks[OVOP_DIV      ] == tkDiv         );
  1966.     assert(optoks[OVOP_MOD      ] == tkPct         );
  1967.  
  1968.     assert(optoks[OVOP_OR       ] == tkOr          );
  1969.     assert(optoks[OVOP_XOR      ] == tkXor         );
  1970.     assert(optoks[OVOP_AND      ] == tkAnd         );
  1971.  
  1972.     assert(optoks[OVOP_LSH      ] == tkLsh         );
  1973.     assert(optoks[OVOP_RSH      ] == tkRsh         );
  1974.     assert(optoks[OVOP_RSZ      ] == tkRsz         );
  1975.  
  1976.     assert(optoks[OVOP_CNC      ] == tkConcat      );
  1977.  
  1978.     assert(optoks[OVOP_EQ       ] == tkEQ          );
  1979.     assert(optoks[OVOP_NE       ] == tkNE          );
  1980.  
  1981.     assert(optoks[OVOP_LT       ] == tkLT          );
  1982.     assert(optoks[OVOP_LE       ] == tkLE          );
  1983.     assert(optoks[OVOP_GE       ] == tkGE          );
  1984.     assert(optoks[OVOP_GT       ] == tkGT          );
  1985.  
  1986.     assert(optoks[OVOP_LOG_AND  ] == tkLogAnd      );
  1987.     assert(optoks[OVOP_LOG_OR   ] == tkLogOr       );
  1988.  
  1989.     assert(optoks[OVOP_LOG_NOT  ] == tkBang        );
  1990.     assert(optoks[OVOP_NOT      ] == tkTilde       );
  1991.  
  1992.     assert(optoks[OVOP_NOP      ] == tkAdd         );
  1993.     assert(optoks[OVOP_NEG      ] == tkSub         );
  1994.  
  1995.     assert(optoks[OVOP_INC      ] == tkInc         );
  1996.     assert(optoks[OVOP_DEC      ] == tkDec         );
  1997.  
  1998.     assert(optoks[OVOP_ASG      ] == tkAsg         );
  1999.  
  2000.     assert(optoks[OVOP_ASG_ADD  ] == tkAsgAdd      );
  2001.     assert(optoks[OVOP_ASG_SUB  ] == tkAsgSub      );
  2002.     assert(optoks[OVOP_ASG_MUL  ] == tkAsgMul      );
  2003.     assert(optoks[OVOP_ASG_DIV  ] == tkAsgDiv      );
  2004.     assert(optoks[OVOP_ASG_MOD  ] == tkAsgMod      );
  2005.  
  2006.     assert(optoks[OVOP_ASG_AND  ] == tkAsgAnd      );
  2007.     assert(optoks[OVOP_ASG_XOR  ] == tkAsgXor      );
  2008.     assert(optoks[OVOP_ASG_OR   ] == tkAsgOr       );
  2009.  
  2010.     assert(optoks[OVOP_ASG_LSH  ] == tkAsgLsh      );
  2011.     assert(optoks[OVOP_ASG_RSH  ] == tkAsgRsh      );
  2012.     assert(optoks[OVOP_ASG_RSZ  ] == tkAsgRsz      );
  2013.  
  2014.     assert(optoks[OVOP_ASG_CNC  ] == tkAsgCnc      );
  2015.  
  2016.     assert(optoks[OVOP_CTOR_INST] == OPNM_CTOR_INST);
  2017.     assert(optoks[OVOP_CTOR_STAT] == OPNM_CTOR_STAT);
  2018.  
  2019.     assert(optoks[OVOP_FINALIZER] == OPNM_FINALIZER);
  2020.  
  2021.     assert(optoks[OVOP_CONV_IMP ] == OPNM_CONV_IMP );
  2022.     assert(optoks[OVOP_CONV_EXP ] == OPNM_CONV_EXP );
  2023.  
  2024.     assert(optoks[OVOP_EQUALS   ] == OPNM_EQUALS   );
  2025.     assert(optoks[OVOP_COMPARE  ] == OPNM_COMPARE  );
  2026.  
  2027.     assert(optoks[OVOP_PROP_GET ] == OPNM_PROP_GET );
  2028.     assert(optoks[OVOP_PROP_SET ] == OPNM_PROP_SET );
  2029.  
  2030.     return  stComp->cmpGlobalHT->tokenToIdent(optoks[oper]);
  2031. }
  2032.  
  2033. /*****************************************************************************
  2034.  *
  2035.  *  Declare an overloaded operator / constructor symbol.
  2036.  */
  2037.  
  2038. SymDef              symTab::stDeclareOper(ovlOpFlavors oper, SymDef scope)
  2039. {
  2040.     SymDef          memSym;
  2041. #if MGDDATA
  2042.     SymDef  []      memTab;
  2043. #else
  2044.     SymDef  *       memTab;
  2045.     size_t          memSiz;
  2046. #endif
  2047.  
  2048.     /* Make sure the overloaded operator table for the class is allocated */
  2049.  
  2050.     assert(scope && scope->sdSymKind == SYM_CLASS);
  2051.  
  2052.     memTab = scope->sdClass.sdcOvlOpers;
  2053.     if  (!memTab)
  2054.     {
  2055.         /* Allocate the overloaded operator table */
  2056.  
  2057. #if MGDDATA
  2058.         memTab = new managed SymDef[OVOP_COUNT];
  2059. #else
  2060.         size_t          size = (unsigned)OVOP_COUNT * sizeof(*memTab);
  2061.         memTab = (SymDef*)stAllocPerm->nraAlloc(size);
  2062.         memset(memTab, 0, size);
  2063. #endif
  2064.  
  2065.         /* Store the table in the class */
  2066.  
  2067.         scope->sdClass.sdcOvlOpers = memTab;
  2068.     }
  2069.  
  2070.     /* This function should never be called to add an overload */
  2071.  
  2072.     assert(oper < OVOP_COUNT); assert(memTab[oper] == NULL);
  2073.  
  2074.     /* Allocate the symbol and stick it in the table */
  2075.  
  2076. #if MGDDATA
  2077.  
  2078.     memSym = new SymDef;
  2079.  
  2080. #else
  2081.  
  2082.     memSiz = symbolSize(SYM_FNC);
  2083.     memSym = (SymDef)stAllocPerm->nraAlloc(memSiz);
  2084.  
  2085. #if SYMALLOC_DISP
  2086.     totSymSize += memSiz;
  2087. #endif
  2088.  
  2089.     memset(memSym, 0, memSiz);          // ISSUE: is this a good idea?
  2090.  
  2091. #endif
  2092.  
  2093.     memSym->sdName         = stOvlOperIdent(oper);
  2094.     memSym->sdSymKind      = SYM_FNC;
  2095.     memSym->sdNameSpace    = NS_NORM;
  2096.     memSym->sdParent       = scope;
  2097.     memSym->sdCompileState = CS_KNOWN;
  2098.  
  2099.     /* Add the member to the parent's list of kids */
  2100.  
  2101.     if  (scope->sdScope.sdScope.sdsChildLast)
  2102.         scope->sdScope.sdScope.sdsChildLast->sdNextInScope  = memSym;
  2103.     else
  2104.         scope->sdScope.sdScope.sdsChildList                 = memSym;
  2105.  
  2106.     scope->sdScope.sdScope.sdsChildLast = memSym;
  2107.  
  2108.     /* Remember that the member is an overloaded operator */
  2109.  
  2110.     memSym->sdFnc.sdfOper = oper; assert(memSym->sdFnc.sdfOper == oper);
  2111.  
  2112.     if  (oper == OVOP_CONV_EXP || oper == OVOP_CONV_IMP)
  2113.         memSym->sdFnc.sdfConvOper = true;
  2114.  
  2115.     /* Store the symbol in the operator table and return */
  2116.  
  2117.     memTab[oper] = memSym;
  2118.  
  2119.     return  memSym;
  2120. }
  2121.  
  2122. /*****************************************************************************/
  2123.