1 /* d-compiler.cc -- D frontend interface to the gcc back-end.
2 Copyright (C) 2020-2021 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)
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/>. */
20 #include "coretypes.h"
22 #include "dmd/compiler.h"
23 #include "dmd/scope.h"
24 #include "dmd/expression.h"
25 #include "dmd/identifier.h"
26 #include "dmd/module.h"
27 #include "dmd/mtype.h"
30 #include "fold-const.h"
35 /* Implements the Compiler interface used by the frontend. */
37 /* Generate C main() in response to seeing D main(). This used to be in
38 libdruntime, but contained a reference to _Dmain which didn't work when
39 druntime was made into a shared library and was linked to a program, such
40 as a C++ program, that didn't have a _Dmain. */
43 Compiler::genCmain (Scope
*sc
)
45 static bool initialized
= false;
50 /* The D code to be generated is provided by __entrypoint.di, try to load it,
51 but don't fail if unfound. */
52 unsigned errors
= global
.startGagging ();
53 Module
*m
= Module::load (Loc (), NULL
, Identifier::idPool ("__entrypoint"));
55 if (global
.endGagging (errors
))
62 dsymbolSemantic (m
, NULL
);
65 d_add_entrypoint_module (m
, sc
->_module
);
71 /* Perform a reinterpret cast of EXPR to type TYPE for use in CTFE.
72 The front end should have already ensured that EXPR is a constant,
73 so we just lower the value to GCC and return the converted CST. */
76 Compiler::paintAsType (UnionExp
*, Expression
*expr
, Type
*type
)
78 /* We support up to 512-bit values. */
79 unsigned char buffer
[64];
82 Type
*tb
= type
->toBasetype ();
84 if (expr
->type
->isintegral ())
85 cst
= build_integer_cst (expr
->toInteger (), build_ctype (expr
->type
));
86 else if (expr
->type
->isfloating ())
87 cst
= build_float_cst (expr
->toReal (), expr
->type
);
88 else if (expr
->op
== TOKarrayliteral
)
90 /* Build array as VECTOR_CST, assumes EXPR is constant. */
91 Expressions
*elements
= expr
->isArrayLiteralExp ()->elements
;
92 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
94 vec_safe_reserve (elms
, elements
->length
);
95 for (size_t i
= 0; i
< elements
->length
; i
++)
97 Expression
*e
= (*elements
)[i
];
98 if (e
->type
->isintegral ())
100 tree value
= build_integer_cst (e
->toInteger (),
101 build_ctype (e
->type
));
102 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
104 else if (e
->type
->isfloating ())
106 tree value
= build_float_cst (e
->toReal (), e
->type
);
107 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
113 /* Build vector type. */
114 int nunits
= expr
->type
->isTypeSArray ()->dim
->toUInteger ();
115 Type
*telem
= expr
->type
->nextOf ();
116 tree vectype
= build_vector_type (build_ctype (telem
), nunits
);
118 cst
= build_vector_from_ctor (vectype
, elms
);
123 /* Encode CST to buffer. */
124 int len
= native_encode_expr (cst
, buffer
, sizeof (buffer
));
126 if (tb
->ty
== Tsarray
)
128 /* Interpret value as a vector of the same size,
129 then return the array literal. */
130 int nunits
= type
->isTypeSArray ()->dim
->toUInteger ();
131 Type
*elem
= type
->nextOf ();
132 tree vectype
= build_vector_type (build_ctype (elem
), nunits
);
134 cst
= native_interpret_expr (vectype
, buffer
, len
);
136 Expression
*e
= d_eval_constant_expression (expr
->loc
, cst
);
137 gcc_assert (e
!= NULL
&& e
->op
== TOKvector
);
139 return e
->isVectorExp ()->e1
;
143 /* Normal interpret cast. */
144 cst
= native_interpret_expr (build_ctype (type
), buffer
, len
);
146 Expression
*e
= d_eval_constant_expression (expr
->loc
, cst
);
147 gcc_assert (e
!= NULL
);
153 /* Check imported module M for any special processing.
154 Modules we look out for are:
155 - object: For D runtime type information.
156 - gcc.builtins: For all gcc builtins.
157 - core.stdc.*: For all gcc library builtins. */
160 Compiler::onParseModule (Module
*m
)
162 ModuleDeclaration
*md
= m
->md
;
164 if (!md
|| !md
->id
|| !md
->packages
)
166 Identifier
*id
= (md
&& md
->id
) ? md
->id
: m
->ident
;
167 if (!strcmp (id
->toChars (), "object"))
168 create_tinfo_types (m
);
170 else if (md
->packages
->length
== 1)
172 if (!strcmp ((*md
->packages
)[0]->toChars (), "gcc")
173 && !strcmp (md
->id
->toChars (), "builtins"))
174 d_build_builtins_module (m
);
176 else if (md
->packages
->length
== 2)
178 if (!strcmp ((*md
->packages
)[0]->toChars (), "core")
179 && !strcmp ((*md
->packages
)[1]->toChars (), "stdc"))
180 d_add_builtin_module (m
);
184 /* A callback function that is called once an imported module is parsed.
185 If the callback returns true, then it tells the front-end that the
186 driver intends on compiling the import. */
189 Compiler::onImport (Module
*)