home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / dotNETSDK / SETUP.EXE / netfxsd1.cab / FL_inlines_h________.3643236F_FC70_11D3_A536_0090278A1BB8 < prev    next >
Encoding:
Text File  |  2001-03-20  |  19.5 KB  |  805 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 == 0 ||
  592.            alignSiz ==  1 ||
  593.            alignSiz ==  2 ||
  594.            alignSiz ==  4 ||
  595.            alignSiz ==  8 ||
  596.            alignSiz == 16);
  597.  
  598.     return  cmpAlignEncodes[alignSiz];
  599. }
  600.  
  601. /*****************************************************************************
  602.  *
  603.  *  Check access to the given symbol - delegates all the "real" work to
  604.  *  a non-inline method.
  605.  */
  606.  
  607. inline
  608. bool                compiler::cmpCheckAccess(SymDef sym)
  609. {
  610.     if  (sym->sdAccessLevel == ACL_PUBLIC || sym->sdSymKind == SYM_NAMESPACE)
  611.         return  true;
  612.     else
  613.         return  cmpCheckAccessNP(sym);
  614. }
  615.  
  616. /*****************************************************************************
  617.  *
  618.  *  Bind the type of the given expression.
  619.  */
  620.  
  621. inline
  622. TypDef              compiler::cmpBindExprType(Tree expr)
  623. {
  624.     TypDef          type = expr->tnType;
  625.  
  626.     cmpBindType(type, false, false);
  627.  
  628.     expr->tnVtyp = type->tdTypeKindGet();
  629.  
  630.     return  type;
  631. }
  632.  
  633. /*****************************************************************************
  634.  *
  635.  *  Return true if the given symbol/type denotes an anonymous union.
  636.  */
  637.  
  638. inline
  639. bool                symTab::stIsAnonUnion(SymDef clsSym)
  640. {
  641.     assert(clsSym);
  642.  
  643.     return  clsSym->sdSymKind == SYM_CLASS && clsSym->sdClass.sdcAnonUnion;
  644. }
  645.  
  646. inline
  647. bool                symTab::stIsAnonUnion(TypDef clsTyp)
  648. {
  649.     assert(clsTyp);
  650.  
  651.     return  clsTyp->tdTypeKind == TYP_CLASS && clsTyp->tdClass.tdcSymbol->sdClass.sdcAnonUnion;
  652. }
  653.  
  654. /*****************************************************************************
  655.  *
  656.  *  Return the namespace that contains the given symbol.
  657.  */
  658.  
  659. inline
  660. SymDef              compiler::cmpSymbolNS(SymDef sym)
  661. {
  662.     assert(sym);
  663.  
  664.     while (sym->sdSymKind != SYM_NAMESPACE)
  665.     {
  666.         sym = sym->sdParent;
  667.  
  668.         assert(sym && (sym->sdSymKind == SYM_CLASS ||
  669.                        sym->sdSymKind == SYM_NAMESPACE));
  670.     }
  671.  
  672.     return  sym;
  673. }
  674.  
  675. /*****************************************************************************
  676.  *
  677.  *  Add a member definition/declaration entry to the given class.
  678.  */
  679.  
  680. inline
  681. void                compiler::cmpRecordMemDef(SymDef clsSym, ExtList decl)
  682. {
  683.     assert(clsSym && clsSym->sdSymKind == SYM_CLASS);
  684.     assert(decl && decl->dlExtended);
  685.  
  686.     if  (clsSym->sdClass.sdcMemDefList)
  687.         clsSym->sdClass.sdcMemDefLast->dlNext = decl;
  688.     else
  689.         clsSym->sdClass.sdcMemDefList         = decl;
  690.  
  691.     clsSym->sdClass.sdcMemDefLast = decl; decl->dlNext = NULL;
  692. }
  693.  
  694. /*****************************************************************************
  695.  *
  696.  *  Save/restore the current symbol table context information
  697.  */
  698.  
  699. inline
  700. void                compiler::cmpSaveSTctx(STctxSave & save)
  701. {
  702.     save.ctxsNS     = cmpCurNS;
  703.     save.ctxsCls    = cmpCurCls;
  704.     save.ctxsScp    = cmpCurScp;
  705.     save.ctxsUses   = cmpCurUses;
  706.     save.ctxsComp   = cmpCurComp;
  707.     save.ctxsFncSym = cmpCurFncSym;
  708.     save.ctxsFncTyp = cmpCurFncTyp;
  709. }
  710.  
  711. inline
  712. void                compiler::cmpRestSTctx(STctxSave & save)
  713. {
  714.     cmpCurNS     = save.ctxsNS;
  715.     cmpCurCls    = save.ctxsCls;
  716.     cmpCurScp    = save.ctxsScp;
  717.     cmpCurUses   = save.ctxsUses;
  718.     cmpCurComp   = save.ctxsComp;
  719.     cmpCurFncSym = save.ctxsFncSym;
  720.     cmpCurFncTyp = save.ctxsFncTyp;
  721. }
  722.  
  723. /*****************************************************************************
  724.  *
  725.  *  Return the closest "generic" (undimensioned) array type that corresponds
  726.  *  to the given managed array type.
  727.  */
  728.  
  729. inline
  730. TypDef              compiler::cmpGetBaseArray(TypDef type)
  731. {
  732.     assert(type);
  733.     assert(type->tdIsManaged);
  734.     assert(type->tdTypeKind == TYP_ARRAY);
  735.  
  736.     if  (type->tdIsUndimmed)
  737.         return  type;
  738.  
  739.     if  (!type->tdArr.tdaBase)
  740.     {
  741.         type->tdArr.tdaBase = cmpGlobalST->stNewGenArrTp(type->tdArr.tdaDcnt,
  742.                                                          type->tdArr.tdaElem,
  743.                                                    (bool)type->tdIsGenArray);
  744.     }
  745.  
  746.     return  type->tdArr.tdaBase;
  747. }
  748.  
  749. /*****************************************************************************
  750.  *
  751.  *  Return true if the give type is a reference to "Object".
  752.  */
  753.  
  754. inline
  755. bool                symTab::stIsObjectRef(TypDef type)
  756. {
  757.     return  type->tdTypeKind == TYP_REF && type->tdIsObjRef;
  758. }
  759.  
  760. /*****************************************************************************
  761.  *
  762.  *  Return the metadata name for the given operator.
  763.  */
  764.  
  765. #ifndef __SMC__
  766.  
  767. #ifdef  DEBUG
  768. extern
  769. const  ovlOpFlavors MDnamesChk[OVOP_COUNT];
  770. #endif
  771. extern
  772. const   char *      MDnamesStr[OVOP_COUNT];
  773.  
  774. #endif
  775.  
  776. inline
  777. const   char *      MDovop2name(ovlOpFlavors ovop)
  778. {
  779.     assert(ovop < arraylen(MDnamesChk));
  780.     assert(ovop < arraylen(MDnamesStr));
  781.  
  782.     assert(MDnamesChk[ovop] == ovop);
  783.  
  784.     return MDnamesStr[ovop];
  785. }
  786.  
  787. extern
  788. ovlOpFlavors        MDfindOvop (const char *name);
  789.  
  790. inline
  791. ovlOpFlavors        MDname2ovop(const char *name)
  792. {
  793.     if  (name[0] == 'o' &&
  794.          name[1] == 'p' && name[2] != 0)
  795.     {
  796.         return  MDfindOvop(name);
  797.     }
  798.     else
  799.         return  OVOP_NONE;
  800. }
  801.  
  802. /*****************************************************************************/
  803. #endif//_INLINES_H_
  804. /*****************************************************************************/
  805.