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