1 /**
2  * Symbol table array.
3  *
4  * Copyright:   Copyright (C) 1985-1998 by Symantec
5  *              Copyright (C) 2000-2023 by The D Language Foundation, All Rights Reserved
6  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
7  * License:     $(LINK2 https://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 extern (C++):
23 
24 nothrow:
25 @safe:
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 import dmd.backend.global : 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         @trusted
52         static void enlarge(ref symtab_t barray, size_t length)
53         {
54             pragma(inline, false);
55             const newcap = (barray.capacity == 0)
56                 ? length
57                 : (length + (length >> 1) + 15) & ~15;
58 
59             T* p;
60             if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
61                 p = cast(T*) MEM_PH_REALLOC(barray.tab, newcap * T.sizeof);
62             else
63                 p = cast(T*) realloc(barray.tab, newcap * T.sizeof);
64 
65             if (length && !p)
66             {
67                 version (unittest)
68                     assert(0);
69                 else
70                     err_nomem();
71             }
72             barray.tab = p;
73             barray.length = length;
74             barray.capacity = newcap;
75             //barray.array = p[0 .. length];
76         }
77 
78         if (length <= capacity)
79             this.length = length;               // the fast path
80             //array = array.ptr[0 .. length];   // the fast path
81         else
82             enlarge(this, length);              // the slow path
83     }
84 
85     @trusted
86     ref inout(T) opIndex(size_t i) inout nothrow pure @nogc
87     {
88         assert(i < length);
89         return tab[i];
90     }
91 
92     @trusted
93     extern (D) inout(T)[] opSlice() inout nothrow pure @nogc
94     {
95         return tab[0 .. length];
96     }
97 
98     @trusted
99     extern (D) inout(T)[] opSlice(size_t a, size_t b) inout nothrow pure @nogc
100     {
101         assert(a <= b && b <= length);
102         return tab[a .. b];
103     }
104 
105     @trusted
106     void dtor()
107     {
108         if (config.flags2 & (CFG2phgen | CFG2phuse | CFG2phauto | CFG2phautoy))
109             MEM_PH_FREE(tab);
110         else
111             free(tab);
112         length = 0;
113         tab = null;
114         symmax = 0;
115     }
116 
117     SYMIDX length;              // 1 past end
118     SYMIDX symmax;              // max # of entries in tab[] possible
119     T* tab;                     // local Symbol table
120 }