1 /**
2  * Declarations for back end
3  *
4  * Compiler implementation of the
5  * $(LINK2 https://www.dlang.org, D programming language).
6  *
7  * Copyright:   Copyright (C) 1984-1998 by Symantec
8  *              Copyright (C) 2000-2023 by The D Language Foundation, All Rights Reserved
9  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
10  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
11  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/global.d, backend/global.d)
12  */
13 module dmd.backend.global;
14 
15 // Online documentation: https://dlang.org/phobos/dmd_backend_global.html
16 
17 extern (C++):
18 @nogc:
19 nothrow:
20 
21 import core.stdc.stdio;
22 import core.stdc.stdint;
23 
24 import dmd.backend.cdef;
25 import dmd.backend.cc;
26 import dmd.backend.cc : Symbol, block, Classsym, Blockx;
27 import dmd.backend.code_x86 : code;
28 import dmd.backend.code;
29 import dmd.backend.dlist;
30 import dmd.backend.el;
31 import dmd.backend.el : elem;
32 import dmd.backend.mem;
33 import dmd.backend.symtab;
34 import dmd.backend.type;
35 //import dmd.backend.obj;
36 
37 import dmd.backend.barray;
38 
39 nothrow:
40 @safe:
41 
42 extern __gshared
43 {
44     char debuga;            // cg - watch assignaddr()
45     char debugb;            // watch block optimization
46     char debugc;            // watch code generated
47     char debugd;            // watch debug information generated
48     char debuge;            // dump eh info
49     char debugf;            // trees after dooptim
50     char debugg;            // trees for code generator
51     char debugo;            // watch optimizer
52     char debugr;            // watch register allocation
53     char debugs;            // watch common subexp eliminator
54     char debugt;            // do test points
55     char debugu;
56     char debugw;            // watch progress
57     char debugx;            // suppress predefined CPP stuff
58     char debugy;            // watch output to il buffer
59 }
60 
61 enum CR = '\r';             // Used because the MPW version of the compiler warps
62 enum LF = '\n';             // \n into \r and \r into \n.  The translator version
63                             // does not and this causes problems with the compilation
64                             // with the translator
65 enum CR_STR = "\r";
66 enum LF_STR = "\n";
67 
68 extern __gshared
69 {
70     const uint[32] mask;            // bit masks
71     const uint[32] maskl;           // bit masks
72 
73     char* argv0;
74     char* finname, foutname, foutdir;
75 
76     char OPTIMIZER,PARSER;
77     symtab_t globsym;
78 
79 //    Config config;                  // precompiled part of configuration
80     char[SCMAX] sytab;
81 
82     extern (C) /*volatile*/ int controlc_saw;    // a control C was seen
83     block* startblock;              // beginning block of function
84 
85     Barray!(block*) dfo;            // array of depth first order
86 
87     block* curblock;                // current block being read in
88     block* block_last;
89 
90     int errcnt;
91     regm_t fregsaved;
92 
93     tym_t pointertype;              // default data pointer type
94 
95     // cg.c
96     Symbol* localgot;
97     Symbol* tls_get_addr_sym;
98 }
99 
100 version (MARS)
101     __gshared Configv configv;                // non-ph part of configuration
102 else
103     extern __gshared Configv configv;                // non-ph part of configuration
104 
105 // iasm.c
106 Symbol *asm_define_label(const(char)* id);
107 
108 // cpp.c
109 const(char)* cpp_mangle(Symbol* s);
110 
111 // ee.c
112 void eecontext_convs(SYMIDX marksi);
113 void eecontext_parse();
114 
115 // exp2.c
116 //#define REP_THRESHOLD (REGSIZE * (6+ (REGSIZE == 4)))
117         /* doesn't belong here, but func to OPxxx is in exp2 */
118 void exp2_setstrthis(elem *e,Symbol *s,targ_size_t offset,type *t);
119 Symbol *exp2_qualified_lookup(Classsym *sclass, int flags, int *pflags);
120 elem *exp2_copytotemp(elem *e);
121 
122 void util_progress();
123 void util_set16();
124 void util_set32(exefmt_t);
125 void util_set64(exefmt_t);
126 int ispow2(ulong);
127 
128 version (Posix)
129 {
130 void* util_malloc(uint n,uint size) { return mem_malloc(n * size); }
131 void* util_calloc(uint n,uint size) { return mem_calloc(n * size); }
132 void util_free(void *p) { mem_free(p); }
133 void *util_realloc(void *oldp,size_t n,size_t size) { return mem_realloc(oldp, n * size); }
134 //#define parc_malloc     mem_malloc
135 //#define parc_calloc     mem_calloc
136 //#define parc_realloc    mem_realloc
137 //#define parc_strdup     mem_strdup
138 //#define parc_free       mem_free
139 }
140 else
141 {
142 void *util_malloc(uint n,uint size);
143 void *util_calloc(uint n,uint size);
144 void util_free(void *p);
145 void *util_realloc(void *oldp,size_t n,size_t size);
146 void *parc_malloc(size_t len);
147 void *parc_calloc(size_t len);
148 void *parc_realloc(void *oldp,size_t len);
149 char *parc_strdup(const(char)* s);
150 void parc_free(void *p);
151 }
152 
153 void swap(int *, int *);
154 //void crlf(FILE *);
155 int isignore(int);
156 int isillegal(int);
157 
158 //#if !defined(__DMC__) && !defined(_MSC_VER)
159 int ishex(int);
160 //#endif
161 
162 /* from cgcs.c */
163 void comsubs();
164 void cgcs_term();
165 
166 /* errmsgs.c */
167 char *dlcmsgs(int);
168 void errmsgs_term();
169 
170 /* from evalu8.c */
171 int boolres(elem *);
172 int iftrue(elem *);
173 int iffalse(elem *);
174 elem *poptelem(elem *);
175 elem *poptelem2(elem *);
176 elem *poptelem3(elem *);
177 elem *poptelem4(elem *);
178 elem *selecte1(elem *, type *);
179 
180 //extern       type *declar(type *,char *,int);
181 
182 /* from err.c */
183 void err_message(const(char)* format,...);
184 void dll_printf(const(char)* format,...);
185 void cmderr(uint,...);
186 int synerr(uint,...);
187 void preerr(uint,...);
188 
189 //#if __clang__
190 //void err_exit() __attribute__((analyzer_noreturn));
191 //void err_nomem() __attribute__((analyzer_noreturn));
192 //void err_fatal(uint,...) __attribute__((analyzer_noreturn));
193 //#else
194 void err_exit();
195 public import dmd.backend.ph2 : err_nomem;
196 void err_fatal(uint,...);
197 //#if __DMC__
198 //#pragma ZTC noreturn(err_exit)
199 //#pragma ZTC noreturn(err_nomem)
200 //#pragma ZTC noreturn(err_fatal)
201 //#endif
202 //#endif
203 
204 int cpperr(uint,...);
205 int tx86err(uint,...);
206 extern __gshared int errmsgs_tx86idx;
207 void warerr(uint,...);
208 void err_warning_enable(uint warnum, int on);
209 void lexerr(uint,...);
210 
211 int typerr(int,type *,type *, ...);
212 void err_noctor(Classsym *stag,list_t arglist);
213 void err_nomatch(const(char)*, list_t);
214 void err_ambiguous(Symbol *,Symbol *);
215 void err_noinstance(Symbol *s1,Symbol *s2);
216 void err_redeclar(Symbol *s,type *t1,type *t2);
217 void err_override(Symbol *sfbase,Symbol *sfder);
218 void err_notamember(const(char)* id, Classsym *s, Symbol *alternate = null);
219 
220 /* file.c */
221 char *file_getsource(const(char)* iname);
222 int file_isdir(const(char)* fname);
223 void file_progress();
224 void file_remove(char *fname);
225 int file_exists(const(char)* fname);
226 int file_size(const(char)* fname);
227 void file_term();
228 char *file_unique();
229 
230 /* from msc.c */
231 type *newpointer(type *);
232 type *newpointer_share(type *);
233 type *reftoptr(type *t);
234 type *newref(type *);
235 type *topointer(type *);
236 type *type_ptr(elem *, type *);
237 int type_chksize(uint);
238 tym_t tym_conv(const type *);
239 inout(type)* type_arrayroot(inout type *);
240 void chklvalue(elem *);
241 int tolvalue(elem **);
242 void chkassign(elem *);
243 void chknosu(const elem *);
244 void chkunass(const elem *);
245 void chknoabstract(const type *);
246 targ_llong msc_getnum();
247 targ_size_t alignmember(const type *,targ_size_t,targ_size_t);
248 targ_size_t _align(targ_size_t,targ_size_t);
249 
250 /* nteh.c */
251 ubyte *nteh_context_string();
252 void nteh_declarvars(Blockx *bx);
253 elem *nteh_setScopeTableIndex(Blockx *blx, int scope_index);
254 Symbol *nteh_contextsym();
255 uint nteh_contextsym_size();
256 Symbol *nteh_ecodesym();
257 code *nteh_unwind(regm_t retregs,uint index);
258 code *linux_unwind(regm_t retregs,uint index);
259 int nteh_offset_sindex();
260 int nteh_offset_sindex_seh();
261 int nteh_offset_info();
262 
263 void *globalrealloc(void *oldp,size_t nbytes);
264 void *vmem_baseaddr();
265 void vmem_reservesize(uint *psize);
266 uint vmem_physmem();
267 void *vmem_reserve(void *ptr,uint size);
268 int   vmem_commit(void *ptr, uint size);
269 void vmem_decommit(void *ptr,uint size);
270 void vmem_release(void *ptr,uint size);
271 void *vmem_mapfile(const(char)* filename,void *ptr,uint size,int flag);
272 void vmem_setfilesize(uint size);
273 void vmem_unmapfile();
274 void os_loadlibrary(const(char)* dllname);
275 void os_freelibrary();
276 void *os_getprocaddress(const(char)* funcname);
277 void os_heapinit();
278 void os_heapterm();
279 void os_term();
280 uint os_unique();
281 int os_file_exists(const(char)* name);
282 int os_file_mtime(const(char)* name);
283 long os_file_size(int fd);
284 long os_file_size(const(char)* filename);
285 char *file_8dot3name(const(char)* filename);
286 int file_write(char *name, void *buffer, uint len);
287 int file_createdirs(char *name);
288 
289 /* pseudo.c */
290 Symbol *pseudo_declar(char *);
291 extern __gshared
292 {
293     ubyte[24] pseudoreg;
294     regm_t[24] pseudomask;
295 }
296 
297 /* Symbol.c */
298 //#if TERMCODE
299 //void symbol_keep(Symbol *s);
300 //#else
301 //#define symbol_keep(s) (()(s))
302 //#endif
303 void symbol_keep(Symbol *s) { }
304 void symbol_print(const Symbol* s);
305 void symbol_term();
306 const(char)* symbol_ident(const Symbol *s);
307 extern (C) Symbol *symbol_calloc(const(char)[] id);
308 extern (C) Symbol *symbol_name(const(char)[] name, SC sclass, type *t);
309 Symbol *symbol_generate(SC sclass, type *t);
310 Symbol *symbol_genauto(type *t);
311 Symbol *symbol_genauto(elem *e);
312 Symbol *symbol_genauto(tym_t ty);
313 void symbol_func(Symbol *);
314 //void symbol_struct_addField(Symbol *s, const(char)* name, type *t, uint offset);
315 Funcsym *symbol_funcalias(Funcsym *sf);
316 Symbol *defsy(const(char)* p, Symbol **parent);
317 void symbol_addtotree(Symbol **parent,Symbol *s);
318 //Symbol *lookupsym(const(char)* p);
319 Symbol *findsy(const(char)* p, Symbol *rover);
320 void createglobalsymtab();
321 void createlocalsymtab();
322 void deletesymtab();
323 void meminit_free(meminit_t *m);
324 baseclass_t *baseclass_find(baseclass_t *bm,Classsym *sbase);
325 baseclass_t *baseclass_find_nest(baseclass_t *bm,Classsym *sbase);
326 int baseclass_nitems(baseclass_t *b);
327 void symbol_free(Symbol *s);
328 SYMIDX symbol_add(Symbol *s);
329 SYMIDX symbol_add(ref symtab_t, Symbol *s);
330 SYMIDX symbol_insert(ref symtab_t, Symbol *s, SYMIDX n);
331 void freesymtab(Symbol **stab, SYMIDX n1, SYMIDX n2);
332 Symbol *symbol_copy(Symbol *s);
333 Symbol *symbol_searchlist(symlist_t sl, const(char)* vident);
334 void symbol_reset(Symbol *s);
335 tym_t symbol_pointerType(const Symbol* s);
336 
337 public import dmd.backend.cg87 : loadconst, cg87_reset;
338 
339 /* cod3.c */
340 public import dmd.backend.cod3 : cod3_thunk;
341 
342 /* out.c */
343 void outfilename(char *name,int linnum);
344 void outcsegname(char *csegname);
345 extern (C) void outthunk(Symbol *sthunk, Symbol *sfunc, uint p, tym_t thisty, targ_size_t d, int i, targ_size_t d2);
346 void outdata(Symbol *s);
347 void outcommon(Symbol *s, targ_size_t n);
348 void out_readonly(Symbol *s);
349 void out_readonly_comdat(Symbol *s, const(void)* p, uint len, uint nzeros);
350 void out_regcand(symtab_t *);
351 void writefunc(Symbol *sfunc);
352 @trusted void alignOffset(int seg,targ_size_t datasize);
353 void out_reset();
354 Symbol *out_readonly_sym(tym_t ty, void *p, int len);
355 Symbol *out_string_literal(const(char)* str, uint len, uint sz);
356 
357 public import dmd.backend.blockopt : bc_goal;
358 
359 block* block_calloc();
360 void block_init();
361 void block_term();
362 void block_next(int,block *);
363 void block_next(Blockx *bctx,int bc,block *bn);
364 block *block_goto(Blockx *bctx,BC bc,block *bn);
365 void block_setlabel(uint lbl);
366 void block_goto();
367 void block_goto(block *);
368 void block_goto(block *bgoto, block *bnew);
369 void block_ptr();
370 void block_pred();
371 void block_clearvisit();
372 void block_visit(block *b);
373 void block_compbcount();
374 void blocklist_free(block **pb);
375 void block_optimizer_free(block *b);
376 void block_free(block *b);
377 void blocklist_hydrate(block **pb);
378 void blocklist_dehydrate(block **pb);
379 void block_appendexp(block *b, elem *e);
380 void block_initvar(Symbol *s);
381 void block_endfunc(int flag);
382 void brcombine();
383 void blockopt(int);
384 void compdfo(ref Barray!(block*) dfo, block* startblock);
385 
386 //#define block_initvar(s) (curblock->Binitvar = (s))
387 
388 /* debug.c */
389 extern __gshared const(char)*[32] regstring;
390 
391 @trusted const(char)* class_str(SC c);
392 @trusted const(char)* tym_str(tym_t ty);
393 @trusted const(char)* oper_str(uint oper);
394 @trusted const(char)* bc_str(uint bc);
395 void WRarglst(list_t a);
396 void WRblock(block *b);
397 void WRblocklist(list_t bl);
398 void WReqn(elem *e);
399 void numberBlocks(block* startblock);
400 void WRfunc(const char* msg, Symbol* sfunc, block* startblock);
401 void WRdefnod();
402 void WRFL(FL);
403 char *sym_ident(SYMIDX si);
404 
405 /* cgelem.c     */
406 elem *doptelem(elem *, goal_t);
407 void postoptelem(elem *);
408 int elemisone(elem *);
409 
410 /* msc.c */
411 targ_size_t size(tym_t);
412 @trusted Symbol *symboldata(targ_size_t offset,tym_t ty);
413 bool dom(const block* A, const block* B);
414 uint revop(uint op);
415 uint invrel(uint op);
416 int binary(const(char)* p, const(char)** tab, int high);
417 int binary(const(char)* p, size_t len, const(char)** tab, int high);
418 
419 /* go.c */
420 void go_term();
421 int go_flag(char *cp);
422 void optfunc();
423 
424 /* filename.c */
425 version (SCPP)
426 {
427     extern __gshared Srcfiles srcfiles;
428     Sfile **filename_indirect(Sfile *sf);
429     Sfile  *filename_search(const(char)* name);
430     Sfile *filename_add(const(char)* name);
431     void filename_hydrate(Srcfiles *fn);
432     void filename_dehydrate(Srcfiles *fn);
433     void filename_merge(Srcfiles *fn);
434     void filename_mergefl(Sfile *sf);
435     void filename_translate(Srcpos *);
436     void filename_free();
437     int filename_cmp(const(char)* f1,const(char)* f2);
438     void srcpos_hydrate(Srcpos *);
439     void srcpos_dehydrate(Srcpos *);
440 }
441 version (HTOD)
442 {
443     extern __gshared Srcfiles srcfiles;
444     Sfile **filename_indirect(Sfile *sf);
445     Sfile  *filename_search(const(char)* name);
446     Sfile *filename_add(const(char)* name);
447     void filename_hydrate(Srcfiles *fn);
448     void filename_dehydrate(Srcfiles *fn);
449     void filename_merge(Srcfiles *fn);
450     void filename_mergefl(Sfile *sf);
451     int filename_cmp(const(char)* f1,const(char)* f2);
452     void filename_translate(Srcpos *);
453     void srcpos_hydrate(Srcpos *);
454     void srcpos_dehydrate(Srcpos *);
455 }
456 
457 public import dmd.backend.drtlsym : rtlsym_init, rtlsym_reset, rtlsym_term;
458 
459 // compress.c
460 extern(C) char *id_compress(const char *id, int idlen, size_t *plen);
461 
462 // Dwarf
463 void dwarf_CFA_set_loc(uint location);
464 void dwarf_CFA_set_reg_offset(int reg, int offset);
465 void dwarf_CFA_offset(int reg, int offset);
466 void dwarf_CFA_args_size(size_t sz);