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);