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