]>
Commit | Line | Data |
---|---|---|
b4c522fa | 1 | /* d-frontend.cc -- D frontend interface to the gcc back-end. |
99dee823 | 2 | Copyright (C) 2013-2021 Free Software Foundation, Inc. |
b4c522fa IB |
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/aggregate.h" | |
b4c522fa | 23 | #include "dmd/declaration.h" |
b4c522fa | 24 | #include "dmd/expression.h" |
b4c522fa IB |
25 | #include "dmd/module.h" |
26 | #include "dmd/mtype.h" | |
27 | #include "dmd/scope.h" | |
b4c522fa IB |
28 | |
29 | #include "tree.h" | |
30 | #include "options.h" | |
31 | #include "fold-const.h" | |
32 | #include "diagnostic.h" | |
b4c522fa IB |
33 | |
34 | #include "d-tree.h" | |
35 | ||
36 | ||
37 | /* Implements the Global interface defined by the frontend. | |
38 | Used for managing the state of the current compilation. */ | |
39 | ||
40 | Global global; | |
41 | ||
42 | void | |
43 | Global::_init (void) | |
44 | { | |
45 | this->mars_ext = "d"; | |
46 | this->hdr_ext = "di"; | |
47 | this->doc_ext = "html"; | |
48 | this->ddoc_ext = "ddoc"; | |
49 | this->json_ext = "json"; | |
50 | this->obj_ext = "o"; | |
51 | ||
52 | this->run_noext = true; | |
53 | this->version = "v" | |
54 | #include "verstr.h" | |
55 | ; | |
56 | ||
57 | this->stdmsg = stderr; | |
b4c522fa IB |
58 | } |
59 | ||
60 | /* Start gagging. Return the current number of gagged errors. */ | |
61 | ||
62 | unsigned | |
63 | Global::startGagging (void) | |
64 | { | |
65 | this->gag++; | |
66 | return this->gaggedErrors; | |
67 | } | |
68 | ||
69 | /* End gagging, restoring the old gagged state. Return true if errors | |
70 | occured while gagged. */ | |
71 | ||
72 | bool | |
73 | Global::endGagging (unsigned oldGagged) | |
74 | { | |
75 | bool anyErrs = (this->gaggedErrors != oldGagged); | |
76 | this->gag--; | |
77 | ||
78 | /* Restore the original state of gagged errors; set total errors | |
79 | to be original errors + new ungagged errors. */ | |
80 | this->errors -= (this->gaggedErrors - oldGagged); | |
81 | this->gaggedErrors = oldGagged; | |
82 | ||
83 | return anyErrs; | |
84 | } | |
85 | ||
86 | /* Increment the error count to record that an error has occured in the | |
87 | current context. An error message may or may not have been printed. */ | |
88 | ||
89 | void | |
90 | Global::increaseErrorCount (void) | |
91 | { | |
92 | if (gag) | |
93 | this->gaggedErrors++; | |
94 | ||
95 | this->errors++; | |
96 | } | |
97 | ||
98 | ||
99 | /* Implements the Loc interface defined by the frontend. | |
100 | Used for keeping track of current file/line position in code. */ | |
101 | ||
102 | Loc::Loc (const char *filename, unsigned linnum, unsigned charnum) | |
103 | { | |
104 | this->linnum = linnum; | |
105 | this->charnum = charnum; | |
106 | this->filename = filename; | |
107 | } | |
108 | ||
109 | const char * | |
110 | Loc::toChars (void) const | |
111 | { | |
112 | OutBuffer buf; | |
113 | ||
114 | if (this->filename) | |
115 | buf.printf ("%s", this->filename); | |
116 | ||
117 | if (this->linnum) | |
118 | { | |
119 | buf.printf (":%u", this->linnum); | |
120 | if (this->charnum) | |
121 | buf.printf (":%u", this->charnum); | |
122 | } | |
123 | ||
fced594b | 124 | return buf.extractChars (); |
b4c522fa IB |
125 | } |
126 | ||
127 | bool | |
af3c19f0 | 128 | Loc::equals (const Loc &loc) |
b4c522fa IB |
129 | { |
130 | if (this->linnum != loc.linnum || this->charnum != loc.charnum) | |
131 | return false; | |
132 | ||
133 | if (!FileName::equals (this->filename, loc.filename)) | |
134 | return false; | |
135 | ||
136 | return true; | |
137 | } | |
138 | ||
139 | ||
b4c522fa IB |
140 | /* Implements back-end specific interfaces used by the frontend. */ |
141 | ||
142 | /* Determine return style of function - whether in registers or through a | |
143 | hidden pointer to the caller's stack. */ | |
144 | ||
145 | RET | |
87e36d9b | 146 | retStyle (TypeFunction *tf) |
b4c522fa IB |
147 | { |
148 | /* Need the backend type to determine this, but this is called from the | |
149 | frontend before semantic processing is finished. An accurate value | |
150 | is not currently needed anyway. */ | |
87e36d9b IB |
151 | if (tf->isref) |
152 | return RETregs; | |
153 | ||
154 | Type *tn = tf->next->toBasetype (); | |
155 | ||
156 | if (tn->ty == Tstruct || tn->ty == Tsarray) | |
157 | return RETstack; | |
158 | ||
159 | return RETregs; | |
b4c522fa IB |
160 | } |
161 | ||
162 | /* Determine if function FD is a builtin one that we can evaluate in CTFE. */ | |
163 | ||
164 | BUILTIN | |
165 | isBuiltin (FuncDeclaration *fd) | |
166 | { | |
167 | if (fd->builtin != BUILTINunknown) | |
168 | return fd->builtin; | |
169 | ||
170 | maybe_set_intrinsic (fd); | |
171 | ||
172 | return fd->builtin; | |
173 | } | |
174 | ||
175 | /* Evaluate builtin D function FD whose argument list is ARGUMENTS. | |
176 | Return result; NULL if cannot evaluate it. */ | |
177 | ||
178 | Expression * | |
179 | eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments) | |
180 | { | |
181 | if (fd->builtin != BUILTINyes) | |
182 | return NULL; | |
183 | ||
184 | tree decl = get_symbol_decl (fd); | |
185 | gcc_assert (fndecl_built_in_p (decl) | |
186 | || DECL_INTRINSIC_CODE (decl) != INTRINSIC_NONE); | |
187 | ||
6c4db916 | 188 | TypeFunction *tf = fd->type->toTypeFunction (); |
b4c522fa IB |
189 | Expression *e = NULL; |
190 | input_location = make_location_t (loc); | |
191 | ||
192 | tree result = d_build_call (tf, decl, NULL, arguments); | |
193 | result = fold (result); | |
194 | ||
195 | /* Builtin should be successfully evaluated. | |
196 | Will only return NULL if we can't convert it. */ | |
197 | if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR) | |
ac78516b | 198 | e = d_eval_constant_expression (loc, result); |
b4c522fa IB |
199 | |
200 | return e; | |
201 | } | |
202 | ||
203 | /* Build and return typeinfo type for TYPE. */ | |
204 | ||
205 | Type * | |
c0aebc60 | 206 | getTypeInfoType (Loc loc, Type *type, Scope *sc) |
b4c522fa | 207 | { |
c0aebc60 IB |
208 | if (!global.params.useTypeInfo) |
209 | { | |
210 | /* Even when compiling without RTTI we should still be able to evaluate | |
211 | TypeInfo at compile-time, just not at run-time. */ | |
212 | if (!sc || !(sc->flags & SCOPEctfe)) | |
213 | { | |
214 | static int warned = 0; | |
215 | ||
216 | if (!warned) | |
217 | { | |
218 | error_at (make_location_t (loc), | |
a9c697b8 | 219 | "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>"); |
c0aebc60 IB |
220 | warned = 1; |
221 | } | |
222 | } | |
223 | } | |
224 | ||
225 | if (Type::dtypeinfo == NULL | |
226 | || (Type::dtypeinfo->storage_class & STCtemp)) | |
227 | { | |
228 | /* If TypeInfo has not been declared, warn about each location once. */ | |
229 | static Loc warnloc; | |
230 | ||
231 | if (!loc.equals (warnloc)) | |
232 | { | |
233 | error_at (make_location_t (loc), | |
234 | "%<object.TypeInfo%> could not be found, " | |
235 | "but is implicitly used"); | |
236 | warnloc = loc; | |
237 | } | |
238 | } | |
239 | ||
b4c522fa IB |
240 | gcc_assert (type->ty != Terror); |
241 | create_typeinfo (type, sc ? sc->_module->importedFrom : NULL); | |
242 | return type->vtinfo->type; | |
243 | } | |
244 | ||
245 | /* Return an inlined copy of a default argument for a function parameter. */ | |
246 | ||
247 | Expression * | |
248 | inlineCopy (Expression *e, Scope *) | |
249 | { | |
250 | return e->copy (); | |
251 | } |