]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/d-compiler.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / d / d-compiler.cc
1 /* d-compiler.cc -- D frontend interface to the gcc back-end.
2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>. */
17
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
21
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"
28
29 #include "tree.h"
30 #include "fold-const.h"
31
32 #include "d-tree.h"
33
34
35 /* Implements the Compiler interface used by the frontend. */
36
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. */
41
42 void
43 Compiler::genCmain (Scope *sc)
44 {
45 static bool initialized = false;
46
47 if (initialized)
48 return;
49
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"));
54
55 if (global.endGagging (errors))
56 m = NULL;
57
58 if (m != NULL)
59 {
60 m->importedFrom = m;
61 m->importAll (NULL);
62 m->semantic (NULL);
63 m->semantic2 (NULL);
64 m->semantic3 (NULL);
65 d_add_entrypoint_module (m, sc->_module);
66 }
67
68 initialized = true;
69 }
70
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. */
74
75 Expression *
76 Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
77 {
78 /* We support up to 512-bit values. */
79 unsigned char buffer[64];
80 tree cst;
81
82 Type *tb = type->toBasetype ();
83
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)
89 {
90 /* Build array as VECTOR_CST, assumes EXPR is constant. */
91 Expressions *elements = expr->isArrayLiteralExp ()->elements;
92 vec <constructor_elt, va_gc> *elms = NULL;
93
94 vec_safe_reserve (elms, elements->length);
95 for (size_t i = 0; i < elements->length; i++)
96 {
97 Expression *e = (*elements)[i];
98 if (e->type->isintegral ())
99 {
100 tree value = build_integer_cst (e->toInteger (),
101 build_ctype (e->type));
102 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
103 }
104 else if (e->type->isfloating ())
105 {
106 tree value = build_float_cst (e->toReal (), e->type);
107 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
108 }
109 else
110 gcc_unreachable ();
111 }
112
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);
117
118 cst = build_vector_from_ctor (vectype, elms);
119 }
120 else
121 gcc_unreachable ();
122
123 /* Encode CST to buffer. */
124 int len = native_encode_expr (cst, buffer, sizeof (buffer));
125
126 if (tb->ty == Tsarray)
127 {
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);
133
134 cst = native_interpret_expr (vectype, buffer, len);
135
136 Expression *e = d_eval_constant_expression (expr->loc, cst);
137 gcc_assert (e != NULL && e->op == TOKvector);
138
139 return e->isVectorExp ()->e1;
140 }
141 else
142 {
143 /* Normal interpret cast. */
144 cst = native_interpret_expr (build_ctype (type), buffer, len);
145
146 Expression *e = d_eval_constant_expression (expr->loc, cst);
147 gcc_assert (e != NULL);
148
149 return e;
150 }
151 }
152
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. */
158
159 void
160 Compiler::loadModule (Module *m)
161 {
162 ModuleDeclaration *md = m->md;
163
164 if (!md || !md->id || !md->packages)
165 {
166 Identifier *id = (md && md->id) ? md->id : m->ident;
167 if (!strcmp (id->toChars (), "object"))
168 create_tinfo_types (m);
169 }
170 else if (md->packages->length == 1)
171 {
172 if (!strcmp ((*md->packages)[0]->toChars (), "gcc")
173 && !strcmp (md->id->toChars (), "builtins"))
174 d_build_builtins_module (m);
175 }
176 else if (md->packages->length == 2)
177 {
178 if (!strcmp ((*md->packages)[0]->toChars (), "core")
179 && !strcmp ((*md->packages)[1]->toChars (), "stdc"))
180 d_add_builtin_module (m);
181 }
182 }