imports.cc revision 1.1.1.3 1 /* imports.cc -- Build imported modules/declarations.
2 Copyright (C) 2014-2020 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/aggregate.h"
23 #include "dmd/declaration.h"
24 #include "dmd/enum.h"
25 #include "dmd/identifier.h"
26 #include "dmd/import.h"
27 #include "dmd/module.h"
28
29 #include "tree.h"
30 #include "stringpool.h"
31
32 #include "d-tree.h"
33
34
35 /* Implements the visitor interface to build debug trees for all
36 module and import declarations, where ISYM holds the cached
37 back-end representation to be returned. */
38 class ImportVisitor : public Visitor
39 {
40 using Visitor::visit;
41
42 /* Build the declaration DECL as an imported symbol. */
43 tree make_import (tree decl)
44 {
45 gcc_assert (decl != NULL_TREE);
46
47 tree import = build_decl (input_location, IMPORTED_DECL,
48 DECL_NAME (decl), void_type_node);
49 IMPORTED_DECL_ASSOCIATED_DECL (import) = decl;
50 d_keep (import);
51
52 return import;
53 }
54
55 public:
56 ImportVisitor (void)
57 {
58 }
59
60 /* This should be overridden by each symbol class. */
61 void visit (Dsymbol *)
62 {
63 gcc_unreachable ();
64 }
65
66 /* Build the module decl for M, this is considered toplevel, regardless
67 of whether there are any parent packages in the module system. */
68 void visit (Module *m)
69 {
70 Loc loc = (m->md != NULL) ? m->md->loc
71 : Loc (m->srcfile->toChars (), 1, 0);
72
73 m->isym = build_decl (make_location_t (loc), NAMESPACE_DECL,
74 get_identifier (m->toPrettyChars ()),
75 void_type_node);
76 d_keep (m->isym);
77
78 if (!m->isRoot ())
79 DECL_EXTERNAL (m->isym) = 1;
80
81 TREE_PUBLIC (m->isym) = 1;
82 DECL_CONTEXT (m->isym) = NULL_TREE;
83 }
84
85 /* Build an import of another module symbol. */
86
87 void visit (Import *m)
88 {
89 tree module = build_import_decl (m->mod);
90 m->isym = this->make_import (module);
91 }
92
93 /* Build an import for any kind of user defined type.
94 Use the TYPE_DECL associated with the type symbol. */
95 void visit (EnumDeclaration *d)
96 {
97 tree type = build_ctype (d->type);
98 /* Not all kinds of D enums create a TYPE_DECL. */
99 if (TREE_CODE (type) == ENUMERAL_TYPE)
100 {
101 type = TYPE_MAIN_VARIANT (type);
102 d->isym = this->make_import (TYPE_STUB_DECL (type));
103 }
104
105 }
106
107 void visit (AggregateDeclaration *d)
108 {
109 tree type = build_ctype (d->type);
110 type = TYPE_MAIN_VARIANT (type);
111 d->isym = this->make_import (TYPE_STUB_DECL (type));
112 }
113
114 void visit (ClassDeclaration *d)
115 {
116 /* Want the RECORD_TYPE, not POINTER_TYPE. */
117 tree type = TREE_TYPE (build_ctype (d->type));
118 type = TYPE_MAIN_VARIANT (type);
119 d->isym = this->make_import (TYPE_STUB_DECL (type));
120 }
121
122 /* For now, ignore importing other kinds of dsymbols. */
123 void visit (ScopeDsymbol *)
124 {
125 }
126
127 /* Alias symbols aren't imported, but their targets are. */
128 void visit (AliasDeclaration *d)
129 {
130 Dsymbol *dsym = d->toAlias ();
131
132 if (dsym == d)
133 {
134 Type *type = d->getType ();
135
136 /* Type imports should really be part of their own visit method. */
137 if (type != NULL)
138 {
139 if (type->ty == Tenum)
140 dsym = ((TypeEnum *) type)->sym;
141 else if (type->ty == Tstruct)
142 dsym = ((TypeStruct *) type)->sym;
143 else if (type->ty == Tclass)
144 dsym = ((TypeClass *) type)->sym;
145 }
146 }
147
148 /* This symbol is really an alias for another, visit the other. */
149 if (dsym != d)
150 {
151 dsym->accept (this);
152 d->isym = dsym->isym;
153 }
154 }
155
156 /* Visit the underlying alias symbol of overloadable aliases. */
157 void visit (OverDeclaration *d)
158 {
159 if (d->aliassym != NULL)
160 {
161 d->aliassym->accept (this);
162 d->isym = d->aliassym->isym;
163 }
164 }
165
166 /* Build IMPORTED_DECLs for all overloads in a set. */
167 void visit (OverloadSet *d)
168 {
169 vec<tree, va_gc> *tset = NULL;
170
171 vec_alloc (tset, d->a.dim);
172
173 for (size_t i = 0; i < d->a.dim; i++)
174 vec_safe_push (tset, build_import_decl (d->a[i]));
175
176 d->isym = build_tree_list_vec (tset);
177 tset->truncate (0);
178 }
179
180 /* Function aliases are the same as alias symbols. */
181 void visit (FuncAliasDeclaration *d)
182 {
183 FuncDeclaration *fd = d->toAliasFunc ();
184
185 if (fd != NULL)
186 {
187 fd->accept (this);
188 d->isym = fd->isym;
189 }
190 }
191
192 /* Skip over importing templates and tuples. */
193 void visit (TemplateDeclaration *)
194 {
195 }
196
197 void visit (TupleDeclaration *)
198 {
199 }
200
201 /* Import any other kind of declaration. If the class does not implement
202 symbol generation routines, the compiler will throw an error. */
203 void visit (Declaration *d)
204 {
205 d->isym = this->make_import (get_symbol_decl (d));
206 }
207 };
208
209
210 /* Build a declaration for the symbol D that can be used for the
211 debug_hook imported_module_or_decl. */
212 tree
213 build_import_decl (Dsymbol *d)
214 {
215 if (!d->isym)
216 {
217 location_t saved_location = input_location;
218 ImportVisitor v;
219
220 input_location = make_location_t (d->loc);
221 d->accept (&v);
222 input_location = saved_location;
223 }
224
225 /* Not all visitors set 'isym'. */
226 return d->isym ? d->isym : NULL_TREE;
227 }
228
229