2 * Example trivial client program that uses the sparse library
3 * to tokenize, pre-process and parse a C file, and prints out
6 * Copyright (C) 2003 Transmeta Corp.
7 * 2003-2004 Linus Torvalds
9 * Licensed under the Open Software License version 1.1
24 #include "expression.h"
25 #include "linearize.h"
27 static int context_increase(struct basic_block
*bb
)
30 struct instruction
*insn
;
32 FOR_EACH_PTR(bb
->insns
, insn
) {
33 if (insn
->opcode
== OP_CONTEXT
)
34 sum
+= insn
->increment
;
35 } END_FOR_EACH_PTR(insn
);
39 static int imbalance(struct entrypoint
*ep
, struct basic_block
*bb
, int entry
, int exit
, const char *why
)
42 struct symbol
*sym
= ep
->name
;
43 warning(bb
->pos
, "context imbalance in '%s' - %s", show_ident(sym
->ident
), why
);
48 static int check_bb_context(struct entrypoint
*ep
, struct basic_block
*bb
, int entry
, int exit
);
50 static int check_children(struct entrypoint
*ep
, struct basic_block
*bb
, int entry
, int exit
)
52 struct instruction
*insn
;
53 struct basic_block
*child
;
55 insn
= last_instruction(bb
->insns
);
58 if (insn
->opcode
== OP_RET
)
59 return entry
!= exit
? imbalance(ep
, bb
, entry
, exit
, "wrong count at exit") : 0;
61 FOR_EACH_PTR(bb
->children
, child
) {
62 if (check_bb_context(ep
, child
, entry
, exit
))
64 } END_FOR_EACH_PTR(child
);
68 static int check_bb_context(struct entrypoint
*ep
, struct basic_block
*bb
, int entry
, int exit
)
72 if (bb
->context
== entry
)
75 /* Now that's not good.. */
77 return imbalance(ep
, bb
, entry
, bb
->context
, "different lock contexts for basic block");
80 entry
+= context_increase(bb
);
82 return imbalance(ep
, bb
, entry
, exit
, "unexpected unlock");
84 return check_children(ep
, bb
, entry
, exit
);
87 static void check_context(struct entrypoint
*ep
)
89 struct symbol
*sym
= ep
->name
;
91 if (verbose
&& ep
->entry
->bb
->needs
) {
93 FOR_EACH_PTR(ep
->entry
->bb
->needs
, pseudo
) {
94 if (pseudo
->type
!= PSEUDO_ARG
)
95 warning(sym
->pos
, "%s: possible uninitialized variable (%s)",
96 show_ident(sym
->ident
), show_pseudo(pseudo
));
97 } END_FOR_EACH_PTR(pseudo
);
100 check_bb_context(ep
, ep
->entry
->bb
, sym
->ctype
.in_context
, sym
->ctype
.out_context
);
103 static void check_symbols(struct symbol_list
*list
)
107 FOR_EACH_PTR(list
, sym
) {
108 struct entrypoint
*ep
;
111 ep
= linearize_symbol(sym
);
114 } END_FOR_EACH_PTR(sym
);
117 int main(int argc
, char **argv
)
119 // Expand, linearize and show it.
120 check_symbols(sparse(argc
, argv
));