Mercurial > hg > CbC > CbC_gcc
diff gcc/d/imports.cc @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/d/imports.cc Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,208 @@ +/* imports.cc -- Build imported modules/declarations. + Copyright (C) 2014-2020 Free Software Foundation, Inc. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" + +#include "dmd/aggregate.h" +#include "dmd/declaration.h" +#include "dmd/enum.h" +#include "dmd/identifier.h" +#include "dmd/import.h" +#include "dmd/module.h" + +#include "tree.h" +#include "stringpool.h" + +#include "d-tree.h" + + +/* Implements the visitor interface to build debug trees for all + module and import declarations, where ISYM holds the cached + back-end representation to be returned. */ +class ImportVisitor : public Visitor +{ + using Visitor::visit; + + /* Build the declaration DECL as an imported symbol. */ + tree make_import (tree decl) + { + gcc_assert (decl != NULL_TREE); + + tree import = build_decl (input_location, IMPORTED_DECL, + DECL_NAME (decl), void_type_node); + IMPORTED_DECL_ASSOCIATED_DECL (import) = decl; + d_keep (import); + + return import; + } + +public: + ImportVisitor (void) + { + } + + /* This should be overridden by each symbol class. */ + void visit (Dsymbol *) + { + gcc_unreachable (); + } + + /* Build the module decl for M, this is considered toplevel, regardless + of whether there are any parent packages in the module system. */ + void visit (Module *m) + { + Loc loc = (m->md != NULL) ? m->md->loc + : Loc (m->srcfile->toChars (), 1, 0); + + m->isym = build_decl (make_location_t (loc), NAMESPACE_DECL, + get_identifier (m->toPrettyChars ()), + void_type_node); + d_keep (m->isym); + + if (!m->isRoot ()) + DECL_EXTERNAL (m->isym) = 1; + + TREE_PUBLIC (m->isym) = 1; + DECL_CONTEXT (m->isym) = NULL_TREE; + } + + /* Build an import of another module symbol. */ + + void visit (Import *m) + { + tree module = build_import_decl (m->mod); + m->isym = this->make_import (module); + } + + /* Build an import for any kind of user defined type. + Use the TYPE_DECL associated with the type symbol. */ + void visit (EnumDeclaration *d) + { + tree type = build_ctype (d->type); + /* Not all kinds of D enums create a TYPE_DECL. */ + if (TREE_CODE (type) == ENUMERAL_TYPE) + d->isym = this->make_import (TYPE_STUB_DECL (type)); + } + + void visit (AggregateDeclaration *d) + { + tree type = build_ctype (d->type); + d->isym = this->make_import (TYPE_STUB_DECL (type)); + } + + void visit (ClassDeclaration *d) + { + /* Want the RECORD_TYPE, not POINTER_TYPE. */ + tree type = TREE_TYPE (build_ctype (d->type)); + d->isym = this->make_import (TYPE_STUB_DECL (type)); + } + + /* For now, ignore importing other kinds of dsymbols. */ + void visit (ScopeDsymbol *) + { + } + + /* Alias symbols aren't imported, but their targets are. */ + void visit (AliasDeclaration *d) + { + Dsymbol *dsym = d->toAlias (); + + if (dsym == d) + { + Type *type = d->getType (); + + /* Type imports should really be part of their own visit method. */ + if (type != NULL) + { + if (type->ty == Tenum) + dsym = ((TypeEnum *) type)->sym; + else if (type->ty == Tstruct) + dsym = ((TypeStruct *) type)->sym; + else if (type->ty == Tclass) + dsym = ((TypeClass *) type)->sym; + } + } + + /* This symbol is really an alias for another, visit the other. */ + if (dsym != d) + { + dsym->accept (this); + d->isym = dsym->isym; + } + } + + /* Visit the underlying alias symbol of overloadable aliases. */ + void visit (OverDeclaration *d) + { + if (d->aliassym != NULL) + { + d->aliassym->accept (this); + d->isym = d->aliassym->isym; + } + } + + /* Function aliases are the same as alias symbols. */ + void visit (FuncAliasDeclaration *d) + { + FuncDeclaration *fd = d->toAliasFunc (); + + if (fd != NULL) + { + fd->accept (this); + d->isym = fd->isym; + } + } + + /* Skip over importing templates and tuples. */ + void visit (TemplateDeclaration *) + { + } + + void visit (TupleDeclaration *) + { + } + + /* Import any other kind of declaration. If the class does not implement + symbol generation routines, the compiler will throw an error. */ + void visit (Declaration *d) + { + d->isym = this->make_import (get_symbol_decl (d)); + } +}; + + +/* Build a declaration for the symbol D that can be used for the + debug_hook imported_module_or_decl. */ +tree +build_import_decl (Dsymbol *d) +{ + if (!d->isym) + { + location_t saved_location = input_location; + ImportVisitor v; + + input_location = make_location_t (d->loc); + d->accept (&v); + input_location = saved_location; + } + + /* Not all visitors set 'isym'. */ + return d->isym ? d->isym : NULL_TREE; +} +