]>
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 | ||
b4c522fa IB |
142 | /* Determine if function FD is a builtin one that we can evaluate in CTFE. */ |
143 | ||
144 | BUILTIN | |
145 | isBuiltin (FuncDeclaration *fd) | |
146 | { | |
147 | if (fd->builtin != BUILTINunknown) | |
148 | return fd->builtin; | |
149 | ||
150 | maybe_set_intrinsic (fd); | |
151 | ||
152 | return fd->builtin; | |
153 | } | |
154 | ||
155 | /* Evaluate builtin D function FD whose argument list is ARGUMENTS. | |
156 | Return result; NULL if cannot evaluate it. */ | |
157 | ||
158 | Expression * | |
159 | eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments) | |
160 | { | |
c1d56e6a | 161 | if (fd->builtin == BUILTINunimp) |
b4c522fa IB |
162 | return NULL; |
163 | ||
164 | tree decl = get_symbol_decl (fd); | |
165 | gcc_assert (fndecl_built_in_p (decl) | |
166 | || DECL_INTRINSIC_CODE (decl) != INTRINSIC_NONE); | |
167 | ||
6c4db916 | 168 | TypeFunction *tf = fd->type->toTypeFunction (); |
b4c522fa IB |
169 | Expression *e = NULL; |
170 | input_location = make_location_t (loc); | |
171 | ||
172 | tree result = d_build_call (tf, decl, NULL, arguments); | |
173 | result = fold (result); | |
174 | ||
175 | /* Builtin should be successfully evaluated. | |
176 | Will only return NULL if we can't convert it. */ | |
177 | if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR) | |
ac78516b | 178 | e = d_eval_constant_expression (loc, result); |
b4c522fa IB |
179 | |
180 | return e; | |
181 | } | |
182 | ||
183 | /* Build and return typeinfo type for TYPE. */ | |
184 | ||
185 | Type * | |
c0aebc60 | 186 | getTypeInfoType (Loc loc, Type *type, Scope *sc) |
b4c522fa | 187 | { |
c0aebc60 IB |
188 | if (!global.params.useTypeInfo) |
189 | { | |
190 | /* Even when compiling without RTTI we should still be able to evaluate | |
191 | TypeInfo at compile-time, just not at run-time. */ | |
192 | if (!sc || !(sc->flags & SCOPEctfe)) | |
193 | { | |
194 | static int warned = 0; | |
195 | ||
196 | if (!warned) | |
197 | { | |
198 | error_at (make_location_t (loc), | |
a9c697b8 | 199 | "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>"); |
c0aebc60 IB |
200 | warned = 1; |
201 | } | |
202 | } | |
203 | } | |
204 | ||
205 | if (Type::dtypeinfo == NULL | |
206 | || (Type::dtypeinfo->storage_class & STCtemp)) | |
207 | { | |
208 | /* If TypeInfo has not been declared, warn about each location once. */ | |
209 | static Loc warnloc; | |
210 | ||
211 | if (!loc.equals (warnloc)) | |
212 | { | |
213 | error_at (make_location_t (loc), | |
214 | "%<object.TypeInfo%> could not be found, " | |
215 | "but is implicitly used"); | |
216 | warnloc = loc; | |
217 | } | |
218 | } | |
219 | ||
b4c522fa IB |
220 | gcc_assert (type->ty != Terror); |
221 | create_typeinfo (type, sc ? sc->_module->importedFrom : NULL); | |
222 | return type->vtinfo->type; | |
223 | } | |
224 | ||
225 | /* Return an inlined copy of a default argument for a function parameter. */ | |
226 | ||
227 | Expression * | |
228 | inlineCopy (Expression *e, Scope *) | |
229 | { | |
230 | return e->copy (); | |
231 | } |