11#include "lib.h"
2+ #include "lang.h"
23#include <stdio.h>
34#include <stdlib.h>
45#include <string.h>
56
7+ int log_level = 0 ;
8+
69unsigned int build_nat (char * c , int len ) {
710 int s = 0 , i = 0 ;
811 for (i = 0 ; i < len ; ++ i ) {
@@ -110,6 +113,28 @@ void SLL_hash_delete(struct SLL_hash_table* t, char* key) {
110113
111114struct SLL_hash_table * identifier_table ;
112115
116+
117+
118+ struct var_decl_expr * get_core_type (struct var_decl_expr * ptr ){
119+ while (ptr -> t != T_ORIG_TYPE ) {
120+ switch (ptr -> t ) {
121+ case T_PTR_TYPE :
122+ ptr = ptr -> d .PTR_TYPE .base ;
123+ break ;
124+ case T_ARRAY_TYPE :
125+ ptr = ptr -> d .ARRAY_TYPE .base ;
126+ break ;
127+ case T_FUNC_TYPE :
128+ ptr = ptr -> d .FUNC_TYPE .ret ;
129+ break ;
130+ case T_ORIG_TYPE :
131+ break ;
132+ }
133+ }
134+ return ptr ;
135+ }
136+
137+
113138struct IdentifierInfo * init_identifier_info () {
114139 struct IdentifierInfo * res =
115140 (struct IdentifierInfo * )malloc (sizeof (struct IdentifierInfo ));
@@ -151,9 +176,18 @@ char* identifier_type_str[6] = {
151176// use yylineno to record the line number of the first registration
152177extern int yylineno ;
153178
154- void register_identifier (char * name , enum IdentifierType type ) {
155- pdebug ("Line %d:\n" , yylineno );
156- pdebug ("Registering identifier %s as %s\n" , name , identifier_type_str [type ]);
179+ // lineno: use -1 to fallback to yylineno.
180+ void register_identifier_in_table (char * name , enum IdentifierType type , struct SLL_hash_table * table , int lineno , char * description ) {
181+ if (lineno == -1 ){
182+ lineno = yylineno ;
183+ }
184+ if (description == NULL ){
185+ // fallback to the default description
186+ description = identifier_type_str [type ];
187+ }
188+
189+ pdebug ("Line %d:\n" , lineno );
190+ pdebug ("Registering identifier %s as %s\n" , name , description );
157191
158192 if (name == NULL ){
159193 pdebug ("Identifier name is NULL (Anonymous), skip registering\n" );
@@ -162,11 +196,11 @@ void register_identifier(char* name, enum IdentifierType type) {
162196
163197 struct IdentifierInfo * info = NULL ;
164198
165- info = (struct IdentifierInfo * )SLL_hash_get (identifier_table , name );
199+ info = (struct IdentifierInfo * )SLL_hash_get (table , name );
166200 if ((long long )info == NONE ) {
167201 pdebug ("Identifier %s is not in the hashtable\n" , name );
168202 info = init_identifier_info ();
169- SLL_hash_set (identifier_table , name , (long long )info );
203+ SLL_hash_set (table , name , (long long )info );
170204 }
171205 else {
172206 pdebug ("Identifier %s is in the hashtable\n" , name );
@@ -182,18 +216,22 @@ void register_identifier(char* name, enum IdentifierType type) {
182216 }
183217 if (info -> flags & (1 << i )) {
184218 // identifier is already registered as a conflicting type.
185- printf ("Warning: (Line %d) Identifier %s is already registered as %s at line %d\n" , yylineno , name , identifier_type_str [ i ] , info -> lineno [i ]);
219+ printf ("Warning: (Line %d) Identifier %s is already registered as %s at line %d\n" , lineno , name , description , info -> lineno [i ]);
186220 conflict = 1 ;
187221 }
188222 }
189223
190224 if (!conflict ) {
191225 pdebug ("No conflict. Now register %s as %s\n" , name , identifier_type_str [type ]);
192226 info -> flags |= (1 << type );
193- info -> lineno [type ] = yylineno ; // the line number of the first registration
227+ info -> lineno [type ] = lineno ; // the line number of the first registration
194228 }
195229}
196230
231+ void register_identifier (char * name , enum IdentifierType type ) {
232+ register_identifier_in_table (name , type , identifier_table , -1 , NULL );
233+ }
234+
197235void register_identifier_variable (char * name ) {
198236 register_identifier (name , IDENT_TYPE_VARIABLE );
199237}
@@ -218,10 +256,10 @@ void register_identifier_typedef(char* name) {
218256 register_identifier (name , IDENT_TYPE_TYPEDEF );
219257}
220258
221- void check_identifier (char * name , enum IdentifierType using_type ){
259+ void check_identifier_in_table (char * name , enum IdentifierType using_type , struct SLL_hash_table * table ){
222260 pdebug ("Line %d:\n" , yylineno );
223261 struct IdentifierInfo * info = NULL ;
224- info = (struct IdentifierInfo * )SLL_hash_get (identifier_table , name );
262+ info = (struct IdentifierInfo * )SLL_hash_get (table , name );
225263 if ((long long )info == NONE ) {
226264 printf ("Warning: (Line %d) Identifier %s has never been registered\n" , yylineno , name );
227265 return ;
@@ -241,6 +279,10 @@ void check_identifier(char *name, enum IdentifierType using_type){
241279 }
242280}
243281
282+ void check_identifier (char * name , enum IdentifierType using_type ){
283+ check_identifier_in_table (name , using_type , identifier_table );
284+ }
285+
244286void check_identifier_enum (char * name ){
245287 check_identifier (name , IDENT_TYPE_ENUM );
246288}
@@ -257,3 +299,20 @@ void check_identifier_typedef(char *name){
257299 check_identifier (name , IDENT_TYPE_TYPEDEF );
258300}
259301
302+ void check_field_list (struct type_list * field_list ){
303+ // build a new hash table for the field list
304+ struct SLL_hash_table * field_table = init_SLL_hash ();
305+ while (field_list != NULL ){
306+ struct left_type * t = field_list -> t ;
307+ struct var_decl_expr * e = field_list -> e ;
308+ struct var_decl_expr * core_type = get_core_type (e );
309+ register_identifier_in_table (
310+ core_type -> d .ORIG_TYPE .name ,
311+ IDENT_TYPE_VARIABLE ,
312+ field_table ,
313+ core_type -> d .ORIG_TYPE .lineno ,
314+ "field variable"
315+ );
316+ field_list = field_list -> next ;
317+ }
318+ }
0 commit comments