1 /** 2 * Declarations for back end 3 * 4 * Compiler implementation of the 5 * $(LINK2 https://www.dlang.org, D programming language). 6 * 7 * Copyright: Copyright (C) 1984-1998 by Symantec 8 * Copyright (C) 2000-2023 by The D Language Foundation, All Rights Reserved 9 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) 10 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 11 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/global.d, backend/global.d) 12 */ 13 module dmd.backend.global; 14 15 // Online documentation: https://dlang.org/phobos/dmd_backend_global.html 16 17 extern (C++): 18 @nogc: 19 nothrow: 20 21 import core.stdc.stdio; 22 import core.stdc.stdint; 23 24 import dmd.backend.cdef; 25 import dmd.backend.cc; 26 import dmd.backend.cc : Symbol, block, Classsym, Blockx; 27 import dmd.backend.code_x86 : code; 28 import dmd.backend.code; 29 import dmd.backend.dlist; 30 import dmd.backend.el; 31 import dmd.backend.el : elem; 32 import dmd.backend.mem; 33 import dmd.backend.symtab; 34 import dmd.backend.type; 35 //import dmd.backend.obj; 36 37 import dmd.backend.barray; 38 39 nothrow: 40 @safe: 41 42 extern __gshared 43 { 44 char debuga; // cg - watch assignaddr() 45 char debugb; // watch block optimization 46 char debugc; // watch code generated 47 char debugd; // watch debug information generated 48 char debuge; // dump eh info 49 char debugf; // trees after dooptim 50 char debugg; // trees for code generator 51 char debugo; // watch optimizer 52 char debugr; // watch register allocation 53 char debugs; // watch common subexp eliminator 54 char debugt; // do test points 55 char debugu; 56 char debugw; // watch progress 57 char debugx; // suppress predefined CPP stuff 58 char debugy; // watch output to il buffer 59 } 60 61 enum CR = '\r'; // Used because the MPW version of the compiler warps 62 enum LF = '\n'; // \n into \r and \r into \n. The translator version 63 // does not and this causes problems with the compilation 64 // with the translator 65 enum CR_STR = "\r"; 66 enum LF_STR = "\n"; 67 68 extern __gshared 69 { 70 const uint[32] mask; // bit masks 71 const uint[32] maskl; // bit masks 72 73 char* argv0; 74 char* finname, foutname, foutdir; 75 76 char OPTIMIZER,PARSER; 77 symtab_t globsym; 78 79 // Config config; // precompiled part of configuration 80 char[SCMAX] sytab; 81 82 extern (C) /*volatile*/ int controlc_saw; // a control C was seen 83 block* startblock; // beginning block of function 84 85 Barray!(block*) dfo; // array of depth first order 86 87 block* curblock; // current block being read in 88 block* block_last; 89 90 int errcnt; 91 regm_t fregsaved; 92 93 tym_t pointertype; // default data pointer type 94 95 // cg.c 96 Symbol* localgot; 97 Symbol* tls_get_addr_sym; 98 } 99 100 version (MARS) 101 __gshared Configv configv; // non-ph part of configuration 102 else 103 extern __gshared Configv configv; // non-ph part of configuration 104 105 // iasm.c 106 Symbol *asm_define_label(const(char)* id); 107 108 // cpp.c 109 const(char)* cpp_mangle(Symbol* s); 110 111 // ee.c 112 void eecontext_convs(SYMIDX marksi); 113 void eecontext_parse(); 114 115 // exp2.c 116 //#define REP_THRESHOLD (REGSIZE * (6+ (REGSIZE == 4))) 117 /* doesn't belong here, but func to OPxxx is in exp2 */ 118 void exp2_setstrthis(elem *e,Symbol *s,targ_size_t offset,type *t); 119 Symbol *exp2_qualified_lookup(Classsym *sclass, int flags, int *pflags); 120 elem *exp2_copytotemp(elem *e); 121 122 void util_progress(); 123 void util_set16(); 124 void util_set32(exefmt_t); 125 void util_set64(exefmt_t); 126 int ispow2(ulong); 127 128 version (Posix) 129 { 130 void* util_malloc(uint n,uint size) { return mem_malloc(n * size); } 131 void* util_calloc(uint n,uint size) { return mem_calloc(n * size); } 132 void util_free(void *p) { mem_free(p); } 133 void *util_realloc(void *oldp,size_t n,size_t size) { return mem_realloc(oldp, n * size); } 134 //#define parc_malloc mem_malloc 135 //#define parc_calloc mem_calloc 136 //#define parc_realloc mem_realloc 137 //#define parc_strdup mem_strdup 138 //#define parc_free mem_free 139 } 140 else 141 { 142 void *util_malloc(uint n,uint size); 143 void *util_calloc(uint n,uint size); 144 void util_free(void *p); 145 void *util_realloc(void *oldp,size_t n,size_t size); 146 void *parc_malloc(size_t len); 147 void *parc_calloc(size_t len); 148 void *parc_realloc(void *oldp,size_t len); 149 char *parc_strdup(const(char)* s); 150 void parc_free(void *p); 151 } 152 153 void swap(int *, int *); 154 //void crlf(FILE *); 155 int isignore(int); 156 int isillegal(int); 157 158 //#if !defined(__DMC__) && !defined(_MSC_VER) 159 int ishex(int); 160 //#endif 161 162 /* from cgcs.c */ 163 void comsubs(); 164 void cgcs_term(); 165 166 /* errmsgs.c */ 167 char *dlcmsgs(int); 168 void errmsgs_term(); 169 170 /* from evalu8.c */ 171 int boolres(elem *); 172 int iftrue(elem *); 173 int iffalse(elem *); 174 elem *poptelem(elem *); 175 elem *poptelem2(elem *); 176 elem *poptelem3(elem *); 177 elem *poptelem4(elem *); 178 elem *selecte1(elem *, type *); 179 180 //extern type *declar(type *,char *,int); 181 182 /* from err.c */ 183 void err_message(const(char)* format,...); 184 void dll_printf(const(char)* format,...); 185 void cmderr(uint,...); 186 int synerr(uint,...); 187 void preerr(uint,...); 188 189 //#if __clang__ 190 //void err_exit() __attribute__((analyzer_noreturn)); 191 //void err_nomem() __attribute__((analyzer_noreturn)); 192 //void err_fatal(uint,...) __attribute__((analyzer_noreturn)); 193 //#else 194 void err_exit(); 195 public import dmd.backend.ph2 : err_nomem; 196 void err_fatal(uint,...); 197 //#if __DMC__ 198 //#pragma ZTC noreturn(err_exit) 199 //#pragma ZTC noreturn(err_nomem) 200 //#pragma ZTC noreturn(err_fatal) 201 //#endif 202 //#endif 203 204 int cpperr(uint,...); 205 int tx86err(uint,...); 206 extern __gshared int errmsgs_tx86idx; 207 void warerr(uint,...); 208 void err_warning_enable(uint warnum, int on); 209 void lexerr(uint,...); 210 211 int typerr(int,type *,type *, ...); 212 void err_noctor(Classsym *stag,list_t arglist); 213 void err_nomatch(const(char)*, list_t); 214 void err_ambiguous(Symbol *,Symbol *); 215 void err_noinstance(Symbol *s1,Symbol *s2); 216 void err_redeclar(Symbol *s,type *t1,type *t2); 217 void err_override(Symbol *sfbase,Symbol *sfder); 218 void err_notamember(const(char)* id, Classsym *s, Symbol *alternate = null); 219 220 /* file.c */ 221 char *file_getsource(const(char)* iname); 222 int file_isdir(const(char)* fname); 223 void file_progress(); 224 void file_remove(char *fname); 225 int file_exists(const(char)* fname); 226 int file_size(const(char)* fname); 227 void file_term(); 228 char *file_unique(); 229 230 /* from msc.c */ 231 type *newpointer(type *); 232 type *newpointer_share(type *); 233 type *reftoptr(type *t); 234 type *newref(type *); 235 type *topointer(type *); 236 type *type_ptr(elem *, type *); 237 int type_chksize(uint); 238 tym_t tym_conv(const type *); 239 inout(type)* type_arrayroot(inout type *); 240 void chklvalue(elem *); 241 int tolvalue(elem **); 242 void chkassign(elem *); 243 void chknosu(const elem *); 244 void chkunass(const elem *); 245 void chknoabstract(const type *); 246 targ_llong msc_getnum(); 247 targ_size_t alignmember(const type *,targ_size_t,targ_size_t); 248 targ_size_t _align(targ_size_t,targ_size_t); 249 250 /* nteh.c */ 251 ubyte *nteh_context_string(); 252 void nteh_declarvars(Blockx *bx); 253 elem *nteh_setScopeTableIndex(Blockx *blx, int scope_index); 254 Symbol *nteh_contextsym(); 255 uint nteh_contextsym_size(); 256 Symbol *nteh_ecodesym(); 257 code *nteh_unwind(regm_t retregs,uint index); 258 code *linux_unwind(regm_t retregs,uint index); 259 int nteh_offset_sindex(); 260 int nteh_offset_sindex_seh(); 261 int nteh_offset_info(); 262 263 void *globalrealloc(void *oldp,size_t nbytes); 264 void *vmem_baseaddr(); 265 void vmem_reservesize(uint *psize); 266 uint vmem_physmem(); 267 void *vmem_reserve(void *ptr,uint size); 268 int vmem_commit(void *ptr, uint size); 269 void vmem_decommit(void *ptr,uint size); 270 void vmem_release(void *ptr,uint size); 271 void *vmem_mapfile(const(char)* filename,void *ptr,uint size,int flag); 272 void vmem_setfilesize(uint size); 273 void vmem_unmapfile(); 274 void os_loadlibrary(const(char)* dllname); 275 void os_freelibrary(); 276 void *os_getprocaddress(const(char)* funcname); 277 void os_heapinit(); 278 void os_heapterm(); 279 void os_term(); 280 uint os_unique(); 281 int os_file_exists(const(char)* name); 282 int os_file_mtime(const(char)* name); 283 long os_file_size(int fd); 284 long os_file_size(const(char)* filename); 285 char *file_8dot3name(const(char)* filename); 286 int file_write(char *name, void *buffer, uint len); 287 int file_createdirs(char *name); 288 289 /* pseudo.c */ 290 Symbol *pseudo_declar(char *); 291 extern __gshared 292 { 293 ubyte[24] pseudoreg; 294 regm_t[24] pseudomask; 295 } 296 297 /* Symbol.c */ 298 //#if TERMCODE 299 //void symbol_keep(Symbol *s); 300 //#else 301 //#define symbol_keep(s) (()(s)) 302 //#endif 303 void symbol_keep(Symbol *s) { } 304 void symbol_print(const Symbol* s); 305 void symbol_term(); 306 const(char)* symbol_ident(const Symbol *s); 307 extern (C) Symbol *symbol_calloc(const(char)[] id); 308 extern (C) Symbol *symbol_name(const(char)[] name, SC sclass, type *t); 309 Symbol *symbol_generate(SC sclass, type *t); 310 Symbol *symbol_genauto(type *t); 311 Symbol *symbol_genauto(elem *e); 312 Symbol *symbol_genauto(tym_t ty); 313 void symbol_func(Symbol *); 314 //void symbol_struct_addField(Symbol *s, const(char)* name, type *t, uint offset); 315 Funcsym *symbol_funcalias(Funcsym *sf); 316 Symbol *defsy(const(char)* p, Symbol **parent); 317 void symbol_addtotree(Symbol **parent,Symbol *s); 318 //Symbol *lookupsym(const(char)* p); 319 Symbol *findsy(const(char)* p, Symbol *rover); 320 void createglobalsymtab(); 321 void createlocalsymtab(); 322 void deletesymtab(); 323 void meminit_free(meminit_t *m); 324 baseclass_t *baseclass_find(baseclass_t *bm,Classsym *sbase); 325 baseclass_t *baseclass_find_nest(baseclass_t *bm,Classsym *sbase); 326 int baseclass_nitems(baseclass_t *b); 327 void symbol_free(Symbol *s); 328 SYMIDX symbol_add(Symbol *s); 329 SYMIDX symbol_add(ref symtab_t, Symbol *s); 330 SYMIDX symbol_insert(ref symtab_t, Symbol *s, SYMIDX n); 331 void freesymtab(Symbol **stab, SYMIDX n1, SYMIDX n2); 332 Symbol *symbol_copy(Symbol *s); 333 Symbol *symbol_searchlist(symlist_t sl, const(char)* vident); 334 void symbol_reset(Symbol *s); 335 tym_t symbol_pointerType(const Symbol* s); 336 337 public import dmd.backend.cg87 : loadconst, cg87_reset; 338 339 /* cod3.c */ 340 public import dmd.backend.cod3 : cod3_thunk; 341 342 /* out.c */ 343 void outfilename(char *name,int linnum); 344 void outcsegname(char *csegname); 345 extern (C) void outthunk(Symbol *sthunk, Symbol *sfunc, uint p, tym_t thisty, targ_size_t d, int i, targ_size_t d2); 346 void outdata(Symbol *s); 347 void outcommon(Symbol *s, targ_size_t n); 348 void out_readonly(Symbol *s); 349 void out_readonly_comdat(Symbol *s, const(void)* p, uint len, uint nzeros); 350 void out_regcand(symtab_t *); 351 void writefunc(Symbol *sfunc); 352 @trusted void alignOffset(int seg,targ_size_t datasize); 353 void out_reset(); 354 Symbol *out_readonly_sym(tym_t ty, void *p, int len); 355 Symbol *out_string_literal(const(char)* str, uint len, uint sz); 356 357 public import dmd.backend.blockopt : bc_goal; 358 359 block* block_calloc(); 360 void block_init(); 361 void block_term(); 362 void block_next(int,block *); 363 void block_next(Blockx *bctx,int bc,block *bn); 364 block *block_goto(Blockx *bctx,BC bc,block *bn); 365 void block_setlabel(uint lbl); 366 void block_goto(); 367 void block_goto(block *); 368 void block_goto(block *bgoto, block *bnew); 369 void block_ptr(); 370 void block_pred(); 371 void block_clearvisit(); 372 void block_visit(block *b); 373 void block_compbcount(); 374 void blocklist_free(block **pb); 375 void block_optimizer_free(block *b); 376 void block_free(block *b); 377 void blocklist_hydrate(block **pb); 378 void blocklist_dehydrate(block **pb); 379 void block_appendexp(block *b, elem *e); 380 void block_initvar(Symbol *s); 381 void block_endfunc(int flag); 382 void brcombine(); 383 void blockopt(int); 384 void compdfo(ref Barray!(block*) dfo, block* startblock); 385 386 //#define block_initvar(s) (curblock->Binitvar = (s)) 387 388 /* debug.c */ 389 extern __gshared const(char)*[32] regstring; 390 391 @trusted const(char)* class_str(SC c); 392 @trusted const(char)* tym_str(tym_t ty); 393 @trusted const(char)* oper_str(uint oper); 394 @trusted const(char)* bc_str(uint bc); 395 void WRarglst(list_t a); 396 void WRblock(block *b); 397 void WRblocklist(list_t bl); 398 void WReqn(elem *e); 399 void numberBlocks(block* startblock); 400 void WRfunc(const char* msg, Symbol* sfunc, block* startblock); 401 void WRdefnod(); 402 void WRFL(FL); 403 char *sym_ident(SYMIDX si); 404 405 /* cgelem.c */ 406 elem *doptelem(elem *, goal_t); 407 void postoptelem(elem *); 408 int elemisone(elem *); 409 410 /* msc.c */ 411 targ_size_t size(tym_t); 412 @trusted Symbol *symboldata(targ_size_t offset,tym_t ty); 413 bool dom(const block* A, const block* B); 414 uint revop(uint op); 415 uint invrel(uint op); 416 int binary(const(char)* p, const(char)** tab, int high); 417 int binary(const(char)* p, size_t len, const(char)** tab, int high); 418 419 /* go.c */ 420 void go_term(); 421 int go_flag(char *cp); 422 void optfunc(); 423 424 /* filename.c */ 425 version (SCPP) 426 { 427 extern __gshared Srcfiles srcfiles; 428 Sfile **filename_indirect(Sfile *sf); 429 Sfile *filename_search(const(char)* name); 430 Sfile *filename_add(const(char)* name); 431 void filename_hydrate(Srcfiles *fn); 432 void filename_dehydrate(Srcfiles *fn); 433 void filename_merge(Srcfiles *fn); 434 void filename_mergefl(Sfile *sf); 435 void filename_translate(Srcpos *); 436 void filename_free(); 437 int filename_cmp(const(char)* f1,const(char)* f2); 438 void srcpos_hydrate(Srcpos *); 439 void srcpos_dehydrate(Srcpos *); 440 } 441 version (HTOD) 442 { 443 extern __gshared Srcfiles srcfiles; 444 Sfile **filename_indirect(Sfile *sf); 445 Sfile *filename_search(const(char)* name); 446 Sfile *filename_add(const(char)* name); 447 void filename_hydrate(Srcfiles *fn); 448 void filename_dehydrate(Srcfiles *fn); 449 void filename_merge(Srcfiles *fn); 450 void filename_mergefl(Sfile *sf); 451 int filename_cmp(const(char)* f1,const(char)* f2); 452 void filename_translate(Srcpos *); 453 void srcpos_hydrate(Srcpos *); 454 void srcpos_dehydrate(Srcpos *); 455 } 456 457 public import dmd.backend.drtlsym : rtlsym_init, rtlsym_reset, rtlsym_term; 458 459 // compress.c 460 extern(C) char *id_compress(const char *id, int idlen, size_t *plen); 461 462 // Dwarf 463 void dwarf_CFA_set_loc(uint location); 464 void dwarf_CFA_set_reg_offset(int reg, int offset); 465 void dwarf_CFA_offset(int reg, int offset); 466 void dwarf_CFA_args_size(size_t sz);