-
Notifications
You must be signed in to change notification settings - Fork 15
/
declaration.c
114 lines (97 loc) · 2.53 KB
/
declaration.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* Declaration handling. All cases are actually the same, including
* typedef (hence the weird typedef syntax)
*/
#include "compiler.h"
unsigned one_typedef(unsigned type, unsigned name)
{
if (name == 0) {
error("invalid typedef");
junk();
return 0;
}
update_symbol_by_name(name, S_TYPEDEF, type);
return 1;
}
void dotypedef(void)
{
unsigned type = get_type();
unsigned name;
if (type == UNKNOWN)
type = CINT;
// while (is_modifier() || is_type_word() || token >= T_SYMBOL || token == T_STAR) {
while (token != T_SEMICOLON) {
unsigned utype = type_name_parse(S_NONE, type, &name);
if (one_typedef(utype, name) == 0)
return;
if (!match(T_COMMA))
break;
}
need_semicolon();
}
unsigned one_declaration(register unsigned s, unsigned type, unsigned name, unsigned defstorage)
{
register struct symbol *sym;
unsigned offset;
/* It's quite valid C to just write "int;" but usually dumb except
that it's used for struct and union */
if (name == 0) {
if (!IS_STRUCT(type))
warning("useless declaration");
return 1;
}
if ((s == S_AUTO || s == S_REGISTER) && defstorage == S_EXTDEF)
error("no automatic globals");
if (IS_FUNCTION(type) && !PTR(type)) {
if (s == S_EXTDEF || s == S_AUTO)
s = S_EXTERN;
}
if (s == S_REGISTER) {
offset = target_register(type, S_AUTO);
if (offset == 0)
s = S_AUTO;
}
/* Do we already have this symbol */
sym = update_symbol_by_name(name, s, type);
if (funcbody)
return 0;
if (s == S_REGISTER)
sym->data.offset = offset;
if (s == S_AUTO)
sym->data.offset = assign_storage(type, S_AUTO);
if (s == S_LSTATIC)
sym->data.offset = ++label_tag;;
if (s != S_EXTERN && (PTR(type) || !IS_FUNCTION(type)) && match(T_EQ)) {
unsigned label = sym->name;
if (s == S_LSTATIC)
label = sym->data.offset;
if (sym->infonext & INITIALIZED)
error("duplicate initializer");
sym->infonext |= INITIALIZED;
if (s >= S_LSTATIC)
header(H_DATA, label, target_alignof(type, s));
initializers(sym, type, s);
if (s >= S_LSTATIC)
footer(H_DATA, label, 0);
}
return 1;
}
void declaration(unsigned defstorage)
{
register unsigned s = get_storage(defstorage);
unsigned name;
register unsigned utype;
unsigned type;
type = get_type();
if (type == UNKNOWN)
type = CINT;
// while (is_modifier() || is_type_word() || token >= T_SYMBOL || token == T_STAR) {
while (token != T_SEMICOLON) {
utype = type_name_parse(s, type, &name);
if (one_declaration(s, utype, name, defstorage) == 0)
return;
if (!match(T_COMMA))
break;
}
need_semicolon();
}