* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)tree.c 5.3 (Berkeley) %G%";
static char rcsid
[] = "$Header: tree.c,v 1.3 87/07/08 21:38:59 donn Exp $";
typedef struct Node
*Node
;
#define evalcmd(cmd) eval(cmd)
#define cmdlist_append(cmd, cl) list_append(list_item(cmd), nil, cl)
#define nextarg(type) ((type *) (ap += sizeof(type)))[-1]
public Node
build(op
, args
)
p
->value
.name
= nextarg(Name
);
p
->value
.sym
= nextarg(Symbol
);
p
->value
.lcon
= nextarg(long);
p
->value
.fcon
= nextarg(double);
p
->value
.scon
= nextarg(String
);
p
->value
.arg
[0] = nextarg(Node
);
(q
->value
.sym
->class == TYPE
or q
->value
.sym
->class == TAG
)
p
->value
.arg
[0] = nextarg(Node
);
if (q
->value
.arg
[1] != nil
) {
error("too many arguments to type rename");
p
->value
.arg
[0] = q
->value
.arg
[0];
p
->value
.arg
[1] = nextarg(Node
);
p
->value
.event
.cond
= nextarg(Node
);
p
->value
.event
.actions
= nextarg(Cmdlist
);
p
->value
.trace
.inst
= nextarg(Boolean
);
p
->value
.trace
.event
= nil
;
p
->value
.trace
.actions
= nextarg(Cmdlist
);
p
->value
.step
.source
= nextarg(Boolean
);
p
->value
.step
.skipcalls
= nextarg(Boolean
);
p
->value
.examine
.mode
= nextarg(String
);
p
->value
.examine
.beginaddr
= nextarg(Node
);
p
->value
.examine
.endaddr
= nextarg(Node
);
p
->value
.examine
.count
= nextarg(Integer
);
for (i
= 0; i
< nargs(op
); i
++) {
p
->value
.arg
[i
] = nextarg(Node
);
printf("built %s node 0x%x with arg[0] 0x%x arg[1] 0x%x\n",
opname(p
->op
), p
, p
->value
.arg
[0], p
->value
.arg
[1]);
* Strip away indirection from a node, thus returning a node for
* interpreting the expression as an lvalue.
} else if (exp
->op
== O_INDIR
) {
p
->nodetype
= exp
->nodetype
;
* Create a node for renaming a node to a pointer type.
public Node
renameptr (p
, t
)
t
->nodetype
= newSymbol(nil
, 0, PTR
, t
->nodetype
, nil
);
p
= build(O_TYPERENAME
, p
, t
);
* Return the tree for a unary ampersand operator.
r
->nodetype
= newSymbol(nil
, 0, PTR
, r
->nodetype
, nil
);
r
->nodetype
->language
= p
->nodetype
->language
;
if (isblock(p
->value
.sym
)) {
r
= build(O_LCON
, codeloc(p
->value
.sym
));
r
= build(O_LCON
, address(p
->value
.sym
, nil
));
fprintf(stderr
, "expected variable, found \"");
* Create a "concrete" version of a node.
* This is necessary when the type of the node contains
* an unresolved type reference.
return build(O_INDIR
, p
);
* Create a command list from a single command.
public Cmdlist
buildcmdlist(cmd
)
cmdlist_append(cmd
, cmdlist
);
if (cmd
->value
.step
.skipcalls
) {
if (not cmd
->value
.step
.source
) {
fprintf(f
, "%s", opinfo
[ord(cmd
->op
)].opstring
);
if (nargs(cmd
->op
) != 0) {
fprintf(f
, "%s", symname(cmd
->value
.sym
));
if (p
!= nil
and p
->op
!= O_QLINE
) {
fprintf(f
, "%s", cmd
->value
.scon
);
fprintf(f
, "%d", cmd
->value
.lcon
);
prtree(f
, cmd
->value
.event
.cond
);
foreach (Command
, c
, cmd
->value
.event
.actions
)
fprintf(f
, "%s }", opinfo
[ord(cmd
->op
)].opstring
);
prtree(f
, cmd
->value
.examine
.beginaddr
);
if (cmd
->value
.examine
.endaddr
!= nil
) {
prtree(f
, cmd
->value
.examine
.endaddr
);
if (cmd
->value
.examine
.count
> 1) {
fprintf(f
, "%d", cmd
->value
.examine
.count
);
fprintf("%s", cmd
->value
.examine
.mode
);
if (nargs(cmd
->op
) != 0) {
prtree(f
, cmd
->value
.arg
[i
]);
if (i
>= nargs(cmd
->op
)) break;
* Print out a trace/stop command name.
#define fprintI(f, b) { if (b) fprintf(f, "i"); }
private print_tracestop(f
, cmd
)
register Command c
, ifcmd
, stopcmd
;
ifcmd
= list_element(Command
, list_head(cmd
->value
.trace
.actions
));
stopcmd
= list_element(Command
, list_head(ifcmd
->value
.event
.actions
));
if (stopcmd
->op
== O_STOPX
) {
fprintI(f
, cmd
->value
.trace
.inst
);
prtree(f
, ifcmd
->value
.event
.cond
);
} else if (ifcmd
->op
== O_STOPIFCHANGED
) {
fprintI(f
, cmd
->value
.trace
.inst
);
prtree(f
, ifcmd
->value
.arg
[0]);
fprintf(f
, "%s ", cmd
->value
.trace
.inst
? "tracei" : "trace");
foreach (Command
, c
, cmd
->value
.trace
.actions
)
if (ord(op
) > ord(O_LASTOP
)) {
panic("bad op %d in prtree", p
->op
);
fprintf(f
, "%s", ident(p
->value
.name
));
printname(f
, p
->value
.sym
);
prtree(f
, p
->value
.arg
[0]);
prtree(f
, p
->value
.arg
[1]);
fprintf(f
, "%d", p
->value
.lcon
);
fprintf(f
, "'%c'", p
->value
.lcon
);
fprintf(f
, "%g", p
->value
.fcon
);
fprintf(f
, "\"%s\"", p
->value
.scon
);
prtree(f
, p
->value
.arg
[0]);
prtree(f
, p
->value
.arg
[1]);
prtree(f
, p
->value
.arg
[0]);
if (p
->value
.arg
[1] != nil
) {
prtree(f
, p
->value
.arg
[1]);
prtree(f
, p
->value
.arg
[0]);
prtree(f
, p
->value
.arg
[0]);
if (p
->value
.arg
[1]!= nil
) {
prtree(f
, p
->value
.arg
[1]);
prtree(f
, p
->value
.arg
[0]);
prtree(f
, p
->value
.arg
[0]);
fprintf(f
, ".%s", symname(p
->value
.arg
[1]->value
.sym
));
prtree(f
, p
->value
.arg
[1]);
prtree(f
, p
->value
.arg
[0]);
prtree(f
, p
->value
.arg
[0]);
fprintf(f
, "%s", opinfo
[ord(op
)].opstring
);
prtree(f
, p
->value
.arg
[1]);
fprintf(f
, "%s", opinfo
[ord(op
)].opstring
);
prtree(f
, p
->value
.arg
[0]);
if (opinfo
[ord(op
)].opstring
== nil
) {
fprintf(f
, "[op %d]", ord(op
));
fprintf(f
, "%s", opinfo
[ord(op
)].opstring
);
* Free storage associated with a tree.
dispose(p
->value
.arg
[0]->value
.scon
);
dispose(p
->value
.arg
[0]);
for (i
= 0; i
< nargs(p
->op
); i
++) {