Merge both node and array information at array degrade time.
[smatch.git] / obfuscate.c
blob7201fac3e843c3486b66cf495febf03934491428
1 /*
2 * Example trivial client program that uses the sparse library
3 * to tokenize, pre-process and parse a C file, and prints out
4 * the results.
6 * Copyright (C) 2003 Transmeta Corp, all rights reserved.
7 */
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <unistd.h>
14 #include <fcntl.h>
16 #include "lib.h"
17 #include "token.h"
18 #include "parse.h"
19 #include "symbol.h"
20 #include "expression.h"
22 static void emit_blob(struct symbol *sym)
24 int size = sym->bit_size;
25 int alignment = sym->ctype.alignment;
26 const char *name = show_ident(sym->ident);
28 if (size <= 0) {
29 warn(sym->pos, "emitting insized symbol");
30 size = 8;
32 if (size & 7)
33 warn(sym->pos, "emitting symbol of size %d bits\n", size);
34 size = (size+7) >> 3;
35 if (alignment < 1)
36 alignment = 1;
37 if (!(size & (alignment-1))) {
38 switch (alignment) {
39 case 1:
40 printf("unsigned char %s[%d];\n", name, size);
41 return;
42 case 2:
43 printf("unsigned short %s[%d];\n", name, (size+1) >> 1);
44 return;
45 case 4:
46 printf("unsigned int %s[%d];\n", name, (size+3) >> 2);
47 return;
50 printf("unsigned char %s[%d] __attribute__((aligned(%d)));\n",
51 name, size, alignment);
52 return;
55 static void emit_fn(struct symbol *sym)
57 const char *name = show_ident(sym->ident);
58 printf("%s();\n", name);
61 void emit_symbol(struct symbol *sym, void *_parent, int flags)
63 struct symbol *ctype;
65 evaluate_symbol(sym);
66 if (sym->type != SYM_NODE) {
67 warn(sym->pos, "I really want to emit nodes, not pure types!");
68 return;
71 ctype = sym->ctype.base_type;
72 if (!ctype)
73 return;
74 switch (ctype->type) {
75 case SYM_NODE:
76 case SYM_PTR:
77 case SYM_ARRAY:
78 case SYM_STRUCT:
79 case SYM_UNION:
80 case SYM_BASETYPE:
81 emit_blob(sym);
82 return;
83 case SYM_FN:
84 emit_fn(sym);
85 return;
86 default:
87 warn(sym->pos, "what kind of strange node do you want me to emit again?");
88 return;
92 int main(int argc, char **argv)
94 int fd;
95 char *filename = argv[1];
96 struct token *token;
97 struct symbol_list *list = NULL;
99 // Initialize symbol stream first, so that we can add defines etc
100 init_symbols();
102 fd = open(filename, O_RDONLY);
103 if (fd < 0)
104 die("No such file: %s", argv[1]);
106 // Tokenize the input stream
107 token = tokenize(filename, fd, NULL);
108 close(fd);
110 // Pre-process the stream
111 token = preprocess(token);
113 // Parse the resulting C code
114 translation_unit(token, &list);
116 // Do type evaluation and simplify
117 symbol_iterate(list, emit_symbol, NULL);
119 return 0;