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