home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)knowCT.c 1.6 3/13/89
- */
- #include "assert.h"
- #include "nodes.h"
- #include "map.h"
- #include "sequence.h"
- #include "trace.h"
- #include "semantics.h"
- #include "builtins.h"
- #include "primitives.h"
- #include "MyParser.h"
- #include "flags.h"
-
- extern NodePtr getCTInfo();
-
- Map nodeToStruct;
- extern Map manifestMap;
-
- /*
- * Handling of invoc nodes.
- * Stage 0: ignore them
- * Stage 1: only depend on CT of target
- * Stage 2: depend on CT of target and args, and propogate CT information
- * the args to results of the operation.
- */
-
- #define STAGE1
-
- static void CT_addDependent(parent, child)
- NodePtr parent, child;
- {
- NodePtr childStruct;
- NodePtr parentStruct;
- parentStruct = (NodePtr) Map_Lookup(nodeToStruct, (int)parent);
- if ((int)parentStruct == NIL) {
- parentStruct = Construct(P_KNOWCT, 3, NN, NN, NN);
- parentStruct->b.knowct.tag = parent->tag;
- parentStruct->b.knowct.definingThing = parent;
- Map_Insert(nodeToStruct, (int)parent, (int)parentStruct);
- }
- childStruct = (NodePtr) Map_Lookup(nodeToStruct, (int)child);
- if ((int)childStruct == NIL) {
- childStruct = Construct(P_KNOWCT, 3, NN, NN, NN);
- childStruct->b.knowct.tag = child->tag;
- childStruct->b.knowct.definingThing = child;
- Map_Insert(nodeToStruct, (int)child, (int)childStruct);
- }
- Sequence_Add(&parentStruct->b.knowct.dependsOn, childStruct);
- }
-
- extern void resolveGlobal();
-
- static void CT_TryToAddDependent(parent, child)
- NodePtr parent, child;
- {
- Symbol st;
- switch (parent->tag) {
- case P_SYMBOL:
- st = (Symbol) parent;
- if (st->isManifest) {
- CT_addDependent(parent, Construct(T_NONE, 0));
- return;
- }
- break;
- case P_INVOC:
- if (Map_Lookup(manifestMap, (int)parent) != NIL) {
- CT_addDependent(parent, Construct(T_NONE, 0));
- return;
- }
- default:
- break;
- }
- switch (child->tag) {
- case P_GLOBALREF:
- resolveGlobal(child, (ValuePtr)NULL);
- assert(child->b.globalref.value != NN);
- CT_addDependent(parent, child->b.globalref.value);
- break;
- case T_NONE:
- case P_INVOC:
- case P_VECTORLIT:
- case P_BOOLLIT:
- case P_CHARLIT:
- case P_INTLIT:
- case P_REALLIT:
- case P_STRINGLIT:
- case P_BUILTINLIT:
- case P_SELFLIT:
- case P_ATLIT:
- case P_OBLIT:
- case P_NTHRESULT:
- case P_EXP:
- case P_UNARYEXP:
- CT_addDependent(parent, child);
- break;
- case P_SYMREF:
- case P_SYMDEF:
- CT_addDependent(parent, (NodePtr) child->b.symref.symbol);
- break;
- case P_SYMBOL:
- CT_addDependent(parent, child);
- break;
- default:
- CT_addDependent(parent, Construct(T_NONE, 0));
- break;
- }
- }
-
- /*ARGSUSED*/
- static void addResultSymbols(p, ob)
- NodePtr p, ob;
- {
- #ifdef JUNKKKK
- NodePtr q, r;
- assert(p->tag == P_OPDEF);
- assert(ob->tag == P_OBLIT);
- q = p->b.opdef.sig->b.opsig.results;
- Sequence_For(r, q)
- assert(r->tag == P_PARAM);
- assert(r->b.param.sym->tag == P_SYMDEF);
- CT_TryToAddDependent(ob, (NodePtr)r->b.param.sym->b.symdef.symbol);
- Sequence_Next
- #endif
- }
-
- extern NodePtr findObjectOperation(), OTLookup();
-
- void buildKnowCTGraph(p)
- register NodePtr p;
- {
- register NodePtr q, right, left, nth;
-
- if ((int)p <= 0x200) return;
- switch (p->tag) {
- case P_ASSIGNSTAT:
- right = p->b.assignstat.right;
- left = p->b.assignstat.left;
- if (Sequence_Length(right) > 1) {
- /* is a multiple assignment */
- Sequence_For(q, left)
- assert(q->tag == P_SYMREF);
- CT_TryToAddDependent((NodePtr)q->b.symref.symbol,
- right->b.children[z__z]);
- Sequence_Next
- } else if (Sequence_Length(left) == 1) {
- q = left->b.children[0];
- assert(q->tag == P_SYMREF);
- CT_TryToAddDependent((NodePtr)q->b.symref.symbol, right->b.children[0]);
- } else {
- Sequence_For(q, left)
- assert(q->tag == P_SYMREF);
- nth = Construct(P_NTHRESULT, 0);
- nth->b.nthresult.whichResult = z__z;
- CT_TryToAddDependent(nth, right->b.children[0]);
- CT_TryToAddDependent((NodePtr)q->b.symref.symbol, nth);
- Sequence_Next
- }
- break;
- case P_INVOC:
- if ((q = (NodePtr)Map_Lookup(manifestMap, (int)p + 2)) != (NodePtr)NIL) {
- return;
- }
- #ifdef STAGE0
- /* do not do anything */
- #else
- #ifdef STAGE1
- CT_TryToAddDependent(p, p->b.invoc.target);
- if (p->b.invoc.target->tag == P_SYMREF &&
- p->b.invoc.target->b.symref.symbol->isManifest) {
- NodePtr ct, opdef, results;
- Symbol st;
- ct = p->b.invoc.target->b.symref.symbol->value.CTinfo;
- if (ct == NULL) {
- TRACE2(knowct, 9, "CT of manifest symbol (0x%08x %s) is null",
- p->b.invoc.target->b.symref.symbol,
- ST_SymbolName(p->b.invoc.target->b.symref.symbol));
- } else {
- TRACE1(knowct, 9, "CT of invoc target is manifest (0x%08x)", ct);
- opdef = findObjectOperation(ct, p->b.invoc.opname);
- assert(opdef != NULL);
- results = opdef->b.opdef.sig->b.opsig.results;
- if (Sequence_Length(results) == 1) {
- st = results->b.children[0]->b.param.sym->b.symdef.symbol;
- TRACE2(knowct, 9, "The result symbol is \"%s\"(0x%08x)",
- ST_SymbolName(st), st);
- TRACE0(knowct, 9, "Adding result symbol as dependent of invoc");
- CT_TryToAddDependent(p, (NodePtr)st);
- }
- }
- }
- #else
- #ifdef STAGE2
- Sequence_For(q, p->b.invoc.args)
- assert(q->tag == P_ARG);
- q = q->b.arg.exp;
- CT_TryToAddDependent(p, q);
- Sequence_Next
- #endif
- #endif
- #endif
- break;
- case P_CONSTDECL:
- if (p->b.constdecl.sym->b.symdef.symbol->isManifest) {
- CT_TryToAddDependent((NodePtr) p->b.constdecl.sym->b.symdef.symbol,
- p->b.constdecl.sym->b.symdef.symbol->value.value);
- break;
- }
- case P_VARDECL:
- if (p->b.constdecl.value != NN)
- CT_TryToAddDependent((NodePtr) p->b.constdecl.sym->b.symdef.symbol,
- p->b.constdecl.value);
- break;
- case P_PARAM:
- break;
- case P_UNARYEXP:
- break;
- case P_EXP:
- break;
- case P_ATLIT:
- case P_OBLIT:
- CT_TryToAddDependent((NodePtr)p->b.oblit.name->b.symdef.symbol, p);
- Sequence_For(q, p->b.oblit.setq)
- assert(q->b.setq.inner->tag == P_SYMDEF);
- CT_TryToAddDependent((NodePtr) q->b.setq.inner->b.symdef.symbol,
- (NodePtr) q->b.setq.outer);
- Sequence_Next
- if (p->tag == P_OBLIT) {
- Sequence_For(q, p->b.oblit.ops)
- addResultSymbols(q, p);
- Sequence_Next
- if (p->b.oblit.monitor != NN) {
- Sequence_For(q, p->b.oblit.monitor->b.monitor.ops)
- addResultSymbols(q, p);
- Sequence_Next
- }
- }
- break;
- case P_IMPORT:
- break;
- case P_EXPORT:
- break;
- case P_PRIMSTAT:
- if (Sequence_Length(p->b.primstat.vars) <= 0) break;
- if (p->b.primstat.number->tag == P_STRINGLIT) {
- CT_TryToAddDependent((NodePtr)p->b.primstat.vars->b.children[0]->b.symref.symbol,
- Construct(T_NONE, 0));
- } else {
- int pNum;
- PrimitiveDescPtr pdp;
- pNum = atoi(p->b.primstat.number->b.intlit.string);
- for (pdp = primitives; pdp->number != 0 && pdp->number != pNum; pdp++) ;
- assert(pdp->number != 0);
- assert(pdp->isFunction);
- if (pdp->atindex[0] == ANYINDEX) {
- CT_TryToAddDependent((NodePtr)p->b.primstat.vars->b.children[0]->b.symref.symbol,
- Construct(T_NONE, 0));
- } else {
- CT_TryToAddDependent((NodePtr)p->b.primstat.vars->b.children[0]->b.symref.symbol,
- refToBuiltin(B_INSTCT, (int)pdp->atindex[0]));
- }
- }
- break;
- default:
- break;
- }
- Sequence_For(q, p)
- if ((int)q > 0x200) buildKnowCTGraph(q);
- Sequence_Next
- }
-
- void initializeKnowCT()
- {
- nodeToStruct = Map_Create();
- }
-
- static char *thingName(t)
- NodePtr t;
- {
- static char buffer[128];
- if (t->b.knowct.tag == P_SYMBOL) sprintf(buffer, "Symbol %s (0x%08x)",
- ST_SymbolName((Symbol)(t->b.knowct.definingThing)), t->b.knowct.definingThing);
- else sprintf(buffer, "%s (0x%08x) on line %d", tagNames[(int)t->b.knowct.tag],
- t->b.knowct.definingThing, t->b.knowct.definingThing->lineNumber);
- return(buffer);
- }
-
- extern void findAll();
-
- void displayKnowCTGraph()
- {
- NodePtr thing, theStruct, q;
- IFTRACE(knowct, 5) {
- Map_For(nodeToStruct, thing, theStruct)
- printf("struct 0x%08x %s", theStruct, thingName(theStruct));
- if (theStruct->b.knowct.isDone) printf(" isDone");
- if (theStruct->b.knowct.isOK) printf(" isOK");
- printf(" depends on:\n");
- Sequence_For(q, theStruct->b.knowct.dependsOn)
- printf("\t\tstruct 0x%08x %s\n", q, thingName(q));
- Sequence_Next
- Map_Next
- }
- }
-
- Boolean isSameCT(a, b)
- NodePtr a, b;
- {
- if (a->tag == P_ATLIT) {
- assert(a->b.atlit.f.cannotBeConformedTo);
- a = OTLookup(a->b.atlit.codeOID);
- }
- if (b->tag == P_ATLIT) {
- assert(b->b.atlit.f.cannotBeConformedTo);
- b = OTLookup(b->b.atlit.codeOID);
- }
- a = GETVALUE(a);
- b = GETVALUE(b);
- assert(a->tag == P_OBLIT && b->tag == P_OBLIT);
- return(a->b.oblit.codeOID == b->b.oblit.codeOID);
- }
-
- void propagateCTInfo(p)
- NodePtr p;
- {
- NodePtr q, ct = NULL, oldCT, opdef, aSymbolStruct;
- register Symbol st;
- Boolean areAllSymbols = TRUE, foundFirstCT, foundDependent;
-
- if (p->tag == T_SEQUENCE) {
- TRACE0(knowct, 3, "Trying to progagate to a set");
- Sequence_For(q, p)
- assert(q->tag == P_KNOWCT);
- if (q->b.knowct.tag != P_SYMBOL) {
- if (areAllSymbols) TRACE0(knowct, 3, "The set contains non-symbols");
- TRACE1(knowct, 5, "%s", thingName(q));
- areAllSymbols = FALSE;
- }
- Sequence_Next
- if (areAllSymbols) {
- TRACE0(knowct, 3, "The set contains only symbols, so trying harder");
- foundFirstCT = FALSE;
- foundDependent = FALSE;
- Sequence_For(aSymbolStruct, p)
- TRACE2(knowct, 4, "Looking at pre-reqs of 0x%08x %s", aSymbolStruct,
- thingName(aSymbolStruct));
- Sequence_For(q, aSymbolStruct->b.knowct.dependsOn)
- TRACE2(knowct, 5, "Looking at 0x%08x %s", q, thingName(q));
- assert(q->tag == P_KNOWCT);
- if (! q->b.knowct.isDone) continue; /* it is in this set */
- foundDependent = TRUE;
- if (!q->b.knowct.isOK) {
- TRACE2(knowct, 5, "0x%08x %s not ok, give up", q, thingName(q));
- ct = NULL;
- break;
- }
- if (!foundFirstCT) {
- ct = q->b.knowct.answer;
- foundFirstCT = TRUE;
- } else {
- if (! isSameCT(ct, q->b.knowct.answer)) {
- TRACE4(knowct, 5, "CT of 0x%08x %s (0x%08x) != 0x%08x, give up", q,
- thingName(q), q->b.knowct.answer, ct);
- ct = NULL;
- break;
- }
- }
- Sequence_Next
- Sequence_Next
- if (! foundDependent) {
- TRACE1(knowct, 3, "Symbol %s has no dependents", thingName(p));
- ct = NULL;
- }
- }
- Sequence_For(aSymbolStruct, p)
- if (ct != NULL) {
- oldCT = ((Symbol)aSymbolStruct->b.knowct.definingThing)->value.CTinfo;
- if (oldCT != NN) assert(isSameCT(oldCT, ct));
- ((Symbol)aSymbolStruct->b.knowct.definingThing)->value.CTinfo = ct;
- }
- aSymbolStruct->b.knowct.isDone = TRUE;
- aSymbolStruct->b.knowct.isOK = (ct != NULL);
- aSymbolStruct->b.knowct.answer = ct;
- TRACE4(knowct, 1, "Finalizing 0x%08x %s: %s 0x%08x", aSymbolStruct,
- thingName(aSymbolStruct),
- aSymbolStruct->b.knowct.isOK ? "know CT" : "do not know CT",
- aSymbolStruct->b.knowct.answer);
- Sequence_Next
- return;
- }
- assert(p->tag == P_KNOWCT);
- TRACE2(knowct, 3, "Propagating 0x%08x %s", p, thingName(p));
- switch (p->b.knowct.tag) {
- case T_NONE:
- ct = NN;
- break;
- case P_INVOC:
- #ifdef STAGE0
- /* do nothing */
- ct = NULL;
- #else
- #ifdef STAGE1
- p->b.knowct.answer = (NodePtr) Map_Lookup(manifestMap,
- (int)p->b.knowct.definingThing + 1);
- if ((int)p->b.knowct.answer != NIL) {
- p->b.knowct.isDone = TRUE;
- p->b.knowct.isOK = TRUE;
- TRACE4(knowct, 1, "Finalizing (manifest) 0x%08x %s: %s 0x%08x", p, thingName(p),
- p->b.knowct.isOK ? "know CT" : "know CT",
- p->b.knowct.answer);
- return;
- }
- q = p->b.knowct.dependsOn->b.children[0];
- TRACE2(knowct, 4, "Looking at 0x%08x %s", q, thingName(q));
- assert(q->tag == P_KNOWCT);
- assert(q->b.knowct.isDone);
- ct = NULL;
- if (!q->b.knowct.isOK) {
- TRACE2(knowct, 5, "0x%08x %s not ok, give up", q, thingName(q));
- } else {
- ct = q->b.knowct.answer;
- TRACE3(knowct, 5, "0x%08x %s ok, ct = 0x%08x", q, thingName(q), ct);
- opdef = findObjectOperation(ct, p->b.knowct.definingThing->b.invoc.opname);
- assert(opdef != NULL);
- q = opdef->b.opdef.sig->b.opsig.results;
- if (Sequence_Length(q) == 1) {
- st = q->b.children[0]->b.param.sym->b.symdef.symbol;
- TRACE2(knowct, 5, "The result symbol is \"%s\"(0x%08x)",
- ST_SymbolName(st), st);
- ct = getCTInfo(st);
- } else {
- ct = NULL;
- }
- }
- #else
- #ifdef STAGE2
- Sequence_For(q, p->b.knowct.dependsOn)
- TRACE2(knowct, 4, "Looking at 0x%08x %s", q, thingName(q));
- assert(q->tag == P_KNOWCT);
- assert(q->b.knowct.isDone);
- if (!q->b.knowct.isOK) {
- TRACE2(knowct, 5, "0x%08x %s not ok, give up", q, thingName(q));
- ct = NULL;
- break;
- }
- Sequence_Next
- ct = NULL;
- #endif
- #endif
- #endif
- break;
- case P_NTHRESULT:
- #ifdef STAGE0
- /* do nothing */
- ct = NULL;
- #else
- #ifdef STAGE1
- assert(Sequence_Length(p->b.knowct.dependsOn) == 1);
- q = p->b.knowct.dependsOn->b.children[0];
- /* q now points to a P_INVOC struct */
- assert(q->b.knowct.tag == P_INVOC);
- assert(q->b.knowct.isDone);
- assert(Sequence_Length(q->b.knowct.dependsOn) == 1);
- q = p->b.knowct.dependsOn->b.children[0];
- /* q now points to a the struct for the target */
- TRACE2(knowct, 4, "Looking at 0x%08x %s", q, thingName(q));
- assert(q->tag == P_KNOWCT);
- assert(q->b.knowct.isDone);
- ct = NULL;
- if (!q->b.knowct.isOK) {
- TRACE2(knowct, 5, "0x%08x %s not ok, give up", q, thingName(q));
- } else {
- ct = q->b.knowct.answer;
- TRACE3(knowct, 5, "0x%08x %s ok, ct = 0x%08x", q, thingName(q), ct);
- opdef = findObjectOperation(ct, p->b.knowct.definingThing->b.invoc.opname);
- assert(opdef != NULL);
- q = opdef->b.opdef.sig->b.opsig.results;
- assert(Sequence_Length(q) > p->b.nthresult.whichResult);
- st = q->b.children[p->b.nthresult.whichResult]->b.param.sym->b.symdef.symbol;
- TRACE1(knowct, 5, "The result symbol is \"%s\"", ST_SymbolName(st));
- ct = getCTInfo(st);
- }
- #else
- #ifdef STAGE2
- Sequence_For(q, p->b.knowct.dependsOn)
- TRACE2(knowct, 4, "Looking at 0x%08x %s", q, thingName(q));
- assert(q->tag == P_KNOWCT);
- assert(q->b.knowct.isDone);
- if (!q->b.knowct.isOK) {
- TRACE2(knowct, 5, "0x%08x %s not ok, give up", q, thingName(q));
- ct = NULL;
- break;
- }
- Sequence_Next
- ct = NULL;
- #endif
- #endif
- #endif
- break;
- case P_EXP:
- switch (p->b.knowct.definingThing->b.exp.op) {
- case KAND:
- case KOR:
- case OIDENTITY:
- case ONOTIDENTITY:
- case OCONFORMSTO:
- ct = refToBuiltin(B_INSTCT, BOOLEANINDEX);
- break;
- default:
- assert(FALSE);
- break;
- }
- break;
- case P_UNARYEXP:
- switch (p->b.knowct.definingThing->b.unaryexp.op) {
- case KISFIXED:
- case KAWAITING:
- ct = refToBuiltin(B_INSTCT, BOOLEANINDEX);
- break;
- case KLOCATE:
- ct = refToBuiltin(B_INSTCT, NODEINDEX);
- break;
- default:
- assert(FALSE);
- break;
- }
- break;
- case P_VECTORLIT:
- ct = findInstCode(p->b.knowct.definingThing->b.vectorlit.vectorType);
- break;
- case P_BOOLLIT:
- ct = refToBuiltin(B_INSTCT, BOOLEANINDEX);
- break;
- case P_CHARLIT:
- ct = refToBuiltin(B_INSTCT, CHARACTERINDEX);
- break;
- case P_INTLIT:
- ct = refToBuiltin(B_INSTCT, INTEGERINDEX);
- break;
- case P_REALLIT:
- ct = refToBuiltin(B_INSTCT, REALINDEX);
- break;
- case P_STRINGLIT:
- ct = refToBuiltin(B_INSTCT, STRINGINDEX);
- break;
- case P_BUILTINLIT:
- ct = refToBuiltinFromToken(B_IT,
- p->b.knowct.definingThing->b.builtinlit.whichType);
- break;
- case P_SELFLIT:
- assert(FALSE);
- break;
- case P_ATLIT:
- ct = refToBuiltin(B_INSTCT, SIGNATUREINDEX);
- break;
- case P_OBLIT:
- ct = p->b.knowct.definingThing;
- break;
- case P_SYMBOL:
- st = (Symbol) p->b.knowct.definingThing;
- if (st->isManifest) {
- p->b.knowct.isDone = TRUE;
- p->b.knowct.isOK = TRUE;
- p->b.knowct.answer = st->value.CTinfo;
- TRACE4(knowct, 1, "Finalizing (manifest) 0x%08x %s: %s 0x%08x", p,
- thingName(p),
- p->b.knowct.isOK ? "know CT" : "know CT",
- p->b.knowct.answer);
- return;
- }
- foundFirstCT = FALSE;
- Sequence_For(q, p->b.knowct.dependsOn)
- TRACE2(knowct, 3, "Looking at 0x%08x %s", q, thingName(q));
- assert(q->tag == P_KNOWCT);
- assert(q->b.knowct.isDone);
- if (!q->b.knowct.isOK) {
- TRACE2(knowct, 5, "0x%08x %s not ok, give up", q, thingName(q));
- ct = NULL;
- break;
- }
- if (!foundFirstCT) {
- ct = q->b.knowct.answer;
- foundFirstCT = TRUE;
- } else {
- if (! isSameCT(ct, q->b.knowct.answer)) {
- TRACE4(knowct, 4, "CT of 0x%08x %s (0x%08x) != 0x%08x, give up", q,
- thingName(q), q->b.knowct.answer, ct);
- ct = NULL;
- break;
- }
- }
- Sequence_Next
- if (! foundFirstCT) {
- TRACE1(knowct, 3, "Symbol %s has no dependents", thingName(p));
- ct = NULL;
- }
- if (ct != NULL) {
- oldCT = ((Symbol)p->b.knowct.definingThing)->value.CTinfo;
- if (!bflag && oldCT != NN) assert(isSameCT(oldCT, ct));
- ((Symbol)p->b.knowct.definingThing)->value.CTinfo = ct;
- }
- break;
- default:
- break;
- }
- p->b.knowct.isDone = TRUE;
- p->b.knowct.isOK = (ct != NULL);
- p->b.knowct.answer = ct;
- TRACE4(knowct, 1, "Finalizing 0x%08x %s: %s 0x%08x", p, thingName(p),
- p->b.knowct.isOK ? "know CT" : "do not know CT",
- p->b.knowct.answer);
- }
-
- static int count = 0;
- static NodePtr SCstack = NULL;
- static NodePtr SCComponent = NULL;
-
- #define min(A, B) ((A) < (B) ? (A) : (B))
-
- void SearchC(v)
- register NodePtr v;
- {
- register NodePtr x, w;
- v->b.knowct.marked = TRUE;
- v->b.knowct.number = count++;
- v->b.knowct.lowLink = v->b.knowct.number;
- Sequence_Add(&SCstack, v);
- v->b.knowct.onStack = TRUE;
- Sequence_For(w, v->b.knowct.dependsOn)
- if (! w->b.knowct.marked) {
- SearchC(w);
- v->b.knowct.lowLink = min(v->b.knowct.lowLink, w->b.knowct.lowLink);
- } else {
- if (w->b.knowct.number < v->b.knowct.number && w->b.knowct.onStack) {
- v->b.knowct.lowLink = min(w->b.knowct.number, v->b.knowct.lowLink);
- }
- }
- Sequence_Next
- if (v->b.knowct.lowLink == v->b.knowct.number) {
- TRACE0(knowct, 1, "------");
- Sequence_ReverseFor(x, SCstack)
- SCstack->nChildren --;
- assert(x->b.knowct.onStack);
- x->b.knowct.onStack = FALSE;
- if (SCComponent == NULL && x == v) {
- /* this is the only element of the component */
- SCComponent = x;
- } else {
- Sequence_Add(&SCComponent, x);
- }
- TRACE2(knowct, 2, "struct 0x%08x %s", x, thingName(x));
- if (x == v) break;
- Sequence_Next
- propagateCTInfo(SCComponent);
- if (SCComponent->tag == T_SEQUENCE) {
- free((char *)SCComponent);
- }
- SCComponent = NULL;
- }
- }
-
- void FindAll()
- {
- NodePtr theThing, theStruct;
- Map_For(nodeToStruct, theThing, theStruct)
- if (! theStruct->b.knowct.marked) SearchC(theStruct);
- Map_Next
- }
-
- void doKnowCTs(p)
- NodePtr p;
- {
- buildKnowCTGraph(p);
- displayKnowCTGraph();
- FindAll();
- }
-