annotate libphobos/libdruntime/rt/minfo.d @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /**
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 * Written in the D programming language.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 * Module initialization routines.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 * Copyright: Copyright Digital Mars 2000 - 2013.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 * License: Distributed under the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 * (See accompanying file LICENSE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 * Authors: Walter Bright, Sean Kelly
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 * Source: $(DRUNTIMESRC src/rt/_minfo.d)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 module rt.minfo;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 import core.stdc.stdlib; // alloca
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 import core.stdc.string; // memcpy
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 import rt.sections;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 enum
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 MIctorstart = 0x1, // we've started constructing it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 MIctordone = 0x2, // finished construction
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 MIstandalone = 0x4, // module ctor does not depend on other module
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 // ctors being done first
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 MItlsctor = 8,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 MItlsdtor = 0x10,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 MIctor = 0x20,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 MIdtor = 0x40,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 MIxgetMembers = 0x80,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 MIictor = 0x100,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 MIunitTest = 0x200,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 MIimportedModules = 0x400,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 MIlocalClasses = 0x800,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 MIname = 0x1000,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 /*****
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 * A ModuleGroup is an unordered collection of modules.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 * There is exactly one for:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 * 1. all statically linked in D modules, either directely or as shared libraries
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 * 2. each call to rt_loadLibrary()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 struct ModuleGroup
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 this(immutable(ModuleInfo*)[] modules) nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 _modules = modules;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 @property immutable(ModuleInfo*)[] modules() const nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 return _modules;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 // this function initializes the bookeeping necessary to create the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 // cycle path, and then creates it. It is a precondition that src and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 // target modules are involved in a cycle.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 // The return value is malloc'd using C, so it must be freed after use.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 private size_t[] genCyclePath(size_t srcidx, size_t targetidx, int[][] edges)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 import core.bitop : bt, btc, bts;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 // set up all the arrays.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 size_t[] cyclePath = (cast(size_t*)malloc(size_t.sizeof * _modules.length * 2))[0 .. _modules.length * 2];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 size_t totalMods;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 int[] distance = (cast(int*)malloc(int.sizeof * _modules.length))[0 .. _modules.length];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 scope(exit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 .free(distance.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 // determine the shortest path between two modules. Uses dijkstra
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 // without a priority queue. (we can be a bit slow here, in order to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 // get a better printout).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 void shortest(size_t start, size_t target)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 // initial setup
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 distance[] = int.max;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 int curdist = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 distance[start] = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 while (true)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 bool done = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 foreach (i, x; distance)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 if (x == curdist)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 if (i == target)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 done = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 foreach (n; edges[i])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 if (distance[n] == int.max)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 distance[n] = curdist + 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 done = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 if (done)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 ++curdist;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 // it should be impossible to not get to target, this is just a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 // sanity check. Not an assert, because druntime is compiled in
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 // release mode.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 if (distance[target] != curdist)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 throw new Error("internal error printing module cycle");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 // determine the path. This is tricky, because we have to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 // follow the edges in reverse to get back to the original. We
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 // don't have a reverse mapping, so it takes a bit of looping.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 totalMods += curdist;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 auto subpath = cyclePath[totalMods - curdist .. totalMods];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 while (true)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 --curdist;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 subpath[curdist] = target;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 if (curdist == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 distloop:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 // search for next (previous) module in cycle.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 foreach (m, d; distance)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 if (d == curdist)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 // determine if m can reach target
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 foreach (e; edges[m])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 if (e == target)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 // recurse
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 target = m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 break distloop;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 // first get to the target
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 shortest(srcidx, targetidx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 // now get back.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 shortest(targetidx, srcidx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 return cyclePath[0 .. totalMods];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 /******************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 * Allocate and fill in _ctors[] and _tlsctors[].
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 * Modules are inserted into the arrays in the order in which the constructors
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 * need to be run.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 * cycleHandling - string indicating option for cycle handling
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 * Throws:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 * Exception if it fails.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 void sortCtors(string cycleHandling)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 import core.bitop : bts, btr, bt, BitRange;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 import rt.util.container.hashtab;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 enum OnCycle
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 deprecate,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 abort,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 print,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 ignore
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 auto onCycle = OnCycle.abort;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 switch (cycleHandling) with(OnCycle)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 case "deprecate":
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 onCycle = deprecate;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 case "abort":
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 onCycle = abort;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 case "print":
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 onCycle = print;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 case "ignore":
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 onCycle = ignore;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 case "":
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 // no option passed
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 // invalid cycle handling option.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 throw new Error("DRT invalid cycle handling option: " ~ cycleHandling);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 debug (printModuleDependencies)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 import core.stdc.stdio : printf;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 foreach (_m; _modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 printf("%s%s%s:", _m.name.ptr, (_m.flags & MIstandalone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 ? "+".ptr : "".ptr, (_m.flags & (MIctor | MIdtor)) ? "*".ptr : "".ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 foreach (_i; _m.importedModules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 printf(" %s", _i.name.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 printf("\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 immutable uint len = cast(uint) _modules.length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 if (!len)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 return; // nothing to do.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 // allocate some stack arrays that will be used throughout the process.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 immutable nwords = (len + 8 * size_t.sizeof - 1) / (8 * size_t.sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 immutable flagbytes = nwords * size_t.sizeof;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 auto ctorstart = cast(size_t*) malloc(flagbytes); // ctor/dtor seen
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 auto ctordone = cast(size_t*) malloc(flagbytes); // ctor/dtor processed
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 auto relevant = cast(size_t*) malloc(flagbytes); // has ctors/dtors
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 scope (exit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 .free(ctorstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 .free(ctordone);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 .free(relevant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 void clearFlags(size_t* flags)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 memset(flags, 0, flagbytes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 // build the edges between each module. We may need this for printing,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 // and also allows avoiding keeping a hash around for module lookups.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 int[][] edges = (cast(int[]*)malloc((int[]).sizeof * _modules.length))[0 .. _modules.length];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 HashTab!(immutable(ModuleInfo)*, int) modIndexes;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 foreach (i, m; _modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 modIndexes[m] = cast(int) i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 auto reachable = cast(size_t*) malloc(flagbytes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 scope(exit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 .free(reachable);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 foreach (i, m; _modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 // use bit array to prevent duplicates
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 // https://issues.dlang.org/show_bug.cgi?id=16208
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 clearFlags(reachable);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 // preallocate enough space to store all the indexes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 int *edge = cast(int*)malloc(int.sizeof * _modules.length);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 size_t nEdges = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 foreach (imp; m.importedModules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 if (imp is m) // self-import
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 if (auto impidx = imp in modIndexes)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 if (!bts(reachable, *impidx))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 edge[nEdges++] = *impidx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 // trim space to what is needed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 edges[i] = (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 // free all the edges after we are done
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 scope(exit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 foreach (e; edges)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 if (e.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 .free(e.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 .free(edges.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 void buildCycleMessage(size_t sourceIdx, size_t cycleIdx, scope void delegate(string) sink)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 version (Windows)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 enum EOL = "\r\n";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 enum EOL = "\n";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 sink("Cyclic dependency between module ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 sink(_modules[sourceIdx].name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 sink(" and ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 sink(_modules[cycleIdx].name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 sink(EOL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 auto cyclePath = genCyclePath(sourceIdx, cycleIdx, edges);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 scope(exit) .free(cyclePath.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 sink(_modules[sourceIdx].name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 sink("* ->" ~ EOL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 foreach (x; cyclePath[0 .. $ - 1])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 sink(_modules[x].name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 sink(bt(relevant, x) ? "* ->" ~ EOL : " ->" ~ EOL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 sink(_modules[sourceIdx].name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 sink("*" ~ EOL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 // find all the non-trivial dependencies (that is, dependencies that have a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 // ctor or dtor) of a given module. Doing this, we can 'skip over' the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 // trivial modules to get at the non-trivial ones.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 // If a cycle is detected, returns the index of the module that completes the cycle.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 // Returns: true for success, false for a deprecated cycle error
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 bool findDeps(size_t idx, size_t* reachable)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 static struct stackFrame
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 size_t curMod;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 size_t curDep;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 // initialize "stack"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 auto stack = cast(stackFrame*) malloc(stackFrame.sizeof * len);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 scope (exit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 .free(stack);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 auto stacktop = stack + len;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 auto sp = stack;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 sp.curMod = cast(int) idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 sp.curDep = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 // initialize reachable by flagging source module
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 clearFlags(reachable);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 bts(reachable, idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 for (;;)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 auto m = _modules[sp.curMod];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 if (sp.curDep >= edges[sp.curMod].length)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 // return
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 if (sp == stack) // finished the algorithm
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 --sp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 auto midx = edges[sp.curMod][sp.curDep];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 if (!bts(reachable, midx))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 if (bt(relevant, midx))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 // need to process this node, don't recurse.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 if (bt(ctorstart, midx))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 // was already started, this is a cycle.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 final switch (onCycle) with(OnCycle)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 case deprecate:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 // check with old algorithm
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 if (sortCtorsOld(edges))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 // unwind to print deprecation message.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 return false; // deprecated cycle error
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 goto case abort; // fall through
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 case abort:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 string errmsg = "";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 buildCycleMessage(idx, midx, (string x) {errmsg ~= x;});
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 throw new Error(errmsg, __FILE__, __LINE__);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 case ignore:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 case print:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 // print the message
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 buildCycleMessage(idx, midx, (string x) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 import core.stdc.stdio : fprintf, stderr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 fprintf(stderr, "%.*s", cast(int) x.length, x.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 });
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 // continue on as if this is correct.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 else if (!bt(ctordone, midx))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 // non-relevant, and hasn't been exhaustively processed, recurse.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 if (++sp >= stacktop)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 // stack overflow, this shouldn't happen.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 import core.internal.abort : abort;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 abort("stack overflow on dependency search");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 sp.curMod = midx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 sp.curDep = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 // next dependency
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 ++sp.curDep;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 return true; // success
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 // The list of constructors that will be returned by the sorting.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 immutable(ModuleInfo)** ctors;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 // current element being inserted into ctors list.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 size_t ctoridx = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 // This function will determine the order of construction/destruction and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 // check for cycles. If a cycle is found, the cycle path is transformed
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 // into a string and thrown as an error.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 // Each call into this function is given a module that has static
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 // ctor/dtors that must be dealt with. It recurses only when it finds
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 // dependencies that also have static ctor/dtors.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 // Returns: true for success, false for a deprecated cycle error
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 bool processMod(size_t curidx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 immutable ModuleInfo* current = _modules[curidx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 // First, determine what modules are reachable.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 auto reachable = cast(size_t*) malloc(flagbytes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 scope (exit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 .free(reachable);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 if (!findDeps(curidx, reachable))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 return false; // deprecated cycle error
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 // process the dependencies. First, we process all relevant ones
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 bts(ctorstart, curidx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 auto brange = BitRange(reachable, len);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 foreach (i; brange)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 // note, don't check for cycles here, because the config could have been set to ignore cycles.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 // however, don't recurse if there is one, so still check for started ctor.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 if (i != curidx && bt(relevant, i) && !bt(ctordone, i) && !bt(ctorstart, i))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 if (!processMod(i))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 return false; // deprecated cycle error
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 // now mark this node, and all nodes reachable from this module as done.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 bts(ctordone, curidx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 btr(ctorstart, curidx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 foreach (i; brange)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 // Since relevant dependencies are already marked as done
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 // from recursion above (or are going to be handled up the call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 // stack), no reason to check for relevance, that is a wasted
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 // op.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 bts(ctordone, i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 // add this module to the construction order list
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 ctors[ctoridx++] = current;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 // returns `false` if deprecated cycle error otherwise set `result`.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 bool doSort(size_t relevantFlags, ref immutable(ModuleInfo)*[] result)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 clearFlags(relevant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 clearFlags(ctorstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 clearFlags(ctordone);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 // pre-allocate enough space to hold all modules.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 ctors = (cast(immutable(ModuleInfo)**).malloc(len * (void*).sizeof));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 ctoridx = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 foreach (idx, m; _modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 if (m.flags & relevantFlags)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 if (m.flags & MIstandalone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 // can run at any time. Just run it first.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 ctors[ctoridx++] = m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 bts(relevant, idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 // now run the algorithm in the relevant ones
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 foreach (idx; BitRange(relevant, len))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 if (!bt(ctordone, idx))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 if (!processMod(idx))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 if (ctoridx == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 // no ctors in the list.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 .free(ctors);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 ctors = cast(immutable(ModuleInfo)**).realloc(ctors, ctoridx * (void*).sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 if (ctors is null)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 result = ctors[0 .. ctoridx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 // finally, do the sorting for both shared and tls ctors. If either returns false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 // print the deprecation warning.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 if (!doSort(MIctor | MIdtor, _ctors) ||
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 !doSort(MItlsctor | MItlsdtor, _tlsctors))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 // print a warning
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 import core.stdc.stdio : fprintf, stderr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 fprintf(stderr, "Deprecation 16211 warning:\n"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 ~ "A cycle has been detected in your program that was undetected prior to DMD\n"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 ~ "2.072. This program will continue, but will not operate when using DMD 2.074\n"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 ~ "to compile. Use runtime option --DRT-oncycle=print to see the cycle details.\n");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 /// ditto
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 void sortCtors()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 import rt.config : rt_configOption;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 sortCtors(rt_configOption("oncycle"));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 /******************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 * This is the old ctor sorting algorithm that does not find all cycles.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 * It is here to allow the deprecated behavior from the original algorithm
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 * until people have fixed their code.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 * If no cycles are found, the _ctors and _tlsctors are replaced with the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 * ones generated by this algorithm to preserve the old incorrect ordering
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 * behavior.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 * Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 * edges - The module edges as found in the `importedModules` member of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 * each ModuleInfo. Generated in sortCtors.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 * Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 * true if no cycle is found, false if one was.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 bool sortCtorsOld(int[][] edges)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 immutable len = edges.length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 assert(len == _modules.length);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 static struct StackRec
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 @property int mod()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 return _mods[_idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 int[] _mods;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 size_t _idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 auto stack = (cast(StackRec*).calloc(len, StackRec.sizeof))[0 .. len];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 // TODO: reuse GCBits by moving it to rt.util.container or core.internal
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 immutable nwords = (len + 8 * size_t.sizeof - 1) / (8 * size_t.sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 auto ctorstart = cast(size_t*).malloc(nwords * size_t.sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 auto ctordone = cast(size_t*).malloc(nwords * size_t.sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573 int[] initialEdges = (cast(int *)malloc(int.sizeof * len))[0 .. len];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 if (!stack.ptr || ctorstart is null || ctordone is null || !initialEdges.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 scope (exit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 .free(stack.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 .free(ctorstart);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 .free(ctordone);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 .free(initialEdges.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 // initialize the initial edges
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 foreach (i, ref v; initialEdges)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 v = cast(int)i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 bool sort(ref immutable(ModuleInfo)*[] ctors, uint mask)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 import core.bitop;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 ctors = (cast(immutable(ModuleInfo)**).malloc(len * size_t.sizeof))[0 .. len];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 if (!ctors.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 // clean flags
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 memset(ctorstart, 0, nwords * size_t.sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 memset(ctordone, 0, nwords * size_t.sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 size_t stackidx = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 size_t cidx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 int[] mods = initialEdges;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 size_t idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 while (true)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 while (idx < mods.length)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 auto m = mods[idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 if (bt(ctordone, m))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 // this module has already been processed, skip
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 ++idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 else if (bt(ctorstart, m))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 /* Trace back to the begin of the cycle.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 bool ctorInCycle;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 size_t start = stackidx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 while (start--)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 auto sm = stack[start].mod;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 if (sm == m)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 assert(sm >= 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 if (bt(ctorstart, sm))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 ctorInCycle = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 assert(stack[start].mod == m);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 if (ctorInCycle)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 /* This is also a cycle, but the import chain does not constrain
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 * the order of initialization, either because the imported
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 * modules have no ctors or the ctors are standalone.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 ++idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 auto curmod = _modules[m];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 if (curmod.flags & mask)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 if (curmod.flags & MIstandalone || !edges[m].length)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 { // trivial ctor => sort in
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 ctors[cidx++] = curmod;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 bts(ctordone, m);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 { // non-trivial ctor => defer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 bts(ctorstart, m);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 else // no ctor => mark as visited
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 bts(ctordone, m);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 if (edges[m].length)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 /* Internal runtime error, recursion exceeds number of modules.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 (stackidx < len) || assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 // recurse
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 stack[stackidx++] = StackRec(mods, idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 idx = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 mods = edges[m];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 if (stackidx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 { // pop old value from stack
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 --stackidx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 mods = stack[stackidx]._mods;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 idx = stack[stackidx]._idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 auto m = mods[idx++];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 if (bt(ctorstart, m) && !bts(ctordone, m))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 ctors[cidx++] = _modules[m];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 else // done
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 // store final number and shrink array
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 ctors = (cast(immutable(ModuleInfo)**).realloc(ctors.ptr, cidx * size_t.sizeof))[0 .. cidx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 /* Do two passes: ctor/dtor, tlsctor/tlsdtor
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 immutable(ModuleInfo)*[] _ctors2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 immutable(ModuleInfo)*[] _tlsctors2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 auto result = sort(_ctors2, MIctor | MIdtor) && sort(_tlsctors2, MItlsctor | MItlsdtor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 if (result) // no cycle
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 // fall back to original ordering as part of the deprecation.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 if (_ctors.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 .free(_ctors.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 _ctors = _ctors2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 if (_tlsctors.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 .free(_tlsctors.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 _tlsctors = _tlsctors2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 // free any allocated memory that will be forgotten
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 if (_ctors2.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 .free(_ctors2.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 if (_tlsctors2.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 .free(_tlsctors2.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 void runCtors()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 // run independent ctors
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 runModuleFuncs!(m => m.ictor)(_modules);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 // sorted module ctors
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 runModuleFuncs!(m => m.ctor)(_ctors);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 void runTlsCtors()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 runModuleFuncs!(m => m.tlsctor)(_tlsctors);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 void runTlsDtors()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738 runModuleFuncsRev!(m => m.tlsdtor)(_tlsctors);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 void runDtors()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 runModuleFuncsRev!(m => m.dtor)(_ctors);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746 void free()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 if (_ctors.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 .free(_ctors.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 _ctors = null;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 if (_tlsctors.ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 .free(_tlsctors.ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 _tlsctors = null;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 // _modules = null; // let the owner free it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758 immutable(ModuleInfo*)[] _modules;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 immutable(ModuleInfo)*[] _ctors;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 immutable(ModuleInfo)*[] _tlsctors;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 /********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765 * Iterate over all module infos.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 int moduleinfos_apply(scope int delegate(immutable(ModuleInfo*)) dg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 foreach (ref sg; SectionGroup)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 foreach (m; sg.modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774 // TODO: Should null ModuleInfo be allowed?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 if (m !is null)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 if (auto res = dg(m))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 return res;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785 /********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786 * Module constructor and destructor routines.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 extern (C)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 void rt_moduleCtor()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 foreach (ref sg; SectionGroup)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 sg.moduleGroup.sortCtors();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796 sg.moduleGroup.runCtors();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800 void rt_moduleTlsCtor()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 foreach (ref sg; SectionGroup)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 sg.moduleGroup.runTlsCtors();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 void rt_moduleTlsDtor()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 foreach_reverse (ref sg; SectionGroup)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 sg.moduleGroup.runTlsDtors();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 void rt_moduleDtor()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 foreach_reverse (ref sg; SectionGroup)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 sg.moduleGroup.runDtors();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 sg.moduleGroup.free();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 version (Win32)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 // Alternate names for backwards compatibility with older DLL code
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 void _moduleCtor()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 rt_moduleCtor();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 void _moduleDtor()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 rt_moduleDtor();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 void _moduleTlsCtor()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840 rt_moduleTlsCtor();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 void _moduleTlsDtor()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845 rt_moduleTlsDtor();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 /********************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 void runModuleFuncs(alias getfp)(const(immutable(ModuleInfo)*)[] modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 foreach (m; modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 if (auto fp = getfp(m))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858 (*fp)();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862 void runModuleFuncsRev(alias getfp)(const(immutable(ModuleInfo)*)[] modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864 foreach_reverse (m; modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866 if (auto fp = getfp(m))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 (*fp)();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 static void assertThrown(T : Throwable, E)(lazy E expr, string msg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 try
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 expr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 catch (T)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879 assert(0, msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 static void stub()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 static struct UTModuleInfo
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888 this(uint flags)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 mi._flags = flags;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893 void setImports(immutable(ModuleInfo)*[] imports...)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 import core.bitop;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 assert(flags & MIimportedModules);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898 immutable nfuncs = popcnt(flags & (MItlsctor|MItlsdtor|MIctor|MIdtor|MIictor));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 immutable size = nfuncs * (void function()).sizeof +
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 size_t.sizeof + imports.length * (ModuleInfo*).sizeof;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 assert(size <= pad.sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 pad[nfuncs] = imports.length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 .memcpy(&pad[nfuncs+1], imports.ptr, imports.length * imports[0].sizeof);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907 immutable ModuleInfo mi;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 size_t[8] pad;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 alias mi this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 static UTModuleInfo mockMI(uint flags)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 auto mi = UTModuleInfo(flags | MIimportedModules);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 auto p = cast(void function()*)&mi.pad;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 if (flags & MItlsctor) *p++ = &stub;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917 if (flags & MItlsdtor) *p++ = &stub;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 if (flags & MIctor) *p++ = &stub;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919 if (flags & MIdtor) *p++ = &stub;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920 if (flags & MIictor) *p++ = &stub;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921 *cast(size_t*)p++ = 0; // number of imported modules
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 assert(cast(void*)p <= &mi + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923 return mi;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 static void checkExp2(string testname, bool shouldThrow, string oncycle,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927 immutable(ModuleInfo*)[] modules,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 immutable(ModuleInfo*)[] dtors=null,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929 immutable(ModuleInfo*)[] tlsdtors=null)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931 auto mgroup = ModuleGroup(modules);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 mgroup.sortCtors(oncycle);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934 // if we are expecting sort to throw, don't throw because of unexpected
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935 // success!
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936 if (!shouldThrow)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 foreach (m; mgroup._modules)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939 assert(!(m.flags & (MIctorstart | MIctordone)), testname);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940 assert(mgroup._ctors == dtors, testname);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 assert(mgroup._tlsctors == tlsdtors, testname);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945 static void checkExp(string testname, bool shouldThrow,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 immutable(ModuleInfo*)[] modules,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947 immutable(ModuleInfo*)[] dtors=null,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 immutable(ModuleInfo*)[] tlsdtors=null)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950 checkExp2(testname, shouldThrow, "abort", modules, dtors, tlsdtors);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 auto m0 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956 auto m1 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958 checkExp("no ctors", false, [&m0.mi, &m1.mi, &m2.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962 auto m0 = mockMI(MIictor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963 auto m1 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964 auto m2 = mockMI(MIictor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965 auto mgroup = ModuleGroup([&m0.mi, &m1.mi, &m2.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 checkExp("independent ctors", false, [&m0.mi, &m1.mi, &m2.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970 auto m0 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 auto m1 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973 auto mgroup = ModuleGroup([&m0.mi, &m1.mi, &m2.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974 checkExp("standalone ctor", false, [&m0.mi, &m1.mi, &m2.mi], [&m0.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978 auto m0 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979 auto m1 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 m1.setImports(&m0.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982 checkExp("imported standalone => no dependency", false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987 auto m0 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988 auto m1 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 m0.setImports(&m1.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991 checkExp("imported standalone => no dependency (2)", false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992 [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996 auto m0 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997 auto m1 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999 m0.setImports(&m1.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000 m1.setImports(&m0.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001 checkExp("standalone may have cycle", false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006 auto m0 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1009 m1.setImports(&m0.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1010 checkExp("imported ctor => ordered ctors", false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1011 [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi], []);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1012 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1013
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1014 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1015 auto m0 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1016 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1017 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1018 m0.setImports(&m1.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1019 checkExp("imported ctor => ordered ctors (2)", false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1020 [&m0.mi, &m1.mi, &m2.mi], [&m1.mi, &m0.mi], []);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1021 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1022
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1023 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1024 auto m0 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1025 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1026 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1027 m0.setImports(&m1.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1028 m1.setImports(&m0.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1029 assertThrown!Throwable(checkExp("", true, [&m0.mi, &m1.mi, &m2.mi]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1030 "detects ctors cycles");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1031 assertThrown!Throwable(checkExp2("", true, "deprecate",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1032 [&m0.mi, &m1.mi, &m2.mi]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1033 "detects ctors cycles (dep)");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1034 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1035
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1036 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1037 auto m0 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1038 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1039 auto m2 = mockMI(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1040 m0.setImports(&m2.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1041 m1.setImports(&m2.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1042 m2.setImports(&m0.mi, &m1.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1043 assertThrown!Throwable(checkExp("", true, [&m0.mi, &m1.mi, &m2.mi]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1044 "detects cycle with repeats");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1045 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1046
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1047 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1048 auto m0 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1049 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1050 auto m2 = mockMI(MItlsctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1051 m0.setImports(&m1.mi, &m2.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1052 checkExp("imported ctor/tlsctor => ordered ctors/tlsctors", false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1053 [&m0.mi, &m1.mi, &m2.mi], [&m1.mi, &m0.mi], [&m2.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1054 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1055
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1056 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1057 auto m0 = mockMI(MIctor | MItlsctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1058 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1059 auto m2 = mockMI(MItlsctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1060 m0.setImports(&m1.mi, &m2.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1061 checkExp("imported ctor/tlsctor => ordered ctors/tlsctors (2)", false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1062 [&m0.mi, &m1.mi, &m2.mi], [&m1.mi, &m0.mi], [&m2.mi, &m0.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1063 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1064
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1065 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1066 auto m0 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1067 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1068 auto m2 = mockMI(MItlsctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1069 m0.setImports(&m1.mi, &m2.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1070 m2.setImports(&m0.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1071 checkExp("no cycle between ctors/tlsctors", false,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1072 [&m0.mi, &m1.mi, &m2.mi], [&m1.mi, &m0.mi], [&m2.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1073 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1074
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1075 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1076 auto m0 = mockMI(MItlsctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1077 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1078 auto m2 = mockMI(MItlsctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1079 m0.setImports(&m2.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1080 m2.setImports(&m0.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1081 assertThrown!Throwable(checkExp("", true, [&m0.mi, &m1.mi, &m2.mi]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1082 "detects tlsctors cycle");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1083 assertThrown!Throwable(checkExp2("", true, "deprecate",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1084 [&m0.mi, &m1.mi, &m2.mi]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1085 "detects tlsctors cycle (dep)");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1086 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1087
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1088 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1089 auto m0 = mockMI(MItlsctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1090 auto m1 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1091 auto m2 = mockMI(MItlsctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1092 m0.setImports(&m1.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1093 m1.setImports(&m0.mi, &m2.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1094 m2.setImports(&m1.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1095 assertThrown!Throwable(checkExp("", true, [&m0.mi, &m1.mi, &m2.mi]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1096 "detects tlsctors cycle with repeats");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1097 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1098
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1099 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1100 auto m0 = mockMI(MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1101 auto m1 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1102 auto m2 = mockMI(MIstandalone | MIctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1103 m0.setImports(&m1.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1104 m1.setImports(&m2.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1105 m2.setImports(&m0.mi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1106 // NOTE: this is implementation dependent, sorted order shouldn't be tested.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1107 checkExp("closed ctors cycle", false, [&m0.mi, &m1.mi, &m2.mi],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1108 [&m1.mi, &m2.mi, &m0.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1109 //checkExp("closed ctors cycle", false, [&m0.mi, &m1.mi, &m2.mi], [&m0.mi, &m1.mi, &m2.mi]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1110 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1111 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1112
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1113 version (CRuntime_Microsoft)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1114 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1115 // Dummy so Win32 code can still call it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1116 extern(C) void _minit() { }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1117 }