CUBRID Engine  latest
esql_symbol_table.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * esql_symbol_table.c - Symbol table manager for C compiler front-end.
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <assert.h>
28 #include <stdlib.h>
29 
30 #include "esql_grammar.h"
31 #include "misc_string.h"
32 #include "esql_misc.h"
33 #include "memory_alloc.h"
34 
35 #define LCHUNK 10
36 
37 typedef struct linkchunk
38 {
39  struct linkchunk *next;
41 } LINKCHUNK;
42 
44 {
48 };
49 
52 
53 static SYMBOL *symbol_free_list; /* Free list of recycled symbols. */
54 static LINK *link_free_list; /* Free list of recycled links. */
55 static STRUCTDEF *struct_free_list; /* Free list of recycled structdefs. */
56 
57 static const unsigned int SYMTAB_SIZE = 511;
59 
60 /* 0 if syms should be deallocated via es_ht_free_symbol() instead. */
61 static int syms_to_free_lists = 1;
62 
63 static int syms_allocated = 0; /* Counters for statistics. */
64 static int syms_deallocated = 0;
65 static int sdefs_allocated = 0;
66 static int sdefs_deallocated = 0;
67 static int links_allocated = 0;
68 static int links_deallocated = 0;
69 
70 static void es_print_symbol (SYMBOL * sym, FILE * fp);
71 static void es_print_struct (STRUCTDEF * sdef, FILE * fp);
72 
73 /*
74  * pp_new_symtab() - Returns a new, initialized SYMTAB structure.
75  * return : a new, initialized SYMTAB structure.
76  */
77 SYMTAB *
79 {
81 }
82 
83 /*
84  * pp_free_symtab() - Free a symbol table and all of the symbols in it.
85  * return : void
86  * symtab(in) : A pointer to the symbol table to be deallocated
87  * free_fn(in) :
88  */
89 void
90 pp_free_symtab (SYMTAB * symtab, HT_FREE_FN free_fn)
91 {
92  if (symtab)
93  {
94  symtab->free_table (symtab, free_fn);
95  }
96 }
97 
98 /*
99  * pp_new_symbol() - Allocate and initialize a new symbol.
100  * return : new allocated symbol
101  * name(in): character string for the new symbol
102  * scope(in): nesting level of this symbol
103  */
104 SYMBOL *
105 pp_new_symbol (const char *name, int scope)
106 {
107  SYMBOL *sym;
108 
109  if (symbol_free_list == NULL)
110  {
111  sym = (SYMBOL *) es_ht_alloc_new_symbol (sizeof (SYMBOL));
112  }
113  else
114  {
115  sym = symbol_free_list;
116  symbol_free_list = symbol_free_list->next;
117  }
118 
119  ++syms_allocated;
120 
121  sym->name = name ? ((unsigned char *) strdup (name)) : NULL;
122  sym->level = scope;
123  sym->type = NULL;
124  sym->etype = NULL;
125  sym->next = NULL;
126 
127  return sym;
128 }
129 
130 /*
131  * pp_discard_symbol() - Discard a single symbol structure and any attacked
132  * links and args.
133  * return : void
134  * sym(in): the symbol to be discarded
135  *
136  * note : the args field is recycled for initializers.
137  */
138 void
140 {
141 
142  if (sym)
143  {
144  if (sym->args)
145  {
146  pp_discard_symbol (sym->args);
147  }
149 
150  if (sym->name)
151  {
152  free_and_init (sym->name);
153  }
154 
155  if (sym->type)
156  {
157  if (IS_FUNCT (sym->type))
158  {
160  }
162  }
163 
164  if (syms_to_free_lists)
165  {
166  sym->next = symbol_free_list;
167  symbol_free_list = sym;
168  }
169  else
170  {
171  es_ht_free_symbol (sym);
172  }
173  }
174 
175 }
176 
177 /*
178  * pp_discard_symbol_chain() - Discard an entire cross-linked chain of symbols.
179  * return : void
180  * sym(in): the head of a chain of symbols to discarded
181  */
182 void
184 {
185  SYMBOL *p = sym;
186 
187  while (sym)
188  {
189  p = sym->next;
190  pp_discard_symbol (sym);
191  sym = p;
192  }
193 }
194 
195 /*
196  * pp_new_link() - Return a new link. It is initialized to zeros.
197  * return : LINK *
198  */
199 LINK *
201 {
202  LINK *p;
203  int i;
204 
205  if (link_free_list == NULL)
206  {
207  LINKCHUNK *new_chunk = (LINKCHUNK *) malloc (sizeof (LINKCHUNK));
208  if (new_chunk == NULL)
209  {
211  exit (1);
212  return NULL;
213  }
214 
215  new_chunk->next = link_chunks;
216  link_chunks = new_chunk;
217  link_free_list = new_chunk->link;
218 
219  /* This loop executes LCHUNK-1 times. the last (LCHUNK-th) link is taken care of after the loop. */
220  for (p = link_free_list, i = LCHUNK; --i > 0; ++p)
221  {
222  p->next = p + 1;
223  }
224 
225  p->next = NULL;
226  }
227 
228  p = link_free_list;
229  link_free_list = link_free_list->next;
230 
231  ++links_allocated;
232 
233  memset ((char *) p, 0, sizeof (LINK));
234  p->decl.s.is_long = 0;
235  p->decl.s.is_short = 0;
236  p->next = NULL;
237 
238  return p;
239 }
240 
241 /*
242  * pp_discard_link_chain() - Discard all links in the chain.
243  * Nothing is removed from the structure table, however.
244  * return : void
245  * p(in): The head of a chain of links to be discarded.
246  */
247 void
249 {
250  LINK *next;
251 
252  while (p)
253  {
254  next = p->next;
255  pp_discard_link (p);
256  p = next;
257  }
258 }
259 
260 /*
261  * pp_discard_link() - Discard a single link.
262  * return : void
263  * p(in): the link to be discarded
264  */
265 void
267 {
268  if (IS_FUNCT (p))
269  {
271  }
272 
273  if (IS_ARRAY (p) && p->decl.d.num_ele)
274  {
276  }
277 
279 
280  p->next = link_free_list;
281  link_free_list = p;
282 }
283 
284 /*
285  * pp_new_structdef() - Allocate a new structdef.
286  * return : STRUCTDEF *
287  * tag(in): the tagname for the struct
288  */
289 STRUCTDEF *
290 pp_new_structdef (const char *tag)
291 {
292  /*
293  * Structs, even "anonymous" ones, must always have tag names for the
294  * benefit of the symbol table manager, so if none was supplied at
295  * creation time we must manufacture one ourselves. These variables
296  * are used in the manufacture of those names.
297  */
298  static int anon_tag = 0;
299  char buf[20];
300 
301  STRUCTDEF *sdef;
302 
303  if (struct_free_list == NULL)
304  {
305  sdef = (STRUCTDEF *) es_ht_alloc_new_symbol (sizeof (STRUCTDEF));
306  }
307  else
308  {
309  sdef = struct_free_list;
310  struct_free_list = struct_free_list->next;
311  }
312 
313  ++sdefs_allocated;
314 
315  if (tag == NULL)
316  {
317  sprintf (buf, "$%d", anon_tag);
318  anon_tag++;
319  tag = buf;
320  }
321 
322  sdef->tag = (unsigned char *) strdup (tag);
323  sdef->type_string = (unsigned char *) "struct";
324  sdef->type = 1; /* struct */
325  sdef->fields = NULL;
326  sdef->next = NULL;
327  sdef->by_name = 0;
328 
329  return sdef;
330 }
331 
332 /*
333  * pp_discard_structdef() - Discard a structdef and any attached fields,
334  * but don't discard any linked structure definitions.
335  * return : void
336  * sdef(in): the structdef to be discarded
337  */
338 void
340 {
341  if (sdef)
342  {
344 
345  if (sdef->tag)
346  {
347  free_and_init (sdef->tag);
348  }
350 
351  if (syms_to_free_lists)
352  {
353  sdef->next = struct_free_list;
354  struct_free_list = sdef;
355  }
356  else
357  {
358  es_ht_free_symbol ((void *) sdef);
359  }
360  }
361 }
362 
363 /*
364  * pp_discard_structdef_chain() -
365  * return : void
366  * sdef_chain(in): A chain of structdefs to be discarded.
367  */
368 void
370 {
371  STRUCTDEF *sdef, *next = NULL;
372 
373  for (sdef = sdef_chain; sdef; sdef = next)
374  {
375  next = sdef->next;
376  pp_discard_structdef (sdef);
377  }
378 }
379 
380 /*
381  * pp_new_pseudo_def() - Allocate a new structdef that describes
382  * the declaration
383  * struct {
384  * long length;
385  * char array[n];
386  * };
387  * This is used during the conversion of 'varchar' declarations into
388  * anonymous structs.
389  *
390  * returns/side-effects: STRUCTDEF *
391  * type(in): the type of the pseudo def (bit, varbit, varchar)
392  * subscript(in) : an expression for the array bound of the pseudo def
393  */
394 STRUCTDEF *
395 pp_new_pseudo_def (SPECIFIER_NOUN type, const char *subscript)
396 {
397  STRUCTDEF *sdef;
398  SYMBOL *length_field, *array_field, *db_int32;
399 
401 
404  pp_add_type_noun (CHAR_);
405  pp_add_declarator (array_field, D_ARRAY);
406  if (type == N_VARCHAR)
407  {
408  array_field->etype->decl.d.num_ele = pp_strdup (subscript);
409  }
410  else
411  {
412  varstring new_subscript;
413  vs_new (&new_subscript);
414  vs_sprintf (&new_subscript, "((%s)+7)/8", subscript);
415  array_field->etype->decl.d.num_ele = pp_strdup (vs_str (&new_subscript));
416  vs_free (&new_subscript);
417  }
418  pp_add_spec_to_decl (pp_current_type_spec (), array_field);
420 
422  db_int32 = pp_findsym (pp_Symbol_table, (unsigned char *) "int");
424  pp_add_typedefed_spec (db_int32->type);
425  pp_add_spec_to_decl (pp_current_type_spec (), length_field);
426  /*
427  * Don't use pp_discard_link(pp_current_spec()) here, since it came
428  * from a typedef.
429  */
430 
432 
433  length_field->next = array_field;
434 
435  sdef = pp_new_structdef (NULL);
436  sdef->fields = length_field;
437  pp_Struct_table->add_symbol (pp_Struct_table, sdef);
438 
439  return sdef;
440 }
441 
442 /*
443  * pp_add_declarator() - Add a declarator link to the end of a chain, the head
444  * of which is pointed to by sym->type and the tail of which is pointed to
445  * by sym->etype. *head must be NULL when the chain is empty. Both
446  * pointers are modified as necessary.
447  * return : void
448  * sym(in) : the symbol whose type description is to be modified
449  * type(in) : the new type to be added to the declarator chain
450  */
451 void
452 pp_add_declarator (SYMBOL * sym, int type)
453 {
454  LINK *link;
455 
456  if (type == D_FUNCTION && sym->etype && IS_ARRAY (sym->etype))
457  {
460  }
461 
462  link = pp_new_link ();
463  if (link == NULL)
464  {
465  return;
466  }
467 
468  link->decl.d.dcl_type = (DCL_TYPE) type;
469 
470  if (sym->type == NULL)
471  {
472  sym->type = sym->etype = link;
473  }
474  else if (sym->etype != NULL)
475  {
476  sym->etype->next = link;
477  sym->etype = link;
478  }
479 
480  if (type == D_FUNCTION && sym->etype != NULL)
481  {
482  sym->args = NULL;
483  sym->etype->decl.d.args = NULL;
484  }
485 }
486 
487 /*
488  * pp_clone_symbol() -
489  * return:
490  * sym(in) :
491  */
492 SYMBOL *
494 {
495  SYMBOL *newsym;
496 
497  newsym = pp_new_symbol ((char *) sym->name, sym->level);
498  if (newsym == NULL)
499  {
500  return NULL;
501  }
502 
503  newsym->type = pp_clone_type (sym->type, &newsym->etype);
504  newsym->next = NULL;
505 
506  return newsym;
507 }
508 
509 /*
510  * pp_clone_type() - Manufacture a clone of the type chain in the input symbol.
511  * The tdef bit in the copy is always cleared.
512  * return : A pointer to the cloned chain, NULL if there were no declarators
513  * to clone.
514  * tchain(in): the type chain to duplicate
515  * endp(in): pointer to the last node in the cloned chain
516  */
517 LINK *
518 pp_clone_type (LINK * tchain, LINK ** endp)
519 {
520  LINK *last = nullptr, *head = nullptr;
521 
522  for (; tchain; tchain = tchain->next)
523  {
524  if (head == nullptr && last == nullptr) /* 1st node in the chain */
525  {
526  head = last = pp_new_link ();
527  }
528  else /* Subsequent node */
529  {
530  last->next = pp_new_link ();
531  if (last->next == NULL)
532  {
533  return NULL;
534  }
535  last = last->next;
536  }
537 
538  memcpy ((char *) last, (char *) tchain, sizeof (*last));
539  if (IS_ARRAY (tchain) && tchain->decl.d.num_ele)
540  {
541  last->decl.d.num_ele = pp_strdup (tchain->decl.d.num_ele);
542  }
543  last->next = NULL;
544  last->tdef = NULL;
545 
546  if (IS_FUNCT (last))
547  {
548  SYMBOL *sym, **lastsym;
549  lastsym = &last->decl.d.args;
550  sym = last->decl.d.args;
551  while (sym)
552  {
553  *lastsym = pp_clone_symbol (sym);
554  lastsym = &(*lastsym)->next;
555  sym = sym->next;
556  }
557  }
558  }
559 
560  *endp = last;
561 
562  return head;
563 }
564 
565 /*
566  * pp_the_same_type() - Return 1 if the types match, 0 if they don't.
567  * Ignore the storage class. If 'relax' is true and the array declarator
568  * is the first link in the chain, then a pointer is considered equivalent
569  * to an array.
570  * return : 1 if the types match, 0 if they don't.
571  * p1(in): a type chain
572  * p2(in): another type chain
573  * relax(in): true iff arrays should be considered equivalent to pointers
574  */
575 int
576 pp_the_same_type (LINK * p1, LINK * p2, int relax)
577 {
578  if (relax && IS_PTR_TYPE (p1) && IS_PTR_TYPE (p2))
579  {
580  p1 = p1->next;
581  p2 = p2->next;
582  }
583 
584  for (; p1 && p2; p1 = p1->next, p2 = p2->next)
585  {
586  if (p1->class_ != p2->class_)
587  {
588  return 0;
589  }
590 
591  if (p1->class_ == DECLARATOR)
592  {
593  if (p1->decl.d.dcl_type != p2->decl.d.dcl_type)
594  {
595  return 0;
596  }
597  }
598  else
599  {
600  if ((p1->decl.s.noun == p2->decl.s.noun) && (p1->decl.s.is_long == p2->decl.s.is_long)
601  && (p1->decl.s.is_short == p2->decl.s.is_short) && (p1->decl.s.is_unsigned == p2->decl.s.is_unsigned))
602  {
603  return (p1->decl.s.noun == N_STRUCTURE) ? p1->decl.s.val.v_struct == p2->decl.s.val.v_struct : 1;
604  }
605  return 0;
606  }
607  }
608 
610  return 0;
611 }
612 
613 /*
614  * pp_attr_str() - Return a string representing the interesting attributes
615  * in a specifier other than the noun and storage class.
616  * return : char *
617  * spec(in): a type link
618  */
619 char *
621 {
622  static char str[32];
623 
624  assert (IS_SPECIFIER (type));
625 
626  str[0] = '\0';
627 
628  switch (type->decl.s.noun)
629  {
630  case N_CHR:
631  if (type->decl.s.is_unsigned)
632  {
633  strcpy (str, "unsigned ");
634  }
635  break;
636 
637  case N_INT:
638  if (type->decl.s.is_unsigned)
639  {
640  strcpy (str, "unsigned ");
641  }
642 
643  strcat (str, type->decl.s.is_long ? "long " : type->decl.s.is_short ? "short " : "int ");
644  break;
645 
646  case N_FLOAT:
647  if (type->decl.s.is_long)
648  {
649  strcpy (str, "long ");
650  }
651  break;
652 
653  default:
654  break;
655  }
656 
657  return str;
658 }
659 
660 /*
661  * pp_type_str() - Return a string representing the type represented by
662  * the link chain.
663  * return : char *
664  * link(in): a type chain
665  */
666 const char *
668 {
669  static char target[80];
670  static char buf[256];
671 
672  target[0] = '\0';
673  buf[0] = '\0';
674 
675  if (link == NULL)
676  {
677  return "(NULL)";
678  }
679 
680  if (link->tdef)
681  {
682  strcpy (target, "tdef ");
683  }
684 
685  for (; link; link = link->next)
686  {
687  if (IS_DECLARATOR (link))
688  {
689  switch (link->decl.d.dcl_type)
690  {
691  case D_ARRAY:
692  strncpy (buf, "array of ", sizeof (buf));
693  break;
694  case D_POINTER:
695  strncpy (buf, "ptr to ", sizeof (buf));
696  break;
697  case D_FUNCTION:
698  strncpy (buf, "function returning ", sizeof (buf));
699  break;
700  default:
701  strncpy (buf, "BAD DECL", sizeof (buf));
702  break;
703  }
704  }
705  else
706  {
707  /* it's a specifier */
708  const char *noun_str;
709 
710  strncpy_bufsize (buf, pp_attr_str (link));
711 
712  switch (link->decl.s.noun)
713  {
714  case N_VOID:
715  noun_str = "void";
716  break;
717  case N_CHR:
718  noun_str = "char";
719  break;
720  case N_INT:
721  noun_str = "int";
722  break;
723  case N_FLOAT:
724  noun_str = "float";
725  break;
726  case N_LABEL:
727  noun_str = "label";
728  break;
729  case N_STRUCTURE:
730  noun_str = (const char *) link->decl.s.val.v_struct->type_string;
731  break;
732  case N_VARCHAR:
733  noun_str = "varchar";
734  break;
735  case N_BIT:
736  noun_str = "bit";
737  break;
738  case N_VARBIT:
739  noun_str = "bit varying";
740  break;
741  default:
742  noun_str = "BAD NOUN";
743  break;
744  }
745  strncat (buf, noun_str, sizeof (buf) - strnlen (buf, sizeof (buf)));
746 
747  if (link->decl.s.noun == N_STRUCTURE)
748  {
749  strncat (target, buf, sizeof (target) - strnlen (target, sizeof (target)));
750  snprintf (buf, sizeof (buf), " %s",
751  (link->decl.s.val.v_struct->tag ? link->decl.s.val.v_struct->
752  tag : ((unsigned char *) "untagged")));
753  }
754  }
755 
756  strncat (target, buf, sizeof (target) - strnlen (target, sizeof (target)));
757  }
758 
759  return target;
760 }
761 
762 /*
763  * es_print_symbol() -
764  * return : void
765  * sym(in): a symbol to be printed
766  * fp(in): the stream to print on
767  */
768 static void
769 es_print_symbol (SYMBOL * sym, FILE * fp)
770 {
771  fprintf (fp, " * %-18.18s %4d %s\n", sym->name, sym->level, pp_type_str (sym->type));
772 }
773 
774 /*
775  * es_print_struct() -
776  * return : void
777  * sdef(in): a structure definition
778  * fp(in): the stream to print it on
779  */
780 static void
781 es_print_struct (STRUCTDEF * sdef, FILE * fp)
782 {
783  SYMBOL *field;
784 
785  fprintf (fp, " * %s %s:\n", sdef->type_string, (sdef->tag ? sdef->tag : ((unsigned char *) "<anon>")));
786 
787  for (field = sdef->fields; field; field = field->next)
788  {
789  fprintf (fp, " * %-20s %s\n", field->name, pp_type_str (field->type));
790  }
791 }
792 
793 /*
794  * pp_print_syms() - Print the entire symbol table to the file.
795  * Previous contents of the file (if any) are destroyed. Prints to stdout
796  * if filename is NULL.
797  * return : void
798  * fp(in): the file pointer to print the symbol table to
799  */
800 void
801 pp_print_syms (FILE * fp)
802 {
803  if (fp == NULL)
804  {
805  fp = stdout;
806  }
807 
808  if (pp_Symbol_table->get_symbol_count (pp_Symbol_table))
809  {
810  fprintf (fp, " *\n * Symbol table:\n *\n");
811  //TODO: get rid of function pointer conversion
812  pp_Symbol_table->print_table (pp_Symbol_table, (void (*)()) es_print_symbol, fp, 1);
813  }
814 
815  if (pp_Struct_table->get_symbol_count (pp_Struct_table))
816  {
817  fprintf (fp, " *\n * Structure table:\n *\n");
818  //TODO: get rid of function pointer conversion
819  pp_Struct_table->print_table (pp_Struct_table, (void (*)()) es_print_struct, fp, 1);
820  }
821 }
822 
823 /*
824  * pp_findsym() - Find a pointer to the symbol with the given name, or NULL if
825  * there is no such symbol
826  * return : SYMBOL *
827  * symtab(in): The symbol table to be searched.
828  * name(in): The name to be searched for.
829  */
830 SYMBOL *
831 pp_findsym (SYMTAB * symtab, unsigned char *name)
832 {
833  SYMBOL dummy;
834 
835  dummy.name = name;
836  return (SYMBOL *) symtab->find_symbol (symtab, &dummy);
837 }
838 
839 /*
840  * pp_symbol_init() - Initialize interesting variables before starting off.
841  * return : void
842  */
843 void
845 {
846  pp_Symbol_table = pp_new_symtab ();
847  pp_Struct_table = pp_new_symtab ();
848 
849  symbol_free_list = NULL;
850  struct_free_list = NULL;
851  link_free_list = NULL;
852  link_chunks = NULL;
853 
854  syms_allocated = 0;
855  syms_deallocated = 0;
856  sdefs_allocated = 0;
857  sdefs_deallocated = 0;
858  links_allocated = 0;
859  links_deallocated = 0;
860 
861  syms_to_free_lists = 1;
862 }
863 
864 /*
865  * pp_symbol_finish() - Clean up all of the various local data structures.
866  * return : void
867  */
868 void
870 {
871  /*
872  * Make sure that the symbols that are about to be freed from the
873  * symbol tables are returned to the malloc pool rather than to our
874  * free lists.
875  */
876  syms_to_free_lists = 0;
877  pp_free_symtab (pp_Symbol_table, (HT_FREE_FN) pp_discard_symbol);
878  pp_free_symtab (pp_Struct_table, (HT_FREE_FN) pp_discard_structdef);
879 
880  /* However, there may still be some symbols left on our free lists; get rid of them. */
881  {
882  SYMBOL *sym, *next = NULL;
883 
884  for (sym = symbol_free_list; sym; sym = next)
885  {
886  next = sym->next;
887  es_ht_free_symbol (sym);
888  }
889  symbol_free_list = NULL;
890  }
891 
892  {
893  STRUCTDEF *sdef, *next = NULL;
894 
895  for (sdef = struct_free_list; sdef; sdef = next)
896  {
897  next = sdef->next;
898  es_ht_free_symbol ((void *) sdef);
899  }
900  struct_free_list = NULL;
901  }
902 
903  {
904  LINKCHUNK *chunk, *next = NULL;
905 
906  for (chunk = link_chunks; chunk; chunk = next)
907  {
908  next = chunk->next;
909  free_and_init (chunk);
910  }
911  link_chunks = NULL;
912  }
913 }
914 
915 /*
916  * pp_symbol_stats() - Print rudimentary statistics information.
917  * return : void
918  * fp(in): A stream to print the statistics on.
919  */
920 void
921 pp_symbol_stats (FILE * fp)
922 {
923 #if !defined(NDEBUG)
924 
926  {
927  fprintf (stderr, "symbol accounting problem: %d/%d\n", syms_allocated, syms_deallocated);
928  }
930  {
931  fprintf (stderr, "link accounting problem: %d/%d\n", links_allocated, links_deallocated);
932  }
934  {
935  fprintf (stderr, "structdef accounting problem: %d/%d\n", sdefs_allocated, sdefs_deallocated);
936  }
937 
939  {
940  fputs ("\n/*\n", fp);
941  fprintf (fp, " * %d/%d symbols allocated/deallocated\n", syms_allocated, syms_deallocated);
942  fprintf (fp, " * %d/%d links allocated/deallocated\n", links_allocated, links_deallocated);
943  fprintf (fp, " * %d/%d structdefs allocated/deallocated\n", sdefs_allocated, sdefs_deallocated);
944 
945  fputs (" */\n", fp);
946  }
947 #endif
948 }
#define IS_ARRAY(p)
Definition: esql_misc.h:52
HASH_TAB * es_ht_make_table(unsigned maxsym, HT_HASH_FN hash_function, HT_CMP_FN cmp_function)
Definition: esql_hash.c:383
static STRUCTDEF * struct_free_list
void pp_discard_symbol(SYMBOL *sym)
#define IS_PTR_TYPE(p)
Definition: esql_misc.h:85
void *(* add_symbol)(HASH_TAB *tbl, void *sym)
Definition: esql_hash.h:37
static int links_deallocated
static int sdefs_allocated
STRUCTDEF * pp_new_pseudo_def(SPECIFIER_NOUN type, const char *subscript)
unsigned char is_unsigned
void pp_free_symtab(SYMTAB *symtab, HT_FREE_FN free_fn)
char * pp_strdup(const char *str)
Definition: esql_misc.c:372
varstring * vs_new(varstring *vstr)
STRUCTDEF * pp_new_structdef(const char *tag)
void *(* find_symbol)(HASH_TAB *tbl, void *sym)
Definition: esql_hash.h:38
STRUCTDEF * v_struct
void pp_discard_structdef(STRUCTDEF *sdef)
SYMBOL * pp_findsym(SYMTAB *symtab, unsigned char *name)
SPECIFIER_NOUN noun
#define LCHUNK
int pp_generic_cmp(void *p1, void *p2)
Definition: esql_misc.c:132
unsigned char * tag
int(* get_symbol_count)(HASH_TAB *tbl)
Definition: esql_hash.h:42
STRUCTDEF * next
LINK * pp_current_type_spec(void)
Definition: esql_declare.c:663
SYMBOL * args
int(* print_table)(HASH_TAB *tbl, void(*prnt)(), void *par, int srt)
Definition: esql_hash.h:41
void esql_yyverror(const char *,...)
struct linkchunk * next
static SYMBOL * symbol_free_list
const char * pp_get_msg(int msg_set, int msg_num)
unsigned char is_long
static int syms_allocated
SYMTAB * pp_Struct_table
static void es_print_struct(STRUCTDEF *sdef, FILE *fp)
int vs_sprintf(varstring *vstr, const char *fmt,...)
SYMTAB * pp_new_symtab(void)
union specifier::@74 val
char * vs_str(varstring *vstr)
void(* HT_FREE_FN)(void *)
Definition: esql_hash.h:31
LINK link[LCHUNK]
void es_ht_free_symbol(void *sym)
Definition: esql_hash.c:369
#define IS_SPECIFIER(p)
Definition: esql_misc.h:49
struct linkchunk LINKCHUNK
void vs_free(varstring *vstr)
unsigned char type
void esql_yyerror(const char *)
#define assert(x)
SYMBOL * pp_clone_symbol(SYMBOL *sym)
#define IS_DECLARATOR(p)
Definition: esql_misc.h:50
esql_err_msg
SYMTAB * pp_Symbol_table
enum specifier_noun SPECIFIER_NOUN
void pp_add_declarator(SYMBOL *sym, int type)
int pp_the_same_type(LINK *p1, LINK *p2, int relax)
void pp_discard_link(LINK *p)
const char * VARCHAR_ARRAY_NAME
static int links_allocated
static int syms_deallocated
#define NULL
Definition: freelistheap.h:34
#define strncpy_bufsize(buf, str)
Definition: porting.h:340
static int sdefs_deallocated
unsigned char is_short
void pp_push_spec_scope(void)
Definition: esql_declare.c:577
#define IS_FUNCT(p)
Definition: esql_misc.h:56
void pp_discard_structdef_chain(STRUCTDEF *sdef_chain)
void pp_print_syms(FILE *fp)
static const unsigned int SYMTAB_SIZE
void pp_reset_current_type_spec(void)
Definition: esql_declare.c:639
void pp_symbol_finish(void)
unsigned int pp_generic_hash(void *p)
Definition: esql_misc.c:99
LINK * pp_new_link(void)
void pp_symbol_init(void)
int pp_dump_malloc_info
SYMBOL * pp_new_symbol(const char *name, int scope)
static LINK * link_free_list
LINK * pp_clone_type(LINK *tchain, LINK **endp)
void pp_add_spec_to_decl(LINK *p_spec, SYMBOL *decl_chain)
Definition: esql_declare.c:213
void pp_add_typedefed_spec(LINK *spec)
Definition: esql_declare.c:995
const char * pp_type_str(LINK *link)
const char * VARCHAR_LENGTH_NAME
void pp_symbol_stats(FILE *fp)
#define free_and_init(ptr)
Definition: memory_alloc.h:147
void pp_add_type_noun(int type)
Definition: esql_declare.c:754
void pp_pop_spec_scope(void)
Definition: esql_declare.c:626
SYMBOL * next
static int syms_to_free_lists
int i
Definition: dynamic_load.c:954
char * strdup(const char *str)
Definition: porting.c:901
unsigned char * name
void * es_ht_alloc_new_symbol(int size)
Definition: esql_hash.c:351
void pp_discard_link_chain(LINK *p)
enum dcl_type DCL_TYPE
void(* free_table)(HASH_TAB *tbl, HT_FREE_FN free)
Definition: esql_hash.h:36
static LINKCHUNK * link_chunks
static void es_print_symbol(SYMBOL *sym, FILE *fp)
int pp_nesting_level
Definition: esql_declare.c:114
char * pp_attr_str(LINK *type)
const char ** p
Definition: dynamic_load.c:945
void pp_discard_symbol_chain(SYMBOL *sym)
const unsigned char * type_string