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