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