Home | History | Annotate | Line # | Download | only in d
imports.cc revision 1.1.1.4
      1      1.1  mrg /* imports.cc -- Build imported modules/declarations.
      2  1.1.1.4  mrg    Copyright (C) 2014-2022 Free Software Foundation, Inc.
      3      1.1  mrg 
      4      1.1  mrg GCC is free software; you can redistribute it and/or modify
      5      1.1  mrg it under the terms of the GNU General Public License as published by
      6      1.1  mrg the Free Software Foundation; either version 3, or (at your option)
      7      1.1  mrg any later version.
      8      1.1  mrg 
      9      1.1  mrg GCC is distributed in the hope that it will be useful,
     10      1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     11      1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12      1.1  mrg GNU General Public License for more details.
     13      1.1  mrg 
     14      1.1  mrg You should have received a copy of the GNU General Public License
     15      1.1  mrg along with GCC; see the file COPYING3.  If not see
     16      1.1  mrg <http://www.gnu.org/licenses/>.  */
     17      1.1  mrg 
     18      1.1  mrg #include "config.h"
     19      1.1  mrg #include "system.h"
     20      1.1  mrg #include "coretypes.h"
     21      1.1  mrg 
     22      1.1  mrg #include "dmd/aggregate.h"
     23      1.1  mrg #include "dmd/declaration.h"
     24      1.1  mrg #include "dmd/enum.h"
     25      1.1  mrg #include "dmd/identifier.h"
     26      1.1  mrg #include "dmd/import.h"
     27      1.1  mrg #include "dmd/module.h"
     28      1.1  mrg 
     29      1.1  mrg #include "tree.h"
     30      1.1  mrg #include "stringpool.h"
     31      1.1  mrg 
     32      1.1  mrg #include "d-tree.h"
     33      1.1  mrg 
     34  1.1.1.4  mrg static hash_map<Dsymbol *, tree> *imported_decls;
     35      1.1  mrg 
     36      1.1  mrg /* Implements the visitor interface to build debug trees for all
     37  1.1.1.4  mrg    module and import declarations, where RESULT_ holds the back-end
     38  1.1.1.4  mrg    representation to be cached and returned from the caller.  */
     39      1.1  mrg class ImportVisitor : public Visitor
     40      1.1  mrg {
     41      1.1  mrg   using Visitor::visit;
     42      1.1  mrg 
     43  1.1.1.4  mrg   tree result_;
     44  1.1.1.4  mrg 
     45      1.1  mrg   /* Build the declaration DECL as an imported symbol.  */
     46      1.1  mrg   tree make_import (tree decl)
     47      1.1  mrg   {
     48      1.1  mrg     gcc_assert (decl != NULL_TREE);
     49      1.1  mrg 
     50      1.1  mrg     tree import = build_decl (input_location, IMPORTED_DECL,
     51      1.1  mrg 			      DECL_NAME (decl), void_type_node);
     52      1.1  mrg     IMPORTED_DECL_ASSOCIATED_DECL (import) = decl;
     53      1.1  mrg     d_keep (import);
     54      1.1  mrg 
     55      1.1  mrg     return import;
     56      1.1  mrg   }
     57      1.1  mrg 
     58      1.1  mrg public:
     59      1.1  mrg   ImportVisitor (void)
     60      1.1  mrg   {
     61  1.1.1.4  mrg     this->result_ = NULL_TREE;
     62  1.1.1.4  mrg   }
     63  1.1.1.4  mrg 
     64  1.1.1.4  mrg   tree result (void)
     65  1.1.1.4  mrg   {
     66  1.1.1.4  mrg     return this->result_;
     67      1.1  mrg   }
     68      1.1  mrg 
     69      1.1  mrg   /* This should be overridden by each symbol class.  */
     70      1.1  mrg   void visit (Dsymbol *)
     71      1.1  mrg   {
     72      1.1  mrg     gcc_unreachable ();
     73      1.1  mrg   }
     74      1.1  mrg 
     75      1.1  mrg   /* Build the module decl for M, this is considered toplevel, regardless
     76      1.1  mrg      of whether there are any parent packages in the module system.  */
     77      1.1  mrg   void visit (Module *m)
     78      1.1  mrg   {
     79      1.1  mrg     Loc loc = (m->md != NULL) ? m->md->loc
     80  1.1.1.4  mrg       : Loc (m->srcfile.toChars (), 1, 0);
     81      1.1  mrg 
     82  1.1.1.4  mrg     this->result_ = build_decl (make_location_t (loc), NAMESPACE_DECL,
     83  1.1.1.4  mrg 				get_identifier (m->toPrettyChars ()),
     84  1.1.1.4  mrg 				void_type_node);
     85  1.1.1.4  mrg     d_keep (this->result_);
     86      1.1  mrg 
     87      1.1  mrg     if (!m->isRoot ())
     88  1.1.1.4  mrg       DECL_EXTERNAL (this->result_) = 1;
     89      1.1  mrg 
     90  1.1.1.4  mrg     TREE_PUBLIC (this->result_) = 1;
     91  1.1.1.4  mrg     DECL_CONTEXT (this->result_) = NULL_TREE;
     92      1.1  mrg   }
     93      1.1  mrg 
     94      1.1  mrg   /* Build an import of another module symbol.  */
     95      1.1  mrg 
     96      1.1  mrg   void visit (Import *m)
     97      1.1  mrg   {
     98      1.1  mrg     tree module = build_import_decl (m->mod);
     99  1.1.1.4  mrg     this->result_ = this->make_import (module);
    100      1.1  mrg   }
    101      1.1  mrg 
    102      1.1  mrg   /* Build an import for any kind of user defined type.
    103      1.1  mrg      Use the TYPE_DECL associated with the type symbol.  */
    104      1.1  mrg   void visit (EnumDeclaration *d)
    105      1.1  mrg   {
    106      1.1  mrg     tree type = build_ctype (d->type);
    107      1.1  mrg     /* Not all kinds of D enums create a TYPE_DECL.  */
    108      1.1  mrg     if (TREE_CODE (type) == ENUMERAL_TYPE)
    109  1.1.1.3  mrg       {
    110  1.1.1.3  mrg 	type = TYPE_MAIN_VARIANT (type);
    111  1.1.1.4  mrg 	this->result_ = this->make_import (TYPE_STUB_DECL (type));
    112  1.1.1.3  mrg       }
    113      1.1  mrg   }
    114      1.1  mrg 
    115      1.1  mrg   void visit (AggregateDeclaration *d)
    116      1.1  mrg   {
    117      1.1  mrg     tree type = build_ctype (d->type);
    118  1.1.1.3  mrg     type = TYPE_MAIN_VARIANT (type);
    119  1.1.1.4  mrg     this->result_ = this->make_import (TYPE_STUB_DECL (type));
    120      1.1  mrg   }
    121      1.1  mrg 
    122      1.1  mrg   void visit (ClassDeclaration *d)
    123      1.1  mrg   {
    124      1.1  mrg     /* Want the RECORD_TYPE, not POINTER_TYPE.  */
    125      1.1  mrg     tree type = TREE_TYPE (build_ctype (d->type));
    126  1.1.1.3  mrg     type = TYPE_MAIN_VARIANT (type);
    127  1.1.1.4  mrg     this->result_ = this->make_import (TYPE_STUB_DECL (type));
    128  1.1.1.4  mrg   }
    129  1.1.1.4  mrg 
    130  1.1.1.4  mrg   void visit (VarDeclaration *d)
    131  1.1.1.4  mrg   {
    132  1.1.1.4  mrg     /* Not all kinds of manifest constants create a CONST_DECL.  */
    133  1.1.1.4  mrg     if (!d->canTakeAddressOf () && !d->type->isscalar ())
    134  1.1.1.4  mrg       return;
    135  1.1.1.4  mrg 
    136  1.1.1.4  mrg     visit ((Declaration *) d);
    137      1.1  mrg   }
    138      1.1  mrg 
    139      1.1  mrg   /* For now, ignore importing other kinds of dsymbols.  */
    140      1.1  mrg   void visit (ScopeDsymbol *)
    141      1.1  mrg   {
    142      1.1  mrg   }
    143      1.1  mrg 
    144      1.1  mrg   /* Alias symbols aren't imported, but their targets are.  */
    145      1.1  mrg   void visit (AliasDeclaration *d)
    146      1.1  mrg   {
    147      1.1  mrg     Dsymbol *dsym = d->toAlias ();
    148      1.1  mrg 
    149      1.1  mrg     if (dsym == d)
    150      1.1  mrg       {
    151      1.1  mrg 	Type *type = d->getType ();
    152      1.1  mrg 
    153      1.1  mrg 	/* Type imports should really be part of their own visit method.  */
    154      1.1  mrg 	if (type != NULL)
    155      1.1  mrg 	  {
    156  1.1.1.4  mrg 	    if (type->ty == TY::Tenum)
    157  1.1.1.4  mrg 	      dsym = type->isTypeEnum ()->sym;
    158  1.1.1.4  mrg 	    else if (type->ty == TY::Tstruct)
    159  1.1.1.4  mrg 	      dsym = type->isTypeStruct ()->sym;
    160  1.1.1.4  mrg 	    else if (type->ty == TY::Tclass)
    161  1.1.1.4  mrg 	      dsym = type->isTypeClass ()->sym;
    162      1.1  mrg 	  }
    163      1.1  mrg       }
    164      1.1  mrg 
    165      1.1  mrg     /* This symbol is really an alias for another, visit the other.  */
    166      1.1  mrg     if (dsym != d)
    167  1.1.1.4  mrg       dsym->accept (this);
    168      1.1  mrg   }
    169      1.1  mrg 
    170      1.1  mrg   /* Visit the underlying alias symbol of overloadable aliases.  */
    171      1.1  mrg   void visit (OverDeclaration *d)
    172      1.1  mrg   {
    173      1.1  mrg     if (d->aliassym != NULL)
    174  1.1.1.4  mrg       d->aliassym->accept (this);
    175      1.1  mrg   }
    176      1.1  mrg 
    177  1.1.1.3  mrg   /* Build IMPORTED_DECLs for all overloads in a set.  */
    178  1.1.1.3  mrg   void visit (OverloadSet *d)
    179  1.1.1.3  mrg   {
    180  1.1.1.3  mrg     vec<tree, va_gc> *tset = NULL;
    181  1.1.1.3  mrg 
    182  1.1.1.4  mrg     vec_alloc (tset, d->a.length);
    183  1.1.1.3  mrg 
    184  1.1.1.4  mrg     for (size_t i = 0; i < d->a.length; i++)
    185  1.1.1.4  mrg       {
    186  1.1.1.4  mrg 	tree overload = build_import_decl (d->a[i]);
    187  1.1.1.4  mrg 	if (overload != NULL_TREE)
    188  1.1.1.4  mrg 	  vec_safe_push (tset, overload);
    189  1.1.1.4  mrg       }
    190  1.1.1.3  mrg 
    191  1.1.1.4  mrg     this->result_ = build_tree_list_vec (tset);
    192  1.1.1.3  mrg     tset->truncate (0);
    193  1.1.1.3  mrg   }
    194  1.1.1.3  mrg 
    195      1.1  mrg   /* Function aliases are the same as alias symbols.  */
    196      1.1  mrg   void visit (FuncAliasDeclaration *d)
    197      1.1  mrg   {
    198      1.1  mrg     FuncDeclaration *fd = d->toAliasFunc ();
    199      1.1  mrg 
    200      1.1  mrg     if (fd != NULL)
    201  1.1.1.4  mrg       fd->accept (this);
    202      1.1  mrg   }
    203      1.1  mrg 
    204      1.1  mrg   /* Skip over importing templates and tuples.  */
    205      1.1  mrg   void visit (TemplateDeclaration *)
    206      1.1  mrg   {
    207      1.1  mrg   }
    208      1.1  mrg 
    209      1.1  mrg   void visit (TupleDeclaration *)
    210      1.1  mrg   {
    211      1.1  mrg   }
    212      1.1  mrg 
    213      1.1  mrg   /* Import any other kind of declaration.  If the class does not implement
    214      1.1  mrg      symbol generation routines, the compiler will throw an error.  */
    215      1.1  mrg   void visit (Declaration *d)
    216      1.1  mrg   {
    217  1.1.1.4  mrg     this->result_ = this->make_import (get_symbol_decl (d));
    218      1.1  mrg   }
    219      1.1  mrg };
    220      1.1  mrg 
    221      1.1  mrg 
    222      1.1  mrg /* Build a declaration for the symbol D that can be used for the
    223      1.1  mrg    debug_hook imported_module_or_decl.  */
    224      1.1  mrg tree
    225      1.1  mrg build_import_decl (Dsymbol *d)
    226      1.1  mrg {
    227  1.1.1.4  mrg   hash_map_maybe_create<hm_ggc> (imported_decls);
    228      1.1  mrg 
    229  1.1.1.4  mrg   if (tree *decl = imported_decls->get (d))
    230  1.1.1.4  mrg     return *decl;
    231  1.1.1.4  mrg 
    232  1.1.1.4  mrg   location_t saved_location = input_location;
    233  1.1.1.4  mrg   ImportVisitor v = ImportVisitor ();
    234  1.1.1.4  mrg 
    235  1.1.1.4  mrg   input_location = make_location_t (d->loc);
    236  1.1.1.4  mrg   d->accept (&v);
    237  1.1.1.4  mrg   input_location = saved_location;
    238      1.1  mrg 
    239  1.1.1.4  mrg   /* Not all visitors set `result'.  */
    240  1.1.1.4  mrg   tree isym = v.result ();
    241  1.1.1.4  mrg   if (isym != NULL_TREE)
    242  1.1.1.4  mrg     imported_decls->put (d, isym);
    243  1.1.1.4  mrg 
    244  1.1.1.4  mrg   return isym;
    245  1.1.1.4  mrg }
    246