PR rtl-optimization/88470
[official-gcc.git] / gcc / d / d-frontend.cc
blob3cba25b1c5dcf42d8808e70452598641ffab8e5d
1 /* d-frontend.cc -- D frontend interface to the gcc back-end.
2 Copyright (C) 2013-2018 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
23 #include "dmd/compiler.h"
24 #include "dmd/declaration.h"
25 #include "dmd/errors.h"
26 #include "dmd/expression.h"
27 #include "dmd/identifier.h"
28 #include "dmd/module.h"
29 #include "dmd/mtype.h"
30 #include "dmd/scope.h"
31 #include "dmd/statement.h"
32 #include "dmd/target.h"
34 #include "tree.h"
35 #include "options.h"
36 #include "fold-const.h"
37 #include "diagnostic.h"
38 #include "stor-layout.h"
40 #include "d-tree.h"
43 /* Implements the Global interface defined by the frontend.
44 Used for managing the state of the current compilation. */
46 Global global;
48 void
49 Global::_init (void)
51 this->mars_ext = "d";
52 this->hdr_ext = "di";
53 this->doc_ext = "html";
54 this->ddoc_ext = "ddoc";
55 this->json_ext = "json";
56 this->obj_ext = "o";
58 this->run_noext = true;
59 this->version = "v"
60 #include "verstr.h"
63 this->stdmsg = stderr;
64 this->errorLimit = flag_max_errors;
67 /* Start gagging. Return the current number of gagged errors. */
69 unsigned
70 Global::startGagging (void)
72 this->gag++;
73 return this->gaggedErrors;
76 /* End gagging, restoring the old gagged state. Return true if errors
77 occured while gagged. */
79 bool
80 Global::endGagging (unsigned oldGagged)
82 bool anyErrs = (this->gaggedErrors != oldGagged);
83 this->gag--;
85 /* Restore the original state of gagged errors; set total errors
86 to be original errors + new ungagged errors. */
87 this->errors -= (this->gaggedErrors - oldGagged);
88 this->gaggedErrors = oldGagged;
90 return anyErrs;
93 /* Increment the error count to record that an error has occured in the
94 current context. An error message may or may not have been printed. */
96 void
97 Global::increaseErrorCount (void)
99 if (gag)
100 this->gaggedErrors++;
102 this->errors++;
106 /* Implements the Loc interface defined by the frontend.
107 Used for keeping track of current file/line position in code. */
109 Loc::Loc (const char *filename, unsigned linnum, unsigned charnum)
111 this->linnum = linnum;
112 this->charnum = charnum;
113 this->filename = filename;
116 const char *
117 Loc::toChars (void) const
119 OutBuffer buf;
121 if (this->filename)
122 buf.printf ("%s", this->filename);
124 if (this->linnum)
126 buf.printf (":%u", this->linnum);
127 if (this->charnum)
128 buf.printf (":%u", this->charnum);
131 return buf.extractString ();
134 bool
135 Loc::equals (const Loc& loc)
137 if (this->linnum != loc.linnum || this->charnum != loc.charnum)
138 return false;
140 if (!FileName::equals (this->filename, loc.filename))
141 return false;
143 return true;
147 /* Implements the Port interface defined by the frontend.
148 A mini library for doing compiler/system specific things. */
150 /* Compare the first N bytes of S1 and S2 without regard to the case. */
153 Port::memicmp (const char *s1, const char *s2, size_t n)
155 int result = 0;
157 for (size_t i = 0; i < n; i++)
159 char c1 = s1[i];
160 char c2 = s2[i];
162 result = c1 - c2;
163 if (result)
165 result = TOUPPER (c1) - TOUPPER (c2);
166 if (result)
167 break;
171 return result;
174 /* Convert all characters in S to uppercase. */
176 char *
177 Port::strupr (char *s)
179 char *t = s;
181 while (*s)
183 *s = TOUPPER (*s);
184 s++;
187 return t;
190 /* Return true if the real_t value from string BUFFER overflows
191 as a result of rounding down to float mode. */
193 bool
194 Port::isFloat32LiteralOutOfRange (const char *buffer)
196 real_t r;
198 real_from_string3 (&r.rv (), buffer, TYPE_MODE (float_type_node));
200 return r == Target::RealProperties::infinity;
203 /* Return true if the real_t value from string BUFFER overflows
204 as a result of rounding down to double mode. */
206 bool
207 Port::isFloat64LiteralOutOfRange (const char *buffer)
209 real_t r;
211 real_from_string3 (&r.rv (), buffer, TYPE_MODE (double_type_node));
213 return r == Target::RealProperties::infinity;
216 /* Fetch a little-endian 16-bit value from BUFFER. */
218 unsigned
219 Port::readwordLE (void *buffer)
221 unsigned char *p = (unsigned char*) buffer;
223 return ((unsigned) p[1] << 8) | (unsigned) p[0];
226 /* Fetch a big-endian 16-bit value from BUFFER. */
228 unsigned
229 Port::readwordBE (void *buffer)
231 unsigned char *p = (unsigned char*) buffer;
233 return ((unsigned) p[0] << 8) | (unsigned) p[1];
236 /* Fetch a little-endian 32-bit value from BUFFER. */
238 unsigned
239 Port::readlongLE (void *buffer)
241 unsigned char *p = (unsigned char*) buffer;
243 return (((unsigned) p[3] << 24)
244 | ((unsigned) p[2] << 16)
245 | ((unsigned) p[1] << 8)
246 | (unsigned) p[0]);
249 /* Fetch a big-endian 32-bit value from BUFFER. */
251 unsigned
252 Port::readlongBE (void *buffer)
254 unsigned char *p = (unsigned char*) buffer;
256 return (((unsigned) p[0] << 24)
257 | ((unsigned) p[1] << 16)
258 | ((unsigned) p[2] << 8)
259 | (unsigned) p[3]);
262 /* Write an SZ-byte sized VALUE to BUFFER, ignoring endian-ness. */
264 void
265 Port::valcpy (void *buffer, uint64_t value, size_t sz)
267 switch (sz)
269 case 1:
270 *(uint8_t *) buffer = (uint8_t) value;
271 break;
273 case 2:
274 *(uint16_t *) buffer = (uint16_t) value;
275 break;
277 case 4:
278 *(uint32_t *) buffer = (uint32_t) value;
279 break;
281 case 8:
282 *(uint64_t *) buffer = (uint64_t) value;
283 break;
285 default:
286 gcc_unreachable ();
291 /* Implements the CTFloat interface defined by the frontend.
292 Compile-time floating-pointer helper functions. */
294 /* Return the absolute value of R. */
296 real_t
297 CTFloat::fabs (real_t r)
299 real_t x;
300 real_arithmetic (&x.rv (), ABS_EXPR, &r.rv (), NULL);
301 return x.normalize ();
304 /* Return the value of R * 2 ^^ EXP. */
306 real_t
307 CTFloat::ldexp (real_t r, int exp)
309 real_t x;
310 real_ldexp (&x.rv (), &r.rv (), exp);
311 return x.normalize ();
314 /* Return true if longdouble value X is identical to Y. */
316 bool
317 CTFloat::isIdentical (real_t x, real_t y)
319 real_value rx = x.rv ();
320 real_value ry = y.rv ();
321 return (REAL_VALUE_ISNAN (rx) && REAL_VALUE_ISNAN (ry))
322 || real_identical (&rx, &ry);
325 /* Return true if real_t value R is NaN. */
327 bool
328 CTFloat::isNaN (real_t r)
330 return REAL_VALUE_ISNAN (r.rv ());
333 /* Same as isNaN, but also check if is signalling. */
335 bool
336 CTFloat::isSNaN (real_t r)
338 return REAL_VALUE_ISSIGNALING_NAN (r.rv ());
341 /* Return true if real_t value is +Inf. */
343 bool
344 CTFloat::isInfinity (real_t r)
346 return REAL_VALUE_ISINF (r.rv ());
349 /* Return a real_t value from string BUFFER rounded to long double mode. */
351 real_t
352 CTFloat::parse (const char *buffer, bool *overflow)
354 real_t r;
355 real_from_string3 (&r.rv (), buffer, TYPE_MODE (long_double_type_node));
357 /* Front-end checks overflow to see if the value is representable. */
358 if (overflow && r == Target::RealProperties::infinity)
359 *overflow = true;
361 return r;
364 /* Format the real_t value R to string BUFFER as a decimal or hexadecimal,
365 converting the result to uppercase if FMT requests it. */
368 CTFloat::sprint (char *buffer, char fmt, real_t r)
370 if (fmt == 'a' || fmt == 'A')
372 /* Converting to a hexadecimal string. */
373 real_to_hexadecimal (buffer, &r.rv (), 32, 0, 1);
374 int buflen;
376 switch (fmt)
378 case 'A':
379 buflen = strlen (buffer);
380 for (int i = 0; i < buflen; i++)
381 buffer[i] = TOUPPER (buffer[i]);
383 return buflen;
385 case 'a':
386 return strlen (buffer);
388 default:
389 gcc_unreachable ();
392 else
394 /* Note: restricting the precision of significant digits to 18. */
395 real_to_decimal (buffer, &r.rv (), 32, 18, 1);
396 return strlen (buffer);
400 /* Return a hash value for real_t value R. */
402 size_t
403 CTFloat::hash (real_t r)
405 return real_hash (&r.rv ());
408 /* Implements the Compiler interface used by the frontend. */
410 /* Generate C main() in response to seeing D main(). This used to be in
411 libdruntime, but contained a reference to _Dmain which didn't work when
412 druntime was made into a shared library and was linked to a program, such
413 as a C++ program, that didn't have a _Dmain. */
415 void
416 Compiler::genCmain (Scope *sc)
418 static bool initialized = false;
420 if (initialized)
421 return;
423 /* The D code to be generated is provided by __entrypoint.di, try to load it,
424 but don't fail if unfound. */
425 unsigned errors = global.startGagging ();
426 Module *m = Module::load (Loc (), NULL, Identifier::idPool ("__entrypoint"));
428 if (global.endGagging (errors))
429 m = NULL;
431 if (m != NULL)
433 m->importedFrom = m;
434 m->importAll (NULL);
435 m->semantic (NULL);
436 m->semantic2 (NULL);
437 m->semantic3 (NULL);
438 d_add_entrypoint_module (m, sc->_module);
441 initialized = true;
444 /* Perform a reinterpret cast of EXPR to type TYPE for use in CTFE.
445 The front end should have already ensured that EXPR is a constant,
446 so we just lower the value to GCC and return the converted CST. */
448 Expression *
449 Compiler::paintAsType (Expression *expr, Type *type)
451 /* We support up to 512-bit values. */
452 unsigned char buffer[64];
453 tree cst;
455 Type *tb = type->toBasetype ();
457 if (expr->type->isintegral ())
458 cst = build_integer_cst (expr->toInteger (), build_ctype (expr->type));
459 else if (expr->type->isfloating ())
460 cst = build_float_cst (expr->toReal (), expr->type);
461 else if (expr->op == TOKarrayliteral)
463 /* Build array as VECTOR_CST, assumes EXPR is constant. */
464 Expressions *elements = ((ArrayLiteralExp *) expr)->elements;
465 vec<constructor_elt, va_gc> *elms = NULL;
467 vec_safe_reserve (elms, elements->dim);
468 for (size_t i = 0; i < elements->dim; i++)
470 Expression *e = (*elements)[i];
471 if (e->type->isintegral ())
473 tree value = build_integer_cst (e->toInteger (),
474 build_ctype (e->type));
475 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
477 else if (e->type->isfloating ())
479 tree value = build_float_cst (e->toReal (), e->type);
480 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
482 else
483 gcc_unreachable ();
486 /* Build vector type. */
487 int nunits = ((TypeSArray *) expr->type)->dim->toUInteger ();
488 Type *telem = expr->type->nextOf ();
489 tree vectype = build_vector_type (build_ctype (telem), nunits);
491 cst = build_vector_from_ctor (vectype, elms);
493 else
494 gcc_unreachable ();
496 /* Encode CST to buffer. */
497 int len = native_encode_expr (cst, buffer, sizeof (buffer));
499 if (tb->ty == Tsarray)
501 /* Interpret value as a vector of the same size,
502 then return the array literal. */
503 int nunits = ((TypeSArray *) type)->dim->toUInteger ();
504 Type *elem = type->nextOf ();
505 tree vectype = build_vector_type (build_ctype (elem), nunits);
507 cst = native_interpret_expr (vectype, buffer, len);
509 Expression *e = d_eval_constant_expression (cst);
510 gcc_assert (e != NULL && e->op == TOKvector);
512 return ((VectorExp *) e)->e1;
514 else
516 /* Normal interpret cast. */
517 cst = native_interpret_expr (build_ctype (type), buffer, len);
519 Expression *e = d_eval_constant_expression (cst);
520 gcc_assert (e != NULL);
522 return e;
526 /* Check imported module M for any special processing.
527 Modules we look out for are:
528 - object: For D runtime type information.
529 - gcc.builtins: For all gcc builtins.
530 - core.stdc.*: For all gcc library builtins. */
532 void
533 Compiler::loadModule (Module *m)
535 ModuleDeclaration *md = m->md;
537 if (!md || !md->id || !md->packages)
539 Identifier *id = (md && md->id) ? md->id : m->ident;
540 if (!strcmp (id->toChars (), "object"))
541 create_tinfo_types (m);
543 else if (md->packages->dim == 1)
545 if (!strcmp ((*md->packages)[0]->toChars (), "gcc")
546 && !strcmp (md->id->toChars (), "builtins"))
547 d_build_builtins_module (m);
549 else if (md->packages->dim == 2)
551 if (!strcmp ((*md->packages)[0]->toChars (), "core")
552 && !strcmp ((*md->packages)[1]->toChars (), "stdc"))
553 d_add_builtin_module (m);
557 /* Implements back-end specific interfaces used by the frontend. */
559 /* Determine return style of function - whether in registers or through a
560 hidden pointer to the caller's stack. */
563 retStyle (TypeFunction *)
565 /* Need the backend type to determine this, but this is called from the
566 frontend before semantic processing is finished. An accurate value
567 is not currently needed anyway. */
568 return RETstack;
571 /* Determine if function FD is a builtin one that we can evaluate in CTFE. */
573 BUILTIN
574 isBuiltin (FuncDeclaration *fd)
576 if (fd->builtin != BUILTINunknown)
577 return fd->builtin;
579 maybe_set_intrinsic (fd);
581 return fd->builtin;
584 /* Evaluate builtin D function FD whose argument list is ARGUMENTS.
585 Return result; NULL if cannot evaluate it. */
587 Expression *
588 eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)
590 if (fd->builtin != BUILTINyes)
591 return NULL;
593 tree decl = get_symbol_decl (fd);
594 gcc_assert (fndecl_built_in_p (decl)
595 || DECL_INTRINSIC_CODE (decl) != INTRINSIC_NONE);
597 TypeFunction *tf = (TypeFunction *) fd->type;
598 Expression *e = NULL;
599 input_location = make_location_t (loc);
601 tree result = d_build_call (tf, decl, NULL, arguments);
602 result = fold (result);
604 /* Builtin should be successfully evaluated.
605 Will only return NULL if we can't convert it. */
606 if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR)
607 e = d_eval_constant_expression (result);
609 return e;
612 /* Build and return typeinfo type for TYPE. */
614 Type *
615 getTypeInfoType (Type *type, Scope *sc)
617 gcc_assert (type->ty != Terror);
618 create_typeinfo (type, sc ? sc->_module->importedFrom : NULL);
619 return type->vtinfo->type;
622 /* Return an inlined copy of a default argument for a function parameter. */
624 Expression *
625 inlineCopy (Expression *e, Scope *)
627 return e->copy ();