1 /* imports.cc -- Build imported modules/declarations.
2 Copyright (C) 2014-2023 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/aggregate.h"
23 #include "dmd/declaration.h"
25 #include "dmd/identifier.h"
26 #include "dmd/import.h"
27 #include "dmd/module.h"
30 #include "stringpool.h"
34 static hash_map
<Dsymbol
*, tree
> *imported_decls
;
36 /* Implements the visitor interface to build debug trees for all
37 module and import declarations, where RESULT_ holds the back-end
38 representation to be cached and returned from the caller. */
39 class ImportVisitor
: public Visitor
45 /* Build the declaration DECL as an imported symbol. */
46 tree
make_import (tree decl
)
48 gcc_assert (decl
!= NULL_TREE
);
50 tree import
= build_decl (input_location
, IMPORTED_DECL
,
51 DECL_NAME (decl
), void_type_node
);
52 IMPORTED_DECL_ASSOCIATED_DECL (import
) = decl
;
61 this->result_
= NULL_TREE
;
69 /* This should be overridden by each symbol class. */
70 void visit (Dsymbol
*) final override
75 /* Build the module decl for M, this is considered toplevel, regardless
76 of whether there are any parent packages in the module system. */
77 void visit (Module
*m
) final override
79 Loc loc
= (m
->md
!= NULL
) ? m
->md
->loc
80 : Loc (m
->srcfile
.toChars (), 1, 0);
82 this->result_
= build_decl (make_location_t (loc
), NAMESPACE_DECL
,
83 get_identifier (m
->toPrettyChars ()),
85 d_keep (this->result_
);
88 DECL_EXTERNAL (this->result_
) = 1;
90 TREE_PUBLIC (this->result_
) = 1;
91 DECL_CONTEXT (this->result_
) = NULL_TREE
;
94 /* Build an import of another module symbol. */
96 void visit (Import
*m
) final override
98 tree module
= build_import_decl (m
->mod
);
99 this->result_
= this->make_import (module
);
102 /* Build an import for any kind of user defined type.
103 Use the TYPE_DECL associated with the type symbol. */
104 void visit (EnumDeclaration
*d
) final override
106 tree type
= build_ctype (d
->type
);
107 /* Not all kinds of D enums create a TYPE_DECL. */
108 if (TREE_CODE (type
) == ENUMERAL_TYPE
)
110 type
= TYPE_MAIN_VARIANT (type
);
111 this->result_
= this->make_import (TYPE_STUB_DECL (type
));
115 void visit (AggregateDeclaration
*d
) final override
117 tree type
= build_ctype (d
->type
);
118 type
= TYPE_MAIN_VARIANT (type
);
119 this->result_
= this->make_import (TYPE_STUB_DECL (type
));
122 void visit (ClassDeclaration
*d
) final override
124 /* Want the RECORD_TYPE, not POINTER_TYPE. */
125 tree type
= TREE_TYPE (build_ctype (d
->type
));
126 type
= TYPE_MAIN_VARIANT (type
);
127 this->result_
= this->make_import (TYPE_STUB_DECL (type
));
130 void visit (VarDeclaration
*d
) final override
132 /* Not all kinds of manifest constants create a CONST_DECL. */
133 if (!d
->canTakeAddressOf () && !d
->type
->isscalar ())
136 visit ((Declaration
*) d
);
139 /* For now, ignore importing other kinds of dsymbols. */
140 void visit (ScopeDsymbol
*) final override
144 /* Alias symbols aren't imported, but their targets are. */
145 void visit (AliasDeclaration
*d
) final override
147 Dsymbol
*dsym
= d
->toAlias ();
151 Type
*type
= d
->getType ();
153 /* Type imports should really be part of their own visit method. */
156 if (type
->ty
== TY::Tenum
)
157 dsym
= type
->isTypeEnum ()->sym
;
158 else if (type
->ty
== TY::Tstruct
)
159 dsym
= type
->isTypeStruct ()->sym
;
160 else if (type
->ty
== TY::Tclass
)
161 dsym
= type
->isTypeClass ()->sym
;
165 /* This symbol is really an alias for another, visit the other. */
170 /* Visit the underlying alias symbol of overloadable aliases. */
171 void visit (OverDeclaration
*d
) final override
173 if (d
->aliassym
!= NULL
)
174 d
->aliassym
->accept (this);
177 /* Build IMPORTED_DECLs for all overloads in a set. */
178 void visit (OverloadSet
*d
) final override
180 vec
<tree
, va_gc
> *tset
= NULL
;
182 vec_alloc (tset
, d
->a
.length
);
184 for (size_t i
= 0; i
< d
->a
.length
; i
++)
185 vec_safe_push (tset
, build_import_decl (d
->a
[i
]));
187 this->result_
= build_tree_list_vec (tset
);
191 /* Function aliases are the same as alias symbols. */
192 void visit (FuncAliasDeclaration
*d
) final override
194 FuncDeclaration
*fd
= d
->toAliasFunc ();
200 /* Skip over importing templates and tuples. */
201 void visit (TemplateDeclaration
*) final override
205 void visit (TupleDeclaration
*) final override
209 /* Import any other kind of declaration. If the class does not implement
210 symbol generation routines, the compiler will throw an error. */
211 void visit (Declaration
*d
) final override
213 this->result_
= this->make_import (get_symbol_decl (d
));
218 /* Build a declaration for the symbol D that can be used for the
219 debug_hook imported_module_or_decl. */
221 build_import_decl (Dsymbol
*d
)
223 hash_map_maybe_create
<hm_ggc
> (imported_decls
);
225 if (tree
*decl
= imported_decls
->get (d
))
228 location_t saved_location
= input_location
;
229 ImportVisitor v
= ImportVisitor ();
231 input_location
= make_location_t (d
->loc
);
233 input_location
= saved_location
;
235 /* Not all visitors set `result'. */
236 tree isym
= v
.result ();
237 if (isym
!= NULL_TREE
)
238 imported_decls
->put (d
, isym
);