Handle '#' properly (well, _more_ properly) in macro expansion.
[smatch.git] / symbol.c
blob19b394116f289a390e354b4997c70dbac62b918a
1 /*
2 * Symbol lookup and handling.
4 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
5 */
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include "lib.h"
12 #include "token.h"
13 #include "parse.h"
14 #include "symbol.h"
15 #include "scope.h"
17 struct symbol *lookup_symbol(struct ident *ident, enum namespace ns)
19 struct symbol *sym;
21 for (sym = ident->symbols; sym; sym = sym->next_id) {
22 if (sym->namespace == ns)
23 return sym;
25 return sym;
28 struct symbol *alloc_symbol(struct token *token, int type)
30 struct symbol *sym = __alloc_symbol(0);
31 sym->type = type;
32 sym->token = token;
33 return sym;
36 void bind_symbol(struct symbol *sym, struct ident *ident, enum namespace ns)
38 if (sym->id_list) {
39 warn(sym->token, "internal error: symbol type already bound");
40 return;
42 sym->namespace = ns;
43 sym->next_id = ident->symbols;
44 ident->symbols = sym;
45 sym->id_list = &ident->symbols;
46 bind_scope(sym);
49 struct symbol *create_symbol(int stream, const char *name, int type)
51 struct token *token = built_in_token(stream, name);
52 struct symbol *sym = alloc_symbol(token, type);
53 bind_symbol(sym, token->ident, NS_TYPEDEF);
54 return sym;
58 * Type and storage class keywords need to have the symbols
59 * created for them, so that the parser can have enough semantic
60 * information to do parsing.
62 * "double" == "long float", "long double" == "long long float"
64 struct sym_init {
65 const char *name;
66 struct symbol *base_type;
67 unsigned int modifiers;
68 } symbol_init_table[] = {
69 /* Storage class */
70 { "auto", NULL, MOD_AUTO },
71 { "register", NULL, MOD_REGISTER },
72 { "static", NULL, MOD_STATIC },
73 { "extern", NULL, MOD_EXTERN },
75 /* Type specifiers */
76 { "void", &void_type, 0 },
77 { "char", &int_type, MOD_CHAR },
78 { "short", &int_type, MOD_SHORT },
79 { "int", &int_type, 0 },
80 { "long", NULL, MOD_LONG },
81 { "float", &fp_type, 0 },
82 { "double", &fp_type, MOD_LONG },
83 { "signed", &int_type, MOD_SIGNED },
84 { "__signed", &int_type, MOD_SIGNED },
85 { "__signed__", &int_type, MOD_SIGNED },
86 { "unsigned", &int_type, MOD_UNSIGNED },
88 /* Type qualifiers */
89 { "const", NULL, MOD_CONST },
90 { "__const", NULL, MOD_CONST },
91 { "__const__", NULL, MOD_CONST },
92 { "volatile", NULL, MOD_VOLATILE },
94 /* Predeclared types */
95 { "__builtin_va_list", &int_type, 0 },
97 /* Typedef.. */
98 { "typedef", NULL, MOD_TYPEDEF },
100 /* Extended types */
101 { "typeof", NULL, MOD_TYPEOF },
102 { "__typeof", NULL, MOD_TYPEOF },
103 { "__typeof__", NULL, MOD_TYPEOF },
105 { "attribute", NULL, MOD_ATTRIBUTE },
106 { "__attribute", NULL, MOD_ATTRIBUTE },
107 { "__attribute__", NULL, MOD_ATTRIBUTE },
109 { "struct", NULL, MOD_STRUCTOF },
110 { "union", NULL, MOD_UNIONOF },
111 { "enum", NULL, MOD_ENUMOF },
113 /* Ignored for now.. */
114 { "inline", NULL, 0 },
115 { "__inline", NULL, 0 },
116 { "__inline__", NULL, 0 },
117 { "restrict", NULL, 0 },
118 { "__restrict", NULL, 0 },
120 { NULL, NULL, 0 }
123 struct symbol void_type,
124 int_type,
125 fp_type,
126 vector_type,
127 bad_type;
129 #define __IDENT(n,str) \
130 struct ident n ## _ident = { len: sizeof(str)-1, name: str }
131 #define IDENT(n) __IDENT(n, #n)
133 IDENT(struct); IDENT(union); IDENT(enum);
134 IDENT(sizeof);
135 IDENT(alignof); IDENT(__alignof); IDENT(__alignof__);
136 IDENT(if); IDENT(else); IDENT(return);
137 IDENT(switch); IDENT(case); IDENT(default);
138 IDENT(break); IDENT(continue);
139 IDENT(for); IDENT(while); IDENT(do); IDENT(goto);
141 IDENT(__asm__); IDENT(__asm); IDENT(asm);
142 IDENT(__volatile__); IDENT(__volatile); IDENT(volatile);
143 IDENT(__attribute__); IDENT(__attribute);
145 void init_symbols(void)
147 int stream = init_stream("builtin", -1);
148 struct sym_init *ptr;
150 hash_ident(&sizeof_ident);
151 hash_ident(&alignof_ident);
152 hash_ident(&__alignof_ident);
153 hash_ident(&__alignof___ident);
154 hash_ident(&if_ident);
155 hash_ident(&else_ident);
156 hash_ident(&return_ident);
157 hash_ident(&switch_ident);
158 hash_ident(&case_ident);
159 hash_ident(&default_ident);
160 hash_ident(&break_ident);
161 hash_ident(&continue_ident);
162 hash_ident(&for_ident);
163 hash_ident(&while_ident);
164 hash_ident(&do_ident);
165 hash_ident(&goto_ident);
166 hash_ident(&__attribute___ident);
167 hash_ident(&__attribute_ident);
168 hash_ident(&__asm___ident);
169 hash_ident(&__asm_ident);
170 hash_ident(&asm_ident);
171 hash_ident(&__volatile___ident);
172 hash_ident(&__volatile_ident);
173 hash_ident(&volatile_ident);
174 for (ptr = symbol_init_table; ptr->name; ptr++) {
175 struct symbol *sym;
176 sym = create_symbol(stream, ptr->name, SYM_TYPE);
177 sym->ctype.base_type = ptr->base_type;
178 sym->ctype.modifiers = ptr->modifiers;