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