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