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

  1. /*****************************************************************************/
  2. #ifndef _INLINES_H_
  3. #define _INLINES_H_
  4. /*****************************************************************************/
  5. #ifndef _TREENODE_H_
  6. #include "treenode.h"
  7. #endif
  8. /*****************************************************************************
  9.  *
  10.  *  The low-level tree node allocation routines.
  11.  */
  12.  
  13. #ifdef  FAST
  14.  
  15. inline
  16. Tree                parser::parseAllocNode()
  17. {
  18.     Tree            node;
  19.  
  20.     node = (Tree)parseAllocPriv.nraAlloc(sizeof(*node));
  21.  
  22.     return  node;
  23. }
  24.  
  25. #endif
  26.  
  27. inline
  28. Tree                parser::parseCreateNameNode(Ident name)
  29. {
  30.     Tree            node = parseCreateNode(TN_NAME);
  31.  
  32.     node->tnName.tnNameId = name;
  33.  
  34.     return  node;
  35. }
  36.  
  37. inline
  38. Tree                parser::parseCreateUSymNode(SymDef sym, SymDef scp)
  39. {
  40.     Tree            node = parseCreateNode(TN_ANY_SYM);
  41.  
  42.     node->tnSym.tnSym = sym;
  43.     node->tnSym.tnScp = scp;
  44.  
  45.     return  node;
  46. }
  47.  
  48. inline
  49. Tree                parser::parseCreateOperNode(treeOps   op,
  50.                                                 Tree      op1,
  51.                                                 Tree      op2)
  52. {
  53.     Tree            node = parseCreateNode(op);
  54.  
  55.     node->tnOp.tnOp1 = op1;
  56.     node->tnOp.tnOp2 = op2;
  57.  
  58.     return  node;
  59. }
  60.  
  61. /*****************************************************************************
  62.  *
  63.  *  This belongs in comp.h, but tnVtypGet(), etc. are not available there.
  64.  */
  65.  
  66. inline
  67. TypDef              compiler::cmpDirectType(TypDef type)
  68. {
  69.     if  (type->tdTypeKind == TYP_TYPEDEF)
  70.         type = type->tdTypedef.tdtType;
  71.  
  72.     return  type;
  73. }
  74.  
  75. inline
  76. var_types           compiler::cmpDirectVtyp(TypDef type)
  77. {
  78.     var_types       vtp = type->tdTypeKindGet();
  79.  
  80.     if  (vtp == TYP_TYPEDEF)
  81.         vtp = type->tdTypedef.tdtType->tdTypeKindGet();
  82.  
  83.     return  vtp;
  84. }
  85.  
  86. inline
  87. TypDef              compiler::cmpActualType(TypDef type)
  88. {
  89.     if  (varTypeIsIndirect(type->tdTypeKindGet()))
  90.         type = cmpGetActualTP(type);
  91.  
  92.     return  type;
  93. }
  94.  
  95. inline
  96. var_types           compiler::cmpActualVtyp(TypDef type)
  97. {
  98.     var_types       vtp = type->tdTypeKindGet();
  99.  
  100.     if  (varTypeIsIndirect(type->tdTypeKindGet()))
  101.         vtp = cmpGetActualTP(type)->tdTypeKindGet();
  102.  
  103.     return  vtp;
  104. }
  105.  
  106. inline
  107. var_types           compiler::cmpSymbolVtyp(SymDef sym)
  108. {
  109.     TypDef          typ = sym->sdType;
  110.     var_types       vtp = typ->tdTypeKindGet();
  111.  
  112.     if  (varTypeIsIndirect(vtp))
  113.         vtp = cmpActualType(typ)->tdTypeKindGet();
  114.  
  115.     return  vtp;
  116. }
  117.  
  118. inline
  119. var_types           compiler::cmpEnumBaseVtp(TypDef type)
  120. {
  121.     assert(type->tdTypeKind == TYP_ENUM);
  122.  
  123.     return type->tdEnum.tdeIntType->tdTypeKindGet();
  124. }
  125.  
  126. inline
  127. bool                compiler::cmpIsByRefType(TypDef type)
  128. {
  129.     assert(type);
  130.  
  131.     if  (type->tdTypeKind == TYP_REF)
  132.     {
  133.         if  (type->tdRef.tdrBase->tdTypeKind != SYM_CLASS)
  134.             return  true;
  135.     }
  136.  
  137.     if  (type->tdTypeKind == TYP_TYPEDEF)
  138.         return  cmpIsByRefType(type->tdTypedef.tdtType);
  139.  
  140.     return  false;
  141. }
  142.  
  143. inline
  144. bool                compiler::cmpIsObjectVal(Tree expr)
  145. {
  146.     TypDef          type = expr->tnType;
  147.  
  148.     if  (expr->tnVtyp == TYP_TYPEDEF)
  149.         type = type->tdTypedef.tdtType;
  150.  
  151.     if  (type->tdTypeKind == TYP_PTR ||
  152.          type->tdTypeKind == TYP_REF)
  153.     {
  154.         return  (expr->tnType == cmpObjectRef());
  155.     }
  156.  
  157.     return false;
  158. }
  159.  
  160. inline
  161. bool                compiler::cmpIsStringVal(Tree expr)
  162. {
  163.     TypDef          type = expr->tnType;
  164.  
  165.     if  (expr->tnVtyp == TYP_TYPEDEF)
  166.         type = type->tdTypedef.tdtType;
  167.  
  168.     if  (type->tdTypeKind == TYP_REF)
  169.         return  (expr->tnType == cmpStringRef());
  170.  
  171.     if  (type->tdTypeKind == TYP_PTR)
  172.     {
  173.         var_types       vtyp = cmpActualVtyp(expr->tnType->tdRef.tdrBase);
  174.  
  175.         return  (vtyp == TYP_CHAR || vtyp == TYP_WCHAR);
  176.     }
  177.  
  178.     return false;
  179. }
  180.  
  181. inline
  182. bool                compiler::cmpDiffContext(TypDef cls1, TypDef cls2)
  183. {
  184.     assert(cls1 && cls1->tdTypeKind == TYP_CLASS);
  185.     assert(cls2 && cls2->tdTypeKind == TYP_CLASS);
  186.  
  187.     if  (cls1->tdClass.tdcContext == cls2->tdClass.tdcContext)
  188.         return  false;
  189.  
  190.     if  (cls1->tdClass.tdcContext == 2)
  191.         return   true;
  192.     if  (cls2->tdClass.tdcContext == 2)
  193.         return   true;
  194.  
  195.     return  false;
  196. }
  197.  
  198. inline
  199. bool                compiler::cmpMakeRawString(Tree expr, TypDef type, bool chkOnly)
  200. {
  201.     if  (expr->tnOper == TN_CNS_STR || expr->tnOper == TN_QMARK)
  202.         return  cmpMakeRawStrLit(expr, type, chkOnly);
  203.     else
  204.         return  false;
  205. }
  206.  
  207. inline
  208. void                compiler::cmpRecErrorPos(Tree expr)
  209. {
  210.     assert(expr);
  211.  
  212.     if (expr->tnLineNo)
  213.         cmpErrorTree = expr;
  214. }
  215.  
  216. /*****************************************************************************
  217.  *
  218.  *  Given a type, check whether it's un unmanaged array and if so decay its
  219.  *  type to a pointer to the first element of the array.
  220.  */
  221.  
  222. inline
  223. Tree                compiler::cmpDecayCheck(Tree expr)
  224. {
  225.     TypDef          type = expr->tnType;
  226.  
  227.     if      (type->tdTypeKind == TYP_ARRAY)
  228.     {
  229.         if  (!type->tdIsManaged)
  230.             expr = cmpDecayArray(expr);
  231.     }
  232.     else if (type->tdTypeKind == TYP_TYPEDEF)
  233.     {
  234.         expr->tnType = type->tdTypedef.tdtType;
  235.         expr->tnVtyp = expr->tnType->tdTypeKindGet();
  236.     }
  237.  
  238.     return  expr;
  239. }
  240.  
  241. /*****************************************************************************
  242.  *
  243.  *  Main public entry point to bind an expression tree.
  244.  */
  245.  
  246. inline
  247. Tree                compiler::cmpBindExpr(Tree expr)
  248. {
  249.     Tree            bound;
  250.     unsigned        saveln;
  251.  
  252.     /* Save the current line# and set it to 0 for the call to the binder */
  253.  
  254.     saveln = cmpScanner->scanGetSourceLno(); cmpScanner->scanSetTokenPos(0);
  255.  
  256. #ifdef DEBUG
  257.     if  (cmpConfig.ccVerbose >= 3) { printf("Binding:\n"); cmpParser->parseDispTree(expr ); }
  258. #endif
  259.  
  260.     bound = cmpBindExprRec(expr);
  261.  
  262. #ifdef DEBUG
  263.     if  (cmpConfig.ccVerbose >= 3) { printf("Bound:  \n"); cmpParser->parseDispTree(bound); printf("\n"); }
  264. #endif
  265.  
  266.     bound->tnLineNo = expr->tnLineNo;
  267. //  bound->tnColumn = expr->tnColumn;
  268.  
  269.     /* Restore the current line# before returning */
  270.  
  271.     cmpScanner->scanSetTokenPos(saveln);
  272.  
  273.     return  bound;
  274. }
  275.  
  276. /*****************************************************************************
  277.  *
  278.  *  Given a TYP_REF type, returns the class type it refers to, after making
  279.  *  sure the class is defined.
  280.  */
  281.  
  282. inline
  283. TypDef              compiler::cmpGetRefBase(TypDef reftyp)
  284. {
  285.     TypDef          clsTyp;
  286.  
  287.     assert(reftyp->tdTypeKind == TYP_REF ||
  288.            reftyp->tdTypeKind == TYP_PTR);
  289.     clsTyp = cmpActualType(reftyp->tdRef.tdrBase);
  290.  
  291.     /* Make sure the class is defined */
  292.  
  293.     if  (clsTyp->tdTypeKind == TYP_CLASS)
  294.         cmpDeclSym(clsTyp->tdClass.tdcSymbol);
  295.  
  296.     return  clsTyp;
  297. }
  298.  
  299. /*****************************************************************************
  300.  *
  301.  *  Look for an overloaded operator / constructor in the given scope.
  302.  */
  303.  
  304. inline
  305. SymDef              symTab::stLookupOper(ovlOpFlavors oper, SymDef scope)
  306. {
  307.     assert(oper < OVOP_COUNT);
  308.     assert(scope && scope->sdSymKind == SYM_CLASS);
  309.  
  310.     if  (scope->sdCompileState < CS_DECLARED)
  311.         stComp->cmpDeclSym(scope);
  312.  
  313.     if  (scope->sdClass.sdcOvlOpers)
  314.         return  scope->sdClass.sdcOvlOpers[oper];
  315.     else
  316.         return  NULL;
  317. }
  318.  
  319. /*****************************************************************************
  320.  *
  321.  *  Same as stLookupOper() but doesn't force the class to be in declared state.
  322.  */
  323.  
  324. inline
  325. SymDef              symTab::stLookupOperND(ovlOpFlavors oper, SymDef scope)
  326. {
  327.     assert(oper < OVOP_COUNT);
  328.     assert(scope && scope->sdSymKind == SYM_CLASS);
  329.  
  330.     if  (scope->sdClass.sdcOvlOpers)
  331.         return  scope->sdClass.sdcOvlOpers[oper];
  332.     else
  333.         return  NULL;
  334. }
  335.  
  336. /*****************************************************************************
  337.  *
  338.  *  Bring the given symbol to "declared" state. This function can be called
  339.  *  pretty much at will (i.e. recursively), it takes care of saving and
  340.  *  restoring compilation state.
  341.  */
  342.  
  343. inline
  344. bool                compiler::cmpDeclSym(SymDef sym)
  345. {
  346.     if  (sym->sdCompileState >= CS_DECLARED)
  347.         return  false;
  348.  
  349.     /* Is this an import class/enum? */
  350.  
  351.     if  (sym->sdIsImport)
  352.     {
  353.         assert(sym->sdSymKind == SYM_CLASS);
  354.  
  355.         sym->sdClass.sdcMDimporter->MDimportClss(0, sym, 0, true);
  356.  
  357.         return (sym->sdCompileState < CS_DECLARED);
  358.     }
  359.  
  360.     return  cmpDeclSymDoit(sym);
  361. }
  362.  
  363. inline
  364. bool                compiler::cmpDeclClsNoCns(SymDef sym)
  365. {
  366.     if  (sym->sdCompileState >= CS_DECLARED)
  367.         return  false;
  368.  
  369.     if  (sym->sdIsImport)
  370.         return  cmpDeclSym    (sym);
  371.     else
  372.         return  cmpDeclSymDoit(sym, true);
  373. }
  374.  
  375. /*****************************************************************************
  376.  *
  377.  *  Make sure the given class has been declared to the specified level, and
  378.  *  then look for a member with the specified name in it.
  379.  */
  380.  
  381. inline
  382. SymDef              symTab::stLookupAllCls(Ident            name,
  383.                                            SymDef           scope,
  384.                                            name_space       symNS,
  385.                                            compileStates    state)
  386. {
  387.     assert(scope && scope->sdSymKind == SYM_CLASS);
  388.  
  389.     /* Make sure the class type is defined */
  390.  
  391.     if  ((unsigned)scope->sdCompileState < (unsigned)state)
  392.     {
  393.         assert(state == CS_DECLSOON || state == CS_DECLARED);
  394.  
  395.         stComp->cmpDeclSym(scope);
  396.     }
  397.  
  398.     return  stFindInClass(name, scope, symNS);
  399. }
  400.  
  401. /*****************************************************************************
  402.  *
  403.  *  Return true if the given expression is a string value - note that we only
  404.  *  recognize values of the managed type String or string constants here.
  405.  */
  406.  
  407. inline
  408. bool                compiler::cmpIsStringExpr(Tree expr)
  409. {
  410.     if  (expr->tnType == cmpStringRef())
  411.         return  true;
  412.  
  413.     if  (expr->tnOper == TN_CNS_STR && !(expr->tnFlags & TNF_BEEN_CAST))
  414.         return  true;
  415.  
  416.     return  false;
  417. }
  418.  
  419. /*****************************************************************************
  420.  *
  421.  *  Similar to cmpCoerceExpr(), but if the operand is a constant it tries
  422.  *  to use the smallest possible type for the constant value.
  423.  */
  424.  
  425. inline
  426. Tree                compiler::cmpCastOfExpr(Tree expr, TypDef type, bool explicitCast)
  427. {
  428.     if  (type->tdTypeKind < expr->tnVtyp)
  429.         expr = cmpShrinkExpr(expr);
  430.  
  431.     return  cmpCoerceExpr(expr, type, explicitCast);
  432. }
  433.  
  434. /*****************************************************************************
  435.  *
  436.  *  Set the current error reporing position to the given compunit and line#.
  437.  */
  438.  
  439. inline
  440. void                compiler::cmpSetErrPos(DefSrc def, SymDef compUnit)
  441. {
  442.     cmpErrorComp = compUnit;
  443.     cmpErrorTree = NULL;
  444.  
  445.     cmpScanner->scanSetTokenPos(compUnit, def->dsdSrcLno);
  446. }
  447.  
  448. /*****************************************************************************
  449.  *
  450.  *  Bind a name reference, expand property use unless target of assignment.
  451.  */
  452.  
  453. inline
  454. Tree                compiler::cmpBindNameUse(Tree expr, bool isCall, bool classOK)
  455. {
  456.     unsigned        flags = expr->tnFlags;
  457.  
  458.     expr = cmpBindName(expr, isCall, classOK);
  459.  
  460.     /* Is this a property reference? */
  461.  
  462.     if  (expr->tnOper == TN_PROPERTY)
  463.     {
  464.         if  (!(flags & TNF_ASG_DEST))
  465.             expr = cmpBindProperty(expr, NULL, NULL);
  466.     }
  467.  
  468.     return  expr;
  469. }
  470.  
  471. /*****************************************************************************
  472.  *
  473.  *  Check whether the given type is an intrinsic type and if so, return its
  474.  *  corresponding value type. Otherwise return NULL.
  475.  */
  476.  
  477. inline
  478. TypDef              compiler::cmpCheck4valType(TypDef type)
  479. {
  480.     if  (type->tdTypeKind > TYP_lastIntrins)
  481.         return  NULL;
  482.     else
  483.         return  cmpFindStdValType(type->tdTypeKindGet());
  484. }
  485.  
  486. /*****************************************************************************
  487.  *
  488.  *  Look for a specific entry in the given "extra info" list.
  489.  */
  490.  
  491. inline
  492. SymXinfoLnk         compiler::cmpFindLinkInfo(SymXinfo infoList)
  493. {
  494.     if  (infoList)
  495.     {
  496.         infoList = cmpFindXtraInfo(infoList, XI_LINKAGE);
  497.         if  (infoList)
  498.             return  (SymXinfoLnk)infoList;
  499.     }
  500.  
  501.     return  NULL;
  502. }
  503.  
  504. inline
  505. SymXinfoSec         compiler::cmpFindSecSpec(SymXinfo infoList)
  506. {
  507.     if  (infoList)
  508.     {
  509.         infoList = cmpFindXtraInfo(infoList, XI_SECURITY);
  510.         if  (infoList)
  511.             return  (SymXinfoSec)infoList;
  512.     }
  513.  
  514.     return  NULL;
  515. }
  516.  
  517. inline
  518. SymXinfoCOM         compiler::cmpFindMarshal(SymXinfo infoList)
  519. {
  520.     if  (infoList)
  521.     {
  522.         infoList = cmpFindXtraInfo(infoList, XI_MARSHAL);
  523.         if  (infoList)
  524.             return  (SymXinfoCOM)infoList;
  525.     }
  526.  
  527.     return  NULL;
  528. }
  529.  
  530. inline
  531. SymXinfoSym         compiler::cmpFindSymInfo(SymXinfo infoList, xinfoKinds kind)
  532. {
  533.     assert(kind == XI_UNION_TAG ||
  534.            kind == XI_UNION_MEM);
  535.  
  536.     if  (infoList)
  537.     {
  538.         infoList = cmpFindXtraInfo(infoList, kind);
  539.         if  (infoList)
  540.             return  (SymXinfoSym)infoList;
  541.     }
  542.  
  543.     return  NULL;
  544. }
  545.  
  546. inline
  547. SymXinfoAtc         compiler::cmpFindATCentry(SymXinfo infoList, atCommFlavors flavor)
  548. {
  549.     while   (infoList)
  550.     {
  551.         if  (infoList->xiKind == XI_ATCOMMENT)
  552.         {
  553.             SymXinfoAtc     entry = (SymXinfoAtc)infoList;
  554.  
  555.             if  (entry->xiAtcInfo->atcFlavor == flavor)
  556.                 return  entry;
  557.         }
  558.  
  559.         infoList = infoList->xiNext;
  560.     }
  561.  
  562.     return  NULL;
  563. }
  564.  
  565. /*****************************************************************************
  566.  *
  567.  *  Convert between an alignment value and a more compact representation.
  568.  */
  569.  
  570. #ifndef __SMC__
  571. extern
  572. BYTE                cmpAlignDecodes[6];
  573. #endif
  574.  
  575. inline
  576. size_t              compiler::cmpDecodeAlign(unsigned alignVal)
  577. {
  578.     assert(alignVal && alignVal < arraylen(cmpAlignDecodes));
  579.  
  580.     return  cmpAlignDecodes[alignVal];
  581. }
  582.  
  583. #ifndef __SMC__
  584. extern
  585. BYTE                cmpAlignEncodes[17];
  586. #endif
  587.  
  588. inline
  589. unsigned            compiler::cmpEncodeAlign(size_t   alignSiz)
  590. {
  591.     assert(alignSiz ==  1 ||
  592.            alignSiz ==  2 ||
  593.            alignSiz ==  4 ||
  594.            alignSiz ==  8 ||
  595.            alignSiz == 16);
  596.  
  597.     return  cmpAlignEncodes[alignSiz];
  598. }
  599.  
  600. /*****************************************************************************
  601.  *
  602.  *  Check access to the given symbol - delegates all the "real" work to
  603.  *  a non-inline method.
  604.  */
  605.  
  606. inline
  607. bool                compiler::cmpCheckAccess(SymDef sym)
  608. {
  609.     if  (sym->sdAccessLevel == ACL_PUBLIC || sym->sdSymKind == SYM_NAMESPACE)
  610.         return  true;
  611.     else
  612.         return  cmpCheckAccessNP(sym);
  613. }
  614.  
  615. /*****************************************************************************
  616.  *
  617.  *  Bind the type of the given expression.
  618.  */
  619.  
  620. inline
  621. TypDef              compiler::cmpBindExprType(Tree expr)
  622. {
  623.     TypDef          type = expr->tnType;
  624.  
  625.     cmpBindType(type, false, false);
  626.  
  627.     expr->tnVtyp = type->tdTypeKindGet();
  628.  
  629.     return  type;
  630. }
  631.  
  632. /*****************************************************************************
  633.  *
  634.  *  Return true if the given symbol/type denotes an anonymous union.
  635.  */
  636.  
  637. inline
  638. bool                symTab::stIsAnonUnion(SymDef clsSym)
  639. {
  640.     assert(clsSym);
  641.  
  642.     return  clsSym->sdSymKind == SYM_CLASS && clsSym->sdClass.sdcAnonUnion;
  643. }
  644.  
  645. inline
  646. bool                symTab::stIsAnonUnion(TypDef clsTyp)
  647. {
  648.     assert(clsTyp);
  649.  
  650.     return  clsTyp->tdTypeKind == TYP_CLASS && clsTyp->tdClass.tdcSymbol->sdClass.sdcAnonUnion;
  651. }
  652.  
  653. /*****************************************************************************
  654.  *
  655.  *  Return the namespace that contains the given symbol.
  656.  */
  657.  
  658. inline
  659. SymDef              compiler::cmpSymbolNS(SymDef sym)
  660. {
  661.     assert(sym);
  662.  
  663.     while (sym->sdSymKind != SYM_NAMESPACE)
  664.     {
  665.         sym = sym->sdParent;
  666.  
  667.         assert(sym && (sym->sdSymKind == SYM_CLASS ||
  668.                        sym->sdSymKind == SYM_NAMESPACE));
  669.     }
  670.  
  671.     return  sym;
  672. }
  673.  
  674. /*****************************************************************************
  675.  *
  676.  *  Add a member definition/declaration entry to the given class.
  677.  */
  678.  
  679. inline
  680. void                compiler::cmpRecordMemDef(SymDef clsSym, ExtList decl)
  681. {
  682.     assert(clsSym && clsSym->sdSymKind == SYM_CLASS);
  683.     assert(decl && decl->dlExtended);
  684.  
  685.     if  (clsSym->sdClass.sdcMemDefList)
  686.         clsSym->sdClass.sdcMemDefLast->dlNext = decl;
  687.     else
  688.         clsSym->sdClass.sdcMemDefList         = decl;
  689.  
  690.     clsSym->sdClass.sdcMemDefLast = decl; decl->dlNext = NULL;
  691. }
  692.  
  693. /*****************************************************************************
  694.  *
  695.  *  Save/restore the current symbol table context information
  696.  */
  697.  
  698. inline
  699. void                compiler::cmpSaveSTctx(STctxSave & save)
  700. {
  701.     save.ctxsNS     = cmpCurNS;
  702.     save.ctxsCls    = cmpCurCls;
  703.     save.ctxsScp    = cmpCurScp;
  704.     save.ctxsUses   = cmpCurUses;
  705.     save.ctxsComp   = cmpCurComp;
  706.     save.ctxsFncSym = cmpCurFncSym;
  707.     save.ctxsFncTyp = cmpCurFncTyp;
  708. }
  709.  
  710. inline
  711. void                compiler::cmpRestSTctx(STctxSave & save)
  712. {
  713.     cmpCurNS     = save.ctxsNS;
  714.     cmpCurCls    = save.ctxsCls;
  715.     cmpCurScp    = save.ctxsScp;
  716.     cmpCurUses   = save.ctxsUses;
  717.     cmpCurComp   = save.ctxsComp;
  718.     cmpCurFncSym = save.ctxsFncSym;
  719.     cmpCurFncTyp = save.ctxsFncTyp;
  720. }
  721.  
  722. /*****************************************************************************
  723.  *
  724.  *  Return the closest "generic" (undimensioned) array type that corresponds
  725.  *  to the given managed array type.
  726.  */
  727.  
  728. inline
  729. TypDef              compiler::cmpGetBaseArray(TypDef type)
  730. {
  731.     assert(type);
  732.     assert(type->tdIsManaged);
  733.     assert(type->tdTypeKind == TYP_ARRAY);
  734.  
  735.     if  (type->tdIsUndimmed)
  736.         return  type;
  737.  
  738.     if  (!type->tdArr.tdaBase)
  739.     {
  740.         type->tdArr.tdaBase = cmpGlobalST->stNewGenArrTp(type->tdArr.tdaDcnt,
  741.                                                          type->tdArr.tdaElem,
  742.                                                    (bool)type->tdIsGenArray);
  743.     }
  744.  
  745.     return  type->tdArr.tdaBase;
  746. }
  747.  
  748. /*****************************************************************************
  749.  *
  750.  *  Return true if the give type is a reference to "Object".
  751.  */
  752.  
  753. inline
  754. bool                symTab::stIsObjectRef(TypDef type)
  755. {
  756.     return  type->tdTypeKind == TYP_REF && type->tdIsObjRef;
  757. }
  758.  
  759. /*****************************************************************************
  760.  *
  761.  *  Return the metadata name for the given operator.
  762.  */
  763.  
  764. #ifndef __SMC__
  765.  
  766. #ifdef  DEBUG
  767. extern
  768. const  ovlOpFlavors MDnamesChk[OVOP_COUNT];
  769. #endif
  770. extern
  771. const   char *      MDnamesStr[OVOP_COUNT];
  772.  
  773. #endif
  774.  
  775. inline
  776. const   char *      MDovop2name(ovlOpFlavors ovop)
  777. {
  778.     assert(ovop < arraylen(MDnamesChk));
  779.     assert(ovop < arraylen(MDnamesStr));
  780.  
  781.     assert(MDnamesChk[ovop] == ovop);
  782.  
  783.     return MDnamesStr[ovop];
  784. }
  785.  
  786. extern
  787. ovlOpFlavors        MDfindOvop (const char *name);
  788.  
  789. inline
  790. ovlOpFlavors        MDname2ovop(const char *name)
  791. {
  792.     if  (name[0] == 'o' &&
  793.          name[1] == 'p' && name[2] != 0)
  794.     {
  795.         return  MDfindOvop(name);
  796.     }
  797.     else
  798.         return  OVOP_NONE;
  799. }
  800.  
  801. /*****************************************************************************/
  802. #endif//_INLINES_H_
  803. /*****************************************************************************/
  804.