/*** debwalk.c - walk bound expression tree and perform operations * */ /* * */ LOCAL bool_t NEAR FASTCALL Walk (bnode_t); LOCAL bool_t NEAR FASTCALL WalkAddrOf (bnode_t); LOCAL bool_t NEAR FASTCALL WalkArray (bnode_t); LOCAL bool_t NEAR FASTCALL WalkAssign (bnode_t); LOCAL bool_t NEAR FASTCALL WalkBang (bnode_t); LOCAL bool_t NEAR FASTCALL WalkBasePtr (bnode_t); LOCAL bool_t NEAR FASTCALL WalkBinary (bnode_t); LOCAL bool_t NEAR FASTCALL WalkBScope (bnode_t); LOCAL bool_t NEAR FASTCALL WalkByteOps (bnode_t); LOCAL bool_t NEAR FASTCALL WalkCast (bnode_t); LOCAL bool_t NEAR FASTCALL WalkCastBin (bnode_t); LOCAL bool_t NEAR FASTCALL WalkConst (bnode_t); LOCAL bool_t NEAR FASTCALL WalkContext (bnode_t); LOCAL bool_t NEAR FASTCALL WalkDMember (bnode_t); LOCAL bool_t NEAR FASTCALL WalkDot (bnode_t); LOCAL bool_t NEAR FASTCALL WalkError (bnode_t); LOCAL bool_t NEAR FASTCALL WalkEmpty (bnode_t); LOCAL bool_t NEAR FASTCALL WalkFetch (bnode_t); LOCAL bool_t NEAR FASTCALL WalkFunction (bnode_t); LOCAL bool_t NEAR FASTCALL WalkLChild (bnode_t); LOCAL bool_t NEAR FASTCALL WalkRChild (bnode_t); LOCAL bool_t NEAR FASTCALL WalkPlusMinus (bnode_t); LOCAL bool_t NEAR FASTCALL WalkPMember (bnode_t); LOCAL bool_t NEAR FASTCALL WalkPostIncDec (bnode_t); LOCAL bool_t NEAR FASTCALL WalkPreIncDec (bnode_t); LOCAL bool_t NEAR FASTCALL WalkPointsTo (bnode_t); LOCAL bool_t NEAR FASTCALL WalkRelat (bnode_t); LOCAL bool_t NEAR FASTCALL WalkSegOp (bnode_t); LOCAL bool_t NEAR FASTCALL WalkSizeOf (bnode_t); LOCAL bool_t NEAR FASTCALL WalkSymbol (bnode_t); LOCAL bool_t NEAR FASTCALL WalkTypestr (bnode_t); LOCAL bool_t NEAR FASTCALL WalkUnary (bnode_t); LOCAL bool_t NEAR FASTCALL WalkUScope (bnode_t); /* * */ LOCAL bool_t NEAR PASCAL PushCXT (peval_t); LOCAL bool_t NEAR PASCAL GetCXTL (pnode_t); LOCAL bool_t NEAR PASCAL GetCXTFunction (pnode_t, pnode_t); // Walk Dispatch table LOCAL bool_t (NEAR FASTCALL *pWalk[]) (bnode_t) = { #define OPCNT(name, val) #define OPCDAT(opc) #define OPDAT(op, opfprec, opgprec, opclass, opbind, opeval, opwalk) opwalk, #include "debops.h" #undef OPDAT #undef OPCDAT #undef OPCNT }; #ifdef WIN32 extern uchar F_level[COPS_EXPR]; #else extern uchar _based(_segname("_CODE")) F_level[COPS_EXPR]; #endif #ifdef WIN32 extern uchar G_level[COPS_EXPR]; #else extern uchar _based(_segname("_CODE")) G_level[COPS_EXPR]; #endif LOCAL char * PchString; LOCAL int CchString; LOCAL int CchStringMax; LOCAL bool_t FPrototype = TRUE; LOCAL bool_t FInScope = FALSE; typedef struct { HDR_TYPE Hdr; char Buf[256]; } FORMATBUF; /** DoGetCXTL - Gets a list of symbols and contexts for expression * * status = DoGetCXTL (phTM, phCXTL) * * Entry phTM = pointer to handle to expression state structure * phCXTL = pointer to handle for CXT list buffer * * Exit *phCXTL = handle for CXT list buffer * * Returns EENOERROR if no error * status code if error */ ushort PASCAL DoGetCXTL (PHTM phTM, PHCXTL phCXTL) { ushort retval = EECATASTROPHIC; // lock the expression state structure and copy the context package DASSERT (*phTM != 0); if (*phTM != 0) { DASSERT(pExState == NULL); pExState = MHMemLock (*phTM); if ((pExState->state.parse_ok == TRUE) && (pExState->state.bind_ok == TRUE)) { if ((hCxtl = MHMemAllocate (sizeof (CXTL) + 5 * sizeof (HCS))) == 0) { pExState->err_num = ERR_NOMEMORY; MHMemUnLock (*phTM); pExState = NULL; *phCXTL = hCxtl; return (EEGENERAL); } else { pCxtl = MHMemLock (hCxtl); mCxtl = 5; pCxtl->CXT = pExState->cxt; pCxtl->cHCS = 0; } pTree = MHMemLock (pExState->hETree); if (GetCXTL (pnodeOfbnode(pTree->start_node))) { retval = EENOERROR; } else { retval = EEGENERAL; } *phCXTL = hCxtl; MHMemUnLock (hCxtl); MHMemUnLock (pExState->hETree); } MHMemUnLock (*phTM); pExState = NULL; } return (retval); } /** GetCXTL - get CXT list from bound expression tree * * fSuccess = GetCXTL (pn) * * Entry pn = pointer to node * hCxtl = handle of CXT list * pCxtl = pointer to CXT list * mCxtl = maximum number of context list entries * * Exit *phCXTL = handle for CXT list * * Returns TRUE if no error * FALSEif error */ LOCAL bool_t NEAR PASCAL GetCXTL (pnode_t pn) { PCXT oldCxt; bool_t retval; peval_t pv; // Recurse down the tree. pv = &pn->v[0]; switch (NODE_OP (pn)) { case OP_typestr: return (TRUE); case OP_const: case OP_ident: case OP_this: case OP_hsym: return (PushCXT (pv)); case OP_cast: return (GetCXTL (pnodeOfbnode(NODE_RCHILD (pn)))); case OP_function: return (GetCXTFunction ( pnodeOfbnode(NODE_LCHILD (pn)), pnodeOfbnode(NODE_RCHILD (pn)))); case OP_context: // Set the new context for evaluation of the remainder of this // part of the tree oldCxt = pCxt; pCxt = SHpCXTFrompCXF ((PCXF)&pn->v[0]); retval = GetCXTL (pnodeOfbnode(NODE_LCHILD (pn))); pCxt = oldCxt; return (retval); // All other operators come through here. Recurse down the tree default: if (!GetCXTL (pnodeOfbnode(NODE_LCHILD (pn)))) return (FALSE); if ((pn->pnRight != 0) && (!GetCXTL (pnodeOfbnode(NODE_RCHILD (pn))))) return (FALSE); return (TRUE); } } /** GetExpr - get expression from bound expression tree * * status = GetExpr (radix, phStr, pEnd); * * Entry radix = numeric radix for formatting * phStr = pointer to handle for formatted string * pEnd = pointer to int to receive index of char that ended parse * * Exit *phStr = handle for allocated expression * *pEnd = index of character that terminated parse * * Returns EENOERROR if no error * error number if */ EESTATUS PASCAL GetExpr ( PHTM phTM, EERADIX radix, PEEHSTR phStr, ushort FAR * pEnd ) { EESTATUS retval = EECATASTROPHIC; char FAR *pStr; DASSERT (*phTM != 0); if (*phTM == 0) { return retval; } DASSERT(pExState == NULL); pExState = MHMemLock (*phTM); if (pExState->state.bind_ok == TRUE) { pTree = MHMemLock(pExState->hETree); pExStr = MHMemLock(pExState->hExStr); PchString = NULL; CchStringMax = CchString = 0; retval = Walk((bnode_t)pTree->start_node); MHMemUnLock(pExState->hETree); MHMemUnLock(pExState->hExStr); if (retval == TRUE) { retval = EENOERROR; if ((*phStr = MHMemAllocate( CchString+1 )) != 0) { pStr = MHMemLock( *phStr ); _fmemcpy(pStr, PchString, CchString); *pEnd = CchString; MHMemUnLock( *phStr); } else { retval = EEGENERAL; *phStr = 0; } } else { retval = EEGENERAL; *phStr = 0; } if (PchString != NULL) { free(PchString); } PchString = NULL; } MHMemUnLock (*phTM); pExState = NULL; return (retval); } /** PushCXT - Push CXT list entry * * fSuccess = PushCXT (pv) * * Entry pv = pointer to evaluation * hCxtl = handle of CXT list * pCxtl = pointer to CXT list * mCxtl = maximum number of context list entries * * Exit CXT entry pushed * * Returns TRUE if no error * FALSE if error */ LOCAL bool_t NEAR PASCAL PushCXT (peval_t pv) { HCXTL nhCxtl; PCXTL npCxtl; uint lenIn; uint lenOut; DASSERT (pCxtl->cHCS <= mCxtl); if (mCxtl < pCxtl->cHCS) { // this is a catatrosphic error return (FALSE); } if (mCxtl == pCxtl->cHCS) { // grow CXT list lenIn = sizeof (CXTL) + mCxtl * sizeof (HCS); lenOut = sizeof (CXTL) + (mCxtl + 5) * sizeof (HCS); if ((nhCxtl = MHMemAllocate (lenOut)) == 0) { return (FALSE); } npCxtl = MHMemLock (nhCxtl); _fmemcpy (npCxtl, pCxtl, lenIn); mCxtl += 5; MHMemUnLock (hCxtl); MHMemFree (hCxtl); hCxtl = nhCxtl; pCxtl = npCxtl; } // in case of a constant we will return only the context information. // anything more than that doesn't make sense and since we // need to get context only information in the case of bp {..}.line // we needed to make this change. pCxtl->rgHCS[pCxtl->cHCS].hSym = pv->hSym; pCxtl->rgHCS[pCxtl->cHCS].CXT = *pCxt; pCxtl->cHCS++; return (TRUE); } LOCAL bool_t NEAR PASCAL GetCXTFunction (pnode_t pnLeft, pnode_t pnRight) { Unreferenced( pnLeft ); Unreferenced( pnRight ); return (FALSE); } LOCAL BOOLEAN WalkAppendString( char * pch, int cch ) /*++ Routine Description: Arguments: Return Value: --*/ { if (cch > CchStringMax - CchString) { PchString = (LPSTR)MHMemReAlloc((HDEP)PchString, CchStringMax + 256); if (PchString == NULL) { return FALSE; } CchStringMax += 256; } _fstrncpy(&PchString[CchString], pch, cch); CchString += cch; return TRUE; } /* WalkAppendString() */ /* * Functions to build a string from a TM Tree */ LOCAL bool_t NEAR FASTCALL Walk( bnode_t bn ) { return (*pWalk[NODE_OP(pnodeOfbnode(bn))])(bn); } LOCAL bool_t NEAR FASTCALL WalkLChild (bnode_t bn) { register bnode_t bnL = NODE_LCHILD (pnodeOfbnode(bn)); BOOL f = FALSE; if (F_level[NODE_OP(pnodeOfbnode(bn))] > F_level[NODE_OP(pnodeOfbnode(bnL))]) { if (!WalkAppendString("(", 1)) { return FALSE; } f = TRUE; } if (!((*pWalk[NODE_OP(pnodeOfbnode(bnL))])(bnL))) { return FALSE; } if (f) { return WalkAppendString(")", 1); } return TRUE; } /* WalkLChild() */ LOCAL bool_t NEAR FASTCALL WalkRChild (bnode_t bn) { register bnode_t bnR = NODE_RCHILD (pnodeOfbnode(bn)); BOOL f = FALSE; if (F_level[NODE_OP(pnodeOfbnode(bn))] > F_level[NODE_OP(pnodeOfbnode(bnR))]) { if (!WalkAppendString("(", 1)) { return FALSE; } f = TRUE; } if (!((*pWalk[NODE_OP(pnodeOfbnode(bnR))])(bnR))) { return FALSE; } if (f) { return WalkAppendString(")", 1); } return TRUE; } /* WalkRChild() */ /* * */ LOCAL bool_t NEAR FASTCALL WalkAddrOf (bnode_t bn) { return WalkAppendString("&", 1) && WalkLChild(bn); } /* WalkAddrOf() */ LOCAL bool_t NEAR FASTCALL WalkArray (bnode_t bn) { return WalkLChild(bn) && WalkAppendString("[", 1) && WalkRChild(bn) && WalkAppendString("]", 1); } /* WalkArray() */ LOCAL bool_t NEAR FASTCALL WalkAssign (bnode_t bn) { char * pch; int cch = 2; switch( NODE_OP (pnodeOfbnode(bn)) ) { case OP_eq: pch = "="; cch = 1; break; case OP_multeq: pch = "*="; break; case OP_diveq: pch = "/="; break; case OP_modeq: pch = "%="; break; case OP_pluseq: pch = "+="; break; case OP_minuseq: pch = "-="; break; case OP_shleq: pch = "<<="; cch = 3; break; case OP_shreq: pch = ">>="; cch = 3; break; case OP_andeq: pch = "&="; break; case OP_xoreq: pch = "^="; break; case OP_oreq: pch = "|="; break; default: DASSERT(FALSE); return FALSE; } return WalkLChild(bn) && WalkAppendString(pch, cch) && WalkRChild(bn); } /* WalkAssign() */ LOCAL bool_t NEAR FASTCALL WalkBang (bnode_t bn) { return WalkAppendString("!", 1) && WalkLChild(bn); } /* WalkBang() */ LOCAL bool_t NEAR FASTCALL WalkBasePtr (bnode_t bn) { DASSERT(FALSE); return TRUE; } LOCAL bool_t NEAR FASTCALL WalkBinary (bnode_t bn) { char * pch; int cch = 1; switch( NODE_OP (pnodeOfbnode(bn)) ) { case OP_mult: pch = "*"; break; case OP_div: pch = "/"; break; case OP_mod: pch = "%"; break; case OP_shl: pch = "<<"; cch = 2; break; case OP_shr: pch = ">>"; cch = 2; break; case OP_and: pch = "&"; break; case OP_xor: pch = "^"; break; case OP_or: pch = "|"; break; case OP_andand: pch = "&&"; cch = 2; break; case OP_oror: pch = "||"; cch = 2; break; default: DASSERT(FALSE); return FALSE; } return WalkLChild(bn) && WalkAppendString(pch, cch) && WalkRChild(bn); } /* WalkBinary() */ LOCAL bool_t NEAR FASTCALL WalkBScope (bnode_t bn) { bool_t fInScope = FInScope; bool_t fResult; FInScope = TRUE; fResult = WalkLChild(bn) && WalkAppendString("::", 2) && WalkRChild(bn); FInScope = fInScope; return fResult; } /* WalkBScope() */ LOCAL bool_t NEAR FASTCALL WalkByteOps (bnode_t bn) { char * pch; switch( NODE_OP (pnodeOfbnode(bn)) ) { case OP_by: pch = "BY "; break; case OP_wo: pch = "WO "; break; case OP_dw: pch = "DW "; break; default: DASSERT(FALSE); return FALSE; } return WalkAppendString(pch, 2) && WalkLChild(bn); } LOCAL bool_t NEAR FASTCALL WalkCast (bnode_t bn) { peval_t pv = &pnodeOfbnode(NODE_LCHILD(pnodeOfbnode(bn)))->v[0]; FORMATBUF fb; char * pch; unsigned int cch; pch = fb.Buf; cch = sizeof(fb.Buf); FormatType(pv, &pch, &cch, NULL, FPrototype, &fb.Hdr); do { pch--; } while (*pch == ' '); return WalkAppendString("(", 1) && WalkAppendString(fb.Buf, pch-fb.Buf+1) && WalkAppendString(")", 1) && WalkRChild(bn); } LOCAL bool_t NEAR FASTCALL WalkCastBin (bnode_t bn) { peval_t pv = &pnodeOfbnode(NODE_LCHILD(pnodeOfbnode(bn)))->v[0]; FORMATBUF fb; char * pch; unsigned int cch; bool_t f; pch = fb.Buf; cch = sizeof(fb.Buf); FormatType(pv, &pch, &cch, NULL, FPrototype, &fb.Hdr); do { pch--; } while (*pch == ' '); f = WalkAppendString("(", 1) && WalkAppendString(fb.Buf, pch-fb.Buf+1) && WalkAppendString(")", 1); if (!f) { return f; } switch( NODE_OP (pnodeOfbnode(bn)) ) { case OP_caststar: pch = "*"; break; case OP_castplus: pch = "+"; break; case OP_castminus: pch = "-"; break; case OP_castamp: pch = "&"; break; default: DASSERT(FALSE); return FALSE; } return WalkAppendString(pch, 1) && WalkRChild(bn); } LOCAL bool_t NEAR FASTCALL WalkConst (bnode_t bn) { peval_t pv = &pnodeOfbnode(bn)->v[0]; return WalkAppendString(pExStr + EVAL_ITOK(pv), EVAL_CBTOK(pv)); } /* WalkConst() */ LOCAL bool_t NEAR FASTCALL WalkContext (bnode_t bn) { peval_t pv = &pnodeOfbnode(bn)->v[0]; return WalkAppendString(pExStr + EVAL_ITOK(pv), EVAL_CBTOK(pv)) && WalkLChild(bn); } /* WalkContext() */ LOCAL bool_t NEAR FASTCALL WalkDMember (bnode_t bn) { DASSERT(FALSE); return TRUE; } LOCAL bool_t NEAR FASTCALL WalkDot (bnode_t bn) { return WalkLChild(bn) && WalkAppendString(".", 1) && WalkRChild(bn); } /* WalkDot() */ LOCAL bool_t NEAR FASTCALL WalkEmpty (register bnode_t bn) { return TRUE; } /* WalkEmpty */ LOCAL bool_t NEAR FASTCALL WalkError (register bnode_t bn) { DASSERT(FALSE); return TRUE; } LOCAL bool_t NEAR FASTCALL WalkFetch (bnode_t bn) { return WalkAppendString("*", 1) && WalkLChild(bn); } /* WalkFetch() */ LOCAL bool_t NEAR FASTCALL WalkFunction (bnode_t bn) { bnode_t bnT; BOOLEAN f = FALSE; bool_t fPrototype = FPrototype; FPrototype = FALSE; if (!WalkLChild(bn) || !WalkAppendString("(", 1)) { FPrototype = fPrototype; return FALSE; } FPrototype = fPrototype; for (bnT = NODE_RCHILD( pnodeOfbnode(bn) ); NODE_OP(pnodeOfbnode(bnT)) != OP_endofargs; bnT = NODE_RCHILD( pnodeOfbnode(bnT) )) { if (f) { if (!WalkAppendString(", ", 2)) { return FALSE; } } else { f = TRUE; } if (!WalkLChild(bnT)) { return FALSE; } } return WalkAppendString(")", 1); } /* WalkFunction() */ LOCAL bool_t NEAR FASTCALL WalkPlusMinus (bnode_t bn) { char * pch; switch( NODE_OP(pnodeOfbnode(bn)) ) { case OP_plus: pch = "+"; break; case OP_minus: pch = "-"; break; default: DASSERT(FALSE); return FALSE; } if (WalkLChild(bn) && WalkAppendString(pch, 1) && WalkRChild(bn)) { return TRUE; } return FALSE; } /* WalkPlusMinus() */ LOCAL bool_t NEAR FASTCALL WalkPMember (bnode_t bn) { DASSERT(FALSE); return TRUE; } LOCAL bool_t NEAR FASTCALL WalkPostIncDec (bnode_t bn) { char * pch; int cch = 2; switch( NODE_OP (pnodeOfbnode(bn)) ) { case OP_postinc: pch = "++"; break; case OP_postdec: pch = "--"; break; default: DASSERT(FALSE); return FALSE; } return WalkLChild(bn) && WalkAppendString(pch, cch); } /* WalkPostIncDec() */ LOCAL bool_t NEAR FASTCALL WalkPreIncDec (bnode_t bn) { char * pch; int cch = 2; switch( NODE_OP (pnodeOfbnode(bn)) ) { case OP_preinc: pch = "++"; break; case OP_predec: pch = "--"; break; default: DASSERT(FALSE); return FALSE; } return WalkAppendString(pch, cch) && WalkLChild(bn); } /* WalkPreIncDec() */ LOCAL bool_t NEAR FASTCALL WalkPointsTo (bnode_t bn) { return WalkLChild(bn) && WalkAppendString("->", 2) && WalkRChild(bn); } /* WalkPointsTo() */ LOCAL bool_t NEAR FASTCALL WalkRelat (bnode_t bn) { char * pch; int cch = 2; switch( NODE_OP (pnodeOfbnode(bn)) ) { case OP_lt: pch = "<"; cch = 1; break; case OP_lteq: pch = "<="; break; case OP_gt: pch = ">"; cch = 1; break; case OP_gteq: pch = ">="; break; case OP_eqeq: pch = "=="; break; case OP_bangeq: pch = "!="; break; default: DASSERT(FALSE); return FALSE; } return WalkLChild(bn) && WalkAppendString(pch, cch) && WalkRChild(bn); } /* WalkRelat() */ LOCAL bool_t NEAR FASTCALL WalkSegOp (bnode_t bn) { return WalkLChild(bn) && WalkAppendString(":", 1) && WalkRChild(bn); } LOCAL bool_t NEAR FASTCALL WalkSizeOf (bnode_t bn) { return WalkAppendString("sizeof(", 7) && WalkLChild(bn) && WalkAppendString(")", 1); } /* WalkSizeOf() */ LOCAL bool_t NEAR FASTCALL WalkSymbol (bnode_t bn) { peval_t pv = &pnodeOfbnode(bn)->v[0]; SYMPTR pSym; int len; EEHSTR hStr = 0; FORMATBUF fb; CV_typ_t rvtype; CV_typ_t mclass; CV_typ_t call; ushort cparam; CV_typ_t paramtype; HTYPE hType; plfEasy pType; char * pch; int cch; char * pch2; char * pch3; char ch; if (EVAL_HSYM(pv) == 0) { return WalkAppendString(pExStr + EVAL_ITOK(pv), EVAL_CBTOK(pv)); } switch((pSym = MHOmfLock( (HDEP)EVAL_HSYM (pv) ))->rectyp) { case S_BPREL16: len = ((BPRELPTR16) pSym)->name[0]; pch = &((BPRELPTR16) pSym)->name[1]; break; case S_BPREL32: len = ((BPRELPTR32) pSym)->name[0]; pch = &((BPRELPTR32) pSym)->name[1]; break; case S_LDATA16: case S_GDATA16: case S_PUB16: len = ((DATAPTR16) pSym)->name[0]; pch = &((DATAPTR16) pSym)->name[1]; break; case S_LDATA32: case S_GDATA32: case S_PUB32: len = ((DATAPTR32) pSym)->name[0]; pch = &((DATAPTR32) pSym)->name[1]; break; case S_REGISTER: len = ((REGPTR) pSym)->name[0]; pch = &((REGPTR) pSym)->name[1]; break; case S_REGREL16: len = ((REGREL16 *) pSym)->name[0]; pch = &((REGREL16 *) pSym)->name[1]; break; case S_REGREL32: len = ((LPREGREL32) pSym)->name[0]; pch = &((LPREGREL32) pSym)->name[1]; break; case S_LPROC16: case S_GPROC16: len = ((PROCPTR16) pSym)->name[0]; pch = &((PROCPTR16) pSym)->name[1]; break; case S_LPROC32: case S_GPROC32: len = ((PROCPTR32) pSym)->name[0]; pch = &((PROCPTR32) pSym)->name[1]; break; case S_LPROCMIPS: case S_GPROCMIPS: len = ((PROCPTRMIPS) pSym)->name[0]; pch = &((PROCPTRMIPS) pSym)->name[1]; break; case S_UDT: len = ((UDTSYM *) pSym)->name[0]; pch = &((UDTSYM *) pSym)->name[1]; break; default: DASSERT(FALSE); return FALSE; } if ((FPrototype) && (hType = THGetTypeFromIndex( EVAL_MOD(pv), EVAL_TYP(pv) )) != 0) { pType = (plfEasy) (&((TYPPTR)(MHOmfLock ((HDEP)hType)))->leaf); switch( pType->leaf ) { case LF_PROCEDURE: mclass = 0; rvtype = ((plfProc)pType)->rvtype; call = ((plfProc)pType)->calltype; cparam = ((plfProc)pType)->parmcount; paramtype = ((plfProc)pType)->arglist; MHOmfUnLock((HDEP)hType); pch2 = fb.Buf; pch3 = pch + len; ch = *pch3; *pch3 = 0; cch = sizeof(fb.Buf); FormatProc(pv, &pch2, &cch, &pch, rvtype, mclass, call, cparam, paramtype, 1, &fb.Hdr); len = pch2 - fb.Buf; pch = fb.Buf; *pch3 = ch; break; #if !defined (C_ONLY) case LF_MFUNCTION: rvtype = ((plfMFunc)pType)->rvtype; mclass = ((plfMFunc)pType)->classtype; call = ((plfMFunc)pType)->calltype; cparam = ((plfMFunc)pType)->parmcount; paramtype = ((plfMFunc)pType)->arglist; MHOmfUnLock ((HDEP)hType); pch3 = pch + len; ch = *pch3; *pch3 = 0; if (FInScope) { pch2 = strrchr(pch, ':'); if (pch2 == NULL) { pch2 = pch; } else { pch2++; } } else { pch2 = pch; } pch = fb.Buf; cch = sizeof(fb.Buf); FormatProc (pv, &pch, &cch, &pch2, rvtype, mclass, call, cparam, paramtype, 1, &fb.Hdr); len = pch - fb.Buf; pch = fb.Buf; *pch3 = ch; break; #endif default: MHOmfUnLock((HDEP)hType); } } return WalkAppendString(pch, len); } /* WalkSymbol() */ LOCAL bool_t NEAR FASTCALL WalkTypestr (bnode_t bn) { peval_t pv = &pnodeOfbnode(NODE_LCHILD(pnodeOfbnode(bn)))->v[0]; FORMATBUF fb; char * pch; unsigned int cch; pch = fb.Buf; cch = sizeof(fb.Buf); FormatType(pv, &pch, &cch, NULL, FPrototype, &fb.Hdr); return WalkAppendString(fb.Buf, pch-fb.Buf); } /* WalkTypestr() */ LOCAL bool_t NEAR FASTCALL WalkUnary (bnode_t bn) { char * pch; int cch = 1; switch( NODE_OP (pnodeOfbnode(bn)) ) { case OP_negate: pch = "-"; break; case OP_tilde: pch = "~"; break; case OP_uplus: pch = "+"; break; default: DASSERT(FALSE); return FALSE; } return WalkAppendString(pch, cch) && WalkLChild(bn); } /* WalkUnary() */ LOCAL bool_t NEAR FASTCALL WalkUScope (bnode_t bn) { bool_t fInScope = FInScope; bool_t fResult; FInScope = TRUE; fResult = WalkAppendString("::", 2) && WalkLChild(bn); FInScope = fInScope; return fResult; } /* WalkUScope() */