1 /**
2  * Symbol table array.
3  *
4  * Copyright:   Copyright (C) 1985-1998 by Symantec
5  *              Copyright (C) 2000-2021 by The D Language Foundation, All Rights Reserved
6  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
7  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/symtab.d, backend/_symtab.d)
9  * Documentation:  https://dlang.org/phobos/dmd_backend_symtab.html
10  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/backend/symtab.d
11  */
12 
13 module dmd.backend.symtab;
14 
15 import core.stdc.stdio;
16 import core.stdc.stdlib;
17 
18 import dmd.backend.cdef;
19 import dmd.backend.cc;
20 import dmd.backend.mem;
21 
22 
23 extern (C++):
24 
25 nothrow:
26 
27 alias SYMIDX = size_t;    // symbol table index
28 
29 alias MEM_PH_MALLOC = mem_malloc;
30 alias MEM_PH_CALLOC = mem_calloc;
31 alias MEM_PH_FREE = mem_free;
32 alias MEM_PH_FREEFP = mem_freefp;
33 alias MEM_PH_STRDUP = mem_strdup;
34 alias MEM_PH_REALLOC = mem_realloc;
35 
36 void stackoffsets(ref symtab_t, bool);
37 
38 private void err_nomem();
39 
40 struct symtab_t
41 {
42   nothrow:
43     alias T = Symbol*;
44     alias capacity = symmax;
45 
46     /**********************
47      * Set useable length of array.
48      * Params:
49      *  length = minimum number of elements in array
50      */
51     void setLength(size_t length)
52     {
53         static void enlarge(ref symtab_t barray, size_t length)
54         {
55             pragma(inline, false);
56             const newcap = (barray.capacity == 0)
57                 ? length
58                 : (length + (length >> 1) + 15) & ~15;
59 
60             T* p;
61             if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
62                 p = cast(T*) MEM_PH_REALLOC(barray.tab, newcap * T.sizeof);
63             else
64                 p = cast(T*) realloc(barray.tab, newcap * T.sizeof);
65 
66             if (length && !p)
67             {
68                 version (unittest)
69                     assert(0);
70                 else
71                     err_nomem();
72             }
73             barray.tab = p;
74             barray.length = length;
75             barray.capacity = newcap;
76             //barray.array = p[0 .. length];
77         }
78 
79         if (length <= capacity)
80             this.length = length;               // the fast path
81             //array = array.ptr[0 .. length];   // the fast path
82         else
83             enlarge(this, length);              // the slow path
84     }
85 
86     ref inout(T) opIndex(size_t i) inout nothrow pure @nogc
87     {
88         assert(i < length);
89         return tab[i];
90     }
91 
92     extern (D) inout(T)[] opSlice() inout nothrow pure @nogc
93     {
94         return tab[0 .. length];
95     }
96 
97     extern (D) inout(T)[] opSlice(size_t a, size_t b) inout nothrow pure @nogc
98     {
99         assert(a <= b && b <= length);
100         return tab[a .. b];
101     }
102 
103     void dtor()
104     {
105         if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
106             MEM_PH_FREE(tab);
107         else
108             free(tab);
109         length = 0;
110         tab = null;
111         symmax = 0;
112     }
113 
114     SYMIDX length;              // 1 past end
115     SYMIDX symmax;              // max # of entries in tab[] possible
116     T* tab;                     // local Symbol table
117 }
118