1 /**
2  * Symbol table array.
3  *
4  * Copyright:   Copyright (C) 1985-1998 by Symantec
5  *              Copyright (C) 2000-2020 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 private void err_nomem();
37 
38 struct symtab_t
39 {
40   nothrow:
41     alias T = Symbol*;
42     alias capacity = symmax;
43 
44     /**********************
45      * Set useable length of array.
46      * Params:
47      *  length = minimum number of elements in array
48      */
49     void setLength(size_t length)
50     {
51         static void enlarge(ref symtab_t barray, size_t length)
52         {
53             pragma(inline, false);
54             const newcap = (barray.capacity == 0)
55                 ? length
56                 : (length + (length >> 1) + 15) & ~15;
57 
58             T* p;
59             if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
60                 p = cast(T*) MEM_PH_REALLOC(barray.tab, newcap * T.sizeof);
61             else
62                 p = cast(T*) realloc(barray.tab, newcap * T.sizeof);
63 
64             if (length && !p)
65             {
66                 version (unittest)
67                     assert(0);
68                 else
69                     err_nomem();
70             }
71             barray.tab = p;
72             barray.length = length;
73             barray.capacity = newcap;
74             //barray.array = p[0 .. length];
75         }
76 
77         if (length <= capacity)
78             this.length = length;               // the fast path
79             //array = array.ptr[0 .. length];   // the fast path
80         else
81             enlarge(this, length);              // the slow path
82     }
83 
84     ref inout(T) opIndex(size_t i) inout nothrow pure @nogc
85     {
86         assert(i < length);
87         return tab[i];
88     }
89 
90     extern (D) inout(T)[] opSlice() inout nothrow pure @nogc
91     {
92         return tab[0 .. length];
93     }
94 
95     extern (D) inout(T)[] opSlice(size_t a, size_t b) inout nothrow pure @nogc
96     {
97         assert(a <= b && b <= length);
98         return tab[a .. b];
99     }
100 
101     void dtor()
102     {
103         if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
104             MEM_PH_FREE(tab);
105         else
106             free(tab);
107         length = 0;
108         tab = null;
109         symmax = 0;
110     }
111 
112     SYMIDX length;              // 1 past end
113     SYMIDX symmax;              // max # of entries in tab[] possible
114     T* tab;                     // local Symbol table
115 }
116