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