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