aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/dclass.c
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2019-06-18 20:42:10 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2021-11-30 16:53:28 +0100
commit5fee5ec362f7a243f459e6378fd49dfc89dc9fb5 (patch)
tree61d1bdbca854a903c0860406f457f06b2040be7a /gcc/d/dmd/dclass.c
parentb3f60112edcb85b459e60f66c44a55138b1cef49 (diff)
downloadgcc-5fee5ec362f7a243f459e6378fd49dfc89dc9fb5.zip
gcc-5fee5ec362f7a243f459e6378fd49dfc89dc9fb5.tar.gz
gcc-5fee5ec362f7a243f459e6378fd49dfc89dc9fb5.tar.bz2
d: Import dmd b8384668f, druntime e6caaab9, phobos 5ab9ad256 (v2.098.0-beta.1)
The D front-end is now itself written in D, in order to build GDC, you will need a working GDC compiler (GCC version 9.1 or later). GCC changes: - Add support for bootstrapping the D front-end. These add the required components in order to have a D front-end written in D itself. Because the compiler front-end only depends on the core runtime modules, only libdruntime is built for the bootstrap stages. D front-end changes: - Import dmd v2.098.0-beta.1. Druntime changes: - Import druntime v2.098.0-beta.1. Phobos changes: - Import phobos v2.098.0-beta.1. The jump from v2.076.1 to v2.098.0 covers nearly 4 years worth of development on the D programming language and run-time libraries. ChangeLog: * Makefile.def: Add bootstrap to libbacktrace, libphobos, zlib, and libatomic. * Makefile.in: Regenerate. * Makefile.tpl (POSTSTAGE1_HOST_EXPORTS): Fix command for GDC. (STAGE1_CONFIGURE_FLAGS): Add --with-libphobos-druntime-only if target-libphobos-bootstrap. (STAGE2_CONFIGURE_FLAGS): Likewise. * configure: Regenerate. * configure.ac: Add support for bootstrapping D front-end. config/ChangeLog: * acx.m4 (ACX_PROG_GDC): New m4 function. gcc/ChangeLog: * Makefile.in (GDC): New variable. (GDCFLAGS): New variable. * configure: Regenerate. * configure.ac: Add call to ACX_PROG_GDC. Substitute GDCFLAGS. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd b8384668f. * Make-lang.in (d-warn): Use strict warnings. (DMD_WARN_CXXFLAGS): Remove. (DMD_COMPILE): Remove. (CHECKING_DFLAGS): Define. (WARN_DFLAGS): Define. (ALL_DFLAGS): Define. (DCOMPILE.base): Define. (DCOMPILE): Define. (DPOSTCOMPILE): Define. (DLINKER): Define. (DLLINKER): Define. (D_FRONTEND_OBJS): Add new dmd front-end objects. (D_GENERATED_SRCS): Remove. (D_GENERATED_OBJS): Remove. (D_ALL_OBJS): Remove D_GENERATED_OBJS. (d21$(exeext)): Build using DLLINKER and -static-libphobos. (d.tags): Remove dmd/*.c and dmd/root/*.c. (d.mostlyclean): Remove D_GENERATED_SRCS, d/idgen$(build_exeext), d/impcnvgen$(build_exeext). (D_INCLUDES): Include $(srcdir)/d/dmd/res. (CFLAGS-d/id.o): Remove. (CFLAGS-d/impcnvtab.o): Remove. (d/%.o): Build using DCOMPILE and DPOSTCOMPILE. Update dependencies from d/dmd/%.c to d/dmd/%.d. (d/idgen$(build_exeext)): Remove. (d/impcnvgen$(build_exeext)): Remove. (d/id.c): Remove. (d/id.h): Remove. (d/impcnvtab.c): Remove. (d/%.dmdgen.o): Remove. (D_SYSTEM_H): Remove. (d/idgen.dmdgen.o): Remove. (d/impcnvgen.dmdgen.o): Remove. * config-lang.in (boot_language): New variable. * d-attribs.cc: Include dmd/expression.h. * d-builtins.cc: Include d-frontend.h. (build_frontend_type): Update for new front-end interface. (d_eval_constant_expression): Likewise. (d_build_builtins_module): Likewise. (maybe_set_builtin_1): Likewise. (d_build_d_type_nodes): Likewise. * d-codegen.cc (d_decl_context): Likewise. (declaration_reference_p): Likewise. (declaration_type): Likewise. (parameter_reference_p): Likewise. (parameter_type): Likewise. (get_array_length): Likewise. (build_delegate_cst): Likewise. (build_typeof_null_value): Likewise. (identity_compare_p): Likewise. (lower_struct_comparison): Likewise. (build_filename_from_loc): Likewise. (build_assert_call): Remove LIBCALL_SWITCH_ERROR. (build_bounds_index_condition): Call LIBCALL_ARRAYBOUNDS_INDEXP on bounds error. (build_bounds_slice_condition): Call LIBCALL_ARRAYBOUNDS_SLICEP on bounds error. (array_bounds_check): Update for new front-end interface. (checkaction_trap_p): Handle CHECKACTION_context. (get_function_type): Update for new front-end interface. (d_build_call): Likewise. * d-compiler.cc: Remove include of dmd/scope.h. (Compiler::genCmain): Remove. (Compiler::paintAsType): Update for new front-end interface. (Compiler::onParseModule): Likewise. * d-convert.cc (convert_expr): Remove call to LIBCALL_ARRAYCAST. (convert_for_rvalue): Update for new front-end interface. (convert_for_assignment): Likewise. (convert_for_condition): Likewise. (d_array_convert): Likewise. * d-diagnostic.cc (error): Remove. (errorSupplemental): Remove. (warning): Remove. (warningSupplemental): Remove. (deprecation): Remove. (deprecationSupplemental): Remove. (message): Remove. (vtip): New. * d-frontend.cc (global): Remove. (Global::_init): Remove. (Global::startGagging): Remove. (Global::endGagging): Remove. (Global::increaseErrorCount): Remove. (Loc::Loc): Remove. (Loc::toChars): Remove. (Loc::equals): Remove. (isBuiltin): Update for new front-end interface. (eval_builtin): Likewise. (getTypeInfoType): Likewise. (inlineCopy): Remove. * d-incpath.cc: Include d-frontend.h. (add_globalpaths): Call d_gc_malloc to allocate Strings. (add_filepaths): Likewise. * d-lang.cc: Include dmd/id.h, dmd/root/file.h, d-frontend.h. Remove include of dmd/mars.h, id.h. (entrypoint_module): Remove. (entrypoint_root_module): Remove. (deps_write_string): Update for new front-end interface. (deps_write): Likewise. (d_init_options): Call rt_init. Remove setting global params that are default initialized by the front-end. (d_handle_option): Handle OPT_fcheckaction_, OPT_fdump_c___spec_, OPT_fdump_c___spec_verbose, OPT_fextern_std_, OPT_fpreview, OPT_revert, OPT_fsave_mixins_, and OPT_ftransition. (d_post_options): Propagate dip1021 and dip1000 preview flags to dip25, and flag_diagnostics_show_caret to printErrorContext. (d_add_entrypoint_module): Remove. (d_parse_file): Update for new front-end interface. (d_type_promotes_to): Likewise. (d_types_compatible_p): Likewise. * d-longdouble.cc (CTFloat::zero): Remove. (CTFloat::one): Remove. (CTFloat::minusone): Remove. (CTFloat::half): Remove. * d-system.h (POSIX): Remove. (realpath): Remove. (isalpha): Remove. (isalnum): Remove. (isdigit): Remove. (islower): Remove. (isprint): Remove. (isspace): Remove. (isupper): Remove. (isxdigit): Remove. (tolower): Remove. (_mkdir): Remove. (INT32_MAX): Remove. (INT32_MIN): Remove. (INT64_MIN): Remove. (UINT32_MAX): Remove. (UINT64_MAX): Remove. * d-target.cc: Include calls.h. (target): Remove. (define_float_constants): Remove initialization of snan. (Target::_init): Update for new front-end interface. (Target::isVectorTypeSupported): Likewise. (Target::isVectorOpSupported): Remove cases for unordered operators. (TargetCPP::typeMangle): Update for new front-end interface. (TargetCPP::parameterType): Likewise. (Target::systemLinkage): Likewise. (Target::isReturnOnStack): Likewise. (Target::isCalleeDestroyingArgs): Define. (Target::preferPassByRef): Define. * d-tree.h (d_add_entrypoint_module): Remove. * decl.cc (gcc_attribute_p): Update for new front-end interface. (apply_pragma_crt): Define. (DeclVisitor::visit(PragmaDeclaration *)): Handle pragmas crt_constructor and crt_destructor. (DeclVisitor::visit(TemplateDeclaration *)): Update for new front-end interface. (DeclVisitor::visit): Likewise. (DeclVisitor::finish_vtable): Likewise. (get_symbol_decl): Error if template has more than one nesting context. Update for new front-end interface. (make_thunk): Update for new front-end interface. (get_vtable_decl): Likewise. * expr.cc (ExprVisitor::visit): Likewise. (build_return_dtor): Likewise. * imports.cc (ImportVisitor::visit): Likewise. * intrinsics.cc: Include dmd/expression.h. Remove include of dmd/mangle.h. (maybe_set_intrinsic): Update for new front-end interface. * intrinsics.def (INTRINSIC_ROL): Update intrinsic signature. (INTRINSIC_ROR): Likewise. (INTRINSIC_ROR_TIARG): Likewise. (INTRINSIC_TOPREC): Likewise. (INTRINSIC_TOPRECL): Likewise. (INTRINSIC_TAN): Update intrinsic module and signature. (INTRINSIC_ISNAN): Likewise. (INTRINSIC_ISFINITE): Likewise. (INTRINSIC_COPYSIGN): Define intrinsic. (INTRINSIC_COPYSIGNI): Define intrinsic. (INTRINSIC_EXP): Update intrinsic module. (INTRINSIC_EXPM1): Likewise. (INTRINSIC_EXP2): Likewise. (INTRINSIC_LOG): Likewise. (INTRINSIC_LOG2): Likewise. (INTRINSIC_LOG10): Likewise. (INTRINSIC_POW): Likewise. (INTRINSIC_ROUND): Likewise. (INTRINSIC_FLOORF): Likewise. (INTRINSIC_FLOOR): Likewise. (INTRINSIC_FLOORL): Likewise. (INTRINSIC_CEILF): Likewise. (INTRINSIC_CEIL): Likewise. (INTRINSIC_CEILL): Likewise. (INTRINSIC_TRUNC): Likewise. (INTRINSIC_FMIN): Likewise. (INTRINSIC_FMAX): Likewise. (INTRINSIC_FMA): Likewise. (INTRINSIC_VA_ARG): Update intrinsic signature. (INTRINSIC_VASTART): Likewise. * lang.opt (fcheck=): Add alternate aliases for contract switches. (fcheckaction=): New option. (check_action): New Enum and EnumValue entries. (fdump-c++-spec-verbose): New option. (fdump-c++-spec=): New option. (fextern-std=): New option. (extern_stdcpp): New Enum and EnumValue entries (fpreview=): New options. (frevert=): New options. (fsave-mixins): New option. (ftransition=): Update options. * modules.cc (get_internal_fn): Replace Prot with Visibility. (build_internal_fn): Likewise. (build_dso_cdtor_fn): Likewise. (build_module_tree): Remove check for __entrypoint module. * runtime.def (P5): Define. (ARRAYBOUNDS_SLICEP): Define. (ARRAYBOUNDS_INDEXP): Define. (NEWTHROW): Define. (ADCMP2): Remove. (ARRAYCAST): Remove. (SWITCH_STRING): Remove. (SWITCH_USTRING): Remove. (SWITCH_DSTRING): Remove. (SWITCH_ERROR): Remove. * toir.cc (IRVisitor::visit): Update for new front-end interface. (IRVisitor::check_previous_goto): Remove checks for case and default statements. (IRVisitor::visit(SwitchStatement *)): Remove handling of string switch conditions. * typeinfo.cc: Include d-frontend.h. (get_typeinfo_kind): Update for new front-end interface. (make_frontend_typeinfo): Likewise. (TypeInfoVisitor::visit): Likewise. (builtin_typeinfo_p): Likewise. (get_typeinfo_decl): Likewise. (build_typeinfo): Likewise. * types.cc (valist_array_p): Likewise. (make_array_type): Likewise. (merge_aggregate_types): Likewise. (TypeVisitor::visit(TypeBasic *)): Likewise. (TypeVisitor::visit(TypeFunction *)): Likewise. (TypeVisitor::visit(TypeStruct *)): Update comment. * verstr.h: Removed. * d-frontend.h: New file. gcc/po/ChangeLog: * EXCLUDES: Remove d/dmd sources from list. gcc/testsuite/ChangeLog: * gdc.dg/Wcastresult2.d: Update test. * gdc.dg/asm1.d: Likewise. * gdc.dg/asm2.d: Likewise. * gdc.dg/asm3.d: Likewise. * gdc.dg/gdc282.d: Likewise. * gdc.dg/imports/gdc170.d: Likewise. * gdc.dg/intrinsics.d: Likewise. * gdc.dg/pr101672.d: Likewise. * gdc.dg/pr90650a.d: Likewise. * gdc.dg/pr90650b.d: Likewise. * gdc.dg/pr94777a.d: Likewise. * gdc.dg/pr95250.d: Likewise. * gdc.dg/pr96869.d: Likewise. * gdc.dg/pr98277.d: Likewise. * gdc.dg/pr98457.d: Likewise. * gdc.dg/simd1.d: Likewise. * gdc.dg/simd2a.d: Likewise. * gdc.dg/simd2b.d: Likewise. * gdc.dg/simd2c.d: Likewise. * gdc.dg/simd2d.d: Likewise. * gdc.dg/simd2e.d: Likewise. * gdc.dg/simd2f.d: Likewise. * gdc.dg/simd2g.d: Likewise. * gdc.dg/simd2h.d: Likewise. * gdc.dg/simd2i.d: Likewise. * gdc.dg/simd2j.d: Likewise. * gdc.dg/simd7951.d: Likewise. * gdc.dg/torture/gdc309.d: Likewise. * gdc.dg/torture/pr94424.d: Likewise. * gdc.dg/torture/pr94777b.d: Likewise. * lib/gdc-utils.exp (gdc-convert-args): Handle new compiler options. (gdc-convert-test): Handle CXXFLAGS, EXTRA_OBJC_SOURCES, and ARG_SETS test directives. (gdc-do-test): Only import modules in the test run directory. * gdc.dg/pr94777c.d: New test. * gdc.dg/pr96156b.d: New test. * gdc.dg/pr96157c.d: New test. * gdc.dg/simd_ctfe.d: New test. * gdc.dg/torture/simd17344.d: New test. * gdc.dg/torture/simd20052.d: New test. * gdc.dg/torture/simd6.d: New test. * gdc.dg/torture/simd7.d: New test. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime e6caaab9. * libdruntime/Makefile.am (D_EXTRA_FLAGS): Build libdruntime with -fpreview=dip1000, -fpreview=fieldwise, and -fpreview=dtorfields. (ALL_DRUNTIME_SOURCES): Add DRUNTIME_DSOURCES_STDCXX. (DRUNTIME_DSOURCES): Update list of C binding modules. (DRUNTIME_DSOURCES_STDCXX): Likewise. (DRUNTIME_DSOURCES_LINUX): Likewise. (DRUNTIME_DSOURCES_OPENBSD): Likewise. (DRUNTIME_DISOURCES): Remove __entrypoint.di. * libdruntime/Makefile.in: Regenerated. * libdruntime/__entrypoint.di: Removed. * libdruntime/gcc/deh.d (_d_isbaseof): Update signature. (_d_createTrace): Likewise. (__gdc_begin_catch): Remove reference to the exception. (_d_throw): Increment reference count of thrown object before unwind. (__gdc_personality): Chain exceptions with Throwable.chainTogether. * libdruntime/gcc/emutls.d: Update imports. * libdruntime/gcc/sections/elf.d: Update imports. (DSO.moduleGroup): Update signature. * libdruntime/gcc/sections/macho.d: Update imports. (DSO.moduleGroup): Update signature. * libdruntime/gcc/sections/pecoff.d: Update imports. (DSO.moduleGroup): Update signature. * src/MERGE: Merge upstream phobos 5ab9ad256. * src/Makefile.am (D_EXTRA_DFLAGS): Add -fpreview=dip1000 and -fpreview=dtorfields flags. (PHOBOS_DSOURCES): Update list of std modules. * src/Makefile.in: Regenerate. * testsuite/lib/libphobos.exp (libphobos-dg-test): Handle assembly compile types. (dg-test): Override. (additional_prunes): Define. (libphobos-dg-prune): Filter any additional_prunes set by tests. * testsuite/libphobos.aa/test_aa.d: Update test. * testsuite/libphobos.druntime/druntime.exp (version_flags): Add -fversion=CoreUnittest. * testsuite/libphobos.druntime_shared/druntime_shared.exp (version_flags): Add -fversion=CoreUnittest -fversion=Shared. * testsuite/libphobos.exceptions/unknown_gc.d: Update test. * testsuite/libphobos.hash/test_hash.d: Update test. * testsuite/libphobos.phobos/phobos.exp (version_flags): Add -fversion=StdUnittest * testsuite/libphobos.phobos_shared/phobos_shared.exp (version_flags): Likewise. * testsuite/libphobos.shared/host.c: Update test. * testsuite/libphobos.shared/load.d: Update test. * testsuite/libphobos.shared/load_13414.d: Update test. * testsuite/libphobos.thread/fiber_guard_page.d: Update test. * testsuite/libphobos.thread/tlsgc_sections.d: Update test. * testsuite/testsuite_flags.in: Add -fpreview=dip1000 to --gdcflags. * testsuite/libphobos.shared/link_mod_collision.d: Removed. * testsuite/libphobos.shared/load_mod_collision.d: Removed. * testsuite/libphobos.betterc/betterc.exp: New test. * testsuite/libphobos.config/config.exp: New test. * testsuite/libphobos.gc/gc.exp: New test. * testsuite/libphobos.imports/imports.exp: New test. * testsuite/libphobos.lifetime/lifetime.exp: New test. * testsuite/libphobos.unittest/unittest.exp: New test.
Diffstat (limited to 'gcc/d/dmd/dclass.c')
-rw-r--r--gcc/d/dmd/dclass.c1041
1 files changed, 0 insertions, 1041 deletions
diff --git a/gcc/d/dmd/dclass.c b/gcc/d/dmd/dclass.c
deleted file mode 100644
index 3f33014..0000000
--- a/gcc/d/dmd/dclass.c
+++ /dev/null
@@ -1,1041 +0,0 @@
-
-/* Compiler implementation of the D programming language
- * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
- * written by Walter Bright
- * http://www.digitalmars.com
- * Distributed under the Boost Software License, Version 1.0.
- * http://www.boost.org/LICENSE_1_0.txt
- * https://github.com/D-Programming-Language/dmd/blob/master/src/class.c
- */
-
-#include "root/dsystem.h" // mem{cpy|set}()
-#include "root/root.h"
-#include "root/rmem.h"
-
-#include "errors.h"
-#include "enum.h"
-#include "init.h"
-#include "attrib.h"
-#include "declaration.h"
-#include "aggregate.h"
-#include "id.h"
-#include "mtype.h"
-#include "scope.h"
-#include "module.h"
-#include "expression.h"
-#include "statement.h"
-#include "template.h"
-#include "target.h"
-#include "objc.h"
-
-bool symbolIsVisible(Dsymbol *origin, Dsymbol *s);
-Objc *objc();
-
-
-/********************************* ClassDeclaration ****************************/
-
-ClassDeclaration *ClassDeclaration::object;
-ClassDeclaration *ClassDeclaration::throwable;
-ClassDeclaration *ClassDeclaration::exception;
-ClassDeclaration *ClassDeclaration::errorException;
-ClassDeclaration *ClassDeclaration::cpp_type_info_ptr; // Object.__cpp_type_info_ptr
-
-ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject)
- : AggregateDeclaration(loc, id ? id : Identifier::generateId("__anonclass"))
-{
- static const char msg[] = "only object.d can define this reserved class name";
-
- if (baseclasses)
- {
- // Actually, this is a transfer
- this->baseclasses = baseclasses;
- }
- else
- this->baseclasses = new BaseClasses();
-
- this->members = members;
-
- baseClass = NULL;
-
- interfaces.length = 0;
- interfaces.ptr = NULL;
-
- vtblInterfaces = NULL;
-
- //printf("ClassDeclaration(%s), dim = %d\n", id->toChars(), this->baseclasses->length);
-
- // For forward references
- type = new TypeClass(this);
-
- staticCtor = NULL;
- staticDtor = NULL;
-
- vtblsym = NULL;
- vclassinfo = NULL;
-
- if (id)
- {
- // Look for special class names
-
- if (id == Id::__sizeof || id == Id::__xalignof || id == Id::_mangleof)
- error("illegal class name");
-
- // BUG: What if this is the wrong TypeInfo, i.e. it is nested?
- if (id->toChars()[0] == 'T')
- {
- if (id == Id::TypeInfo)
- {
- if (!inObject)
- error("%s", msg);
- Type::dtypeinfo = this;
- }
-
- if (id == Id::TypeInfo_Class)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfoclass = this;
- }
-
- if (id == Id::TypeInfo_Interface)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfointerface = this;
- }
-
- if (id == Id::TypeInfo_Struct)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfostruct = this;
- }
-
- if (id == Id::TypeInfo_Pointer)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfopointer = this;
- }
-
- if (id == Id::TypeInfo_Array)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfoarray = this;
- }
-
- if (id == Id::TypeInfo_StaticArray)
- {
- //if (!inObject)
- // Type::typeinfostaticarray->error("%s", msg);
- Type::typeinfostaticarray = this;
- }
-
- if (id == Id::TypeInfo_AssociativeArray)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfoassociativearray = this;
- }
-
- if (id == Id::TypeInfo_Enum)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfoenum = this;
- }
-
- if (id == Id::TypeInfo_Function)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfofunction = this;
- }
-
- if (id == Id::TypeInfo_Delegate)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfodelegate = this;
- }
-
- if (id == Id::TypeInfo_Tuple)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfotypelist = this;
- }
-
- if (id == Id::TypeInfo_Const)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfoconst = this;
- }
-
- if (id == Id::TypeInfo_Invariant)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfoinvariant = this;
- }
-
- if (id == Id::TypeInfo_Shared)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfoshared = this;
- }
-
- if (id == Id::TypeInfo_Wild)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfowild = this;
- }
-
- if (id == Id::TypeInfo_Vector)
- {
- if (!inObject)
- error("%s", msg);
- Type::typeinfovector = this;
- }
- }
-
- if (id == Id::Object)
- {
- if (!inObject)
- error("%s", msg);
- object = this;
- }
-
- if (id == Id::Throwable)
- {
- if (!inObject)
- error("%s", msg);
- throwable = this;
- }
-
- if (id == Id::Exception)
- {
- if (!inObject)
- error("%s", msg);
- exception = this;
- }
-
- if (id == Id::Error)
- {
- if (!inObject)
- error("%s", msg);
- errorException = this;
- }
-
- if (id == Id::cpp_type_info_ptr)
- {
- if (!inObject)
- error("%s", msg);
- cpp_type_info_ptr = this;
- }
- }
-
- com = false;
- isscope = false;
- isabstract = ABSfwdref;
- inuse = 0;
- baseok = BASEOKnone;
- cpp_type_info_ptr_sym = NULL;
-}
-
-ClassDeclaration *ClassDeclaration::create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject)
-{
- return new ClassDeclaration(loc, id, baseclasses, members, inObject);
-}
-
-Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
-{
- //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars());
- ClassDeclaration *cd =
- s ? (ClassDeclaration *)s
- : new ClassDeclaration(loc, ident, NULL, NULL, false);
-
- cd->storage_class |= storage_class;
-
- cd->baseclasses->setDim(this->baseclasses->length);
- for (size_t i = 0; i < cd->baseclasses->length; i++)
- {
- BaseClass *b = (*this->baseclasses)[i];
- BaseClass *b2 = new BaseClass(b->type->syntaxCopy());
- (*cd->baseclasses)[i] = b2;
- }
-
- return ScopeDsymbol::syntaxCopy(cd);
-}
-
-Scope *ClassDeclaration::newScope(Scope *sc)
-{
- Scope *sc2 = AggregateDeclaration::newScope(sc);
- if (isCOMclass())
- {
- /* This enables us to use COM objects under Linux and
- * work with things like XPCOM
- */
- sc2->linkage = target.systemLinkage();
- }
- return sc2;
-}
-
-/*********************************************
- * Determine if 'this' is a base class of cd.
- * This is used to detect circular inheritance only.
- */
-
-bool ClassDeclaration::isBaseOf2(ClassDeclaration *cd)
-{
- if (!cd)
- return false;
- //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
- for (size_t i = 0; i < cd->baseclasses->length; i++)
- {
- BaseClass *b = (*cd->baseclasses)[i];
- if (b->sym == this || isBaseOf2(b->sym))
- return true;
- }
- return false;
-}
-
-/*******************************************
- * Determine if 'this' is a base class of cd.
- */
-
-bool ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
-{
- //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
- if (poffset)
- *poffset = 0;
- while (cd)
- {
- /* cd->baseClass might not be set if cd is forward referenced.
- */
- if (!cd->baseClass && cd->semanticRun < PASSsemanticdone && !cd->isInterfaceDeclaration())
- {
- dsymbolSemantic(cd, NULL);
- if (!cd->baseClass && cd->semanticRun < PASSsemanticdone)
- cd->error("base class is forward referenced by %s", toChars());
- }
-
- if (this == cd->baseClass)
- return true;
-
- cd = cd->baseClass;
- }
- return false;
-}
-
-/*********************************************
- * Determine if 'this' has complete base class information.
- * This is used to detect forward references in covariant overloads.
- */
-
-bool ClassDeclaration::isBaseInfoComplete()
-{
- return baseok >= BASEOKdone;
-}
-
-Dsymbol *ClassDeclaration::search(const Loc &loc, Identifier *ident, int flags)
-{
- //printf("%s.ClassDeclaration::search('%s', flags=x%x)\n", toChars(), ident->toChars(), flags);
-
- //if (_scope) printf("%s baseok = %d\n", toChars(), baseok);
- if (_scope && baseok < BASEOKdone)
- {
- if (!inuse)
- {
- // must semantic on base class/interfaces
- ++inuse;
- dsymbolSemantic(this, NULL);
- --inuse;
- }
- }
-
- if (!members || !symtab) // opaque or addMember is not yet done
- {
- error("is forward referenced when looking for `%s`", ident->toChars());
- //*(char*)0=0;
- return NULL;
- }
-
- Dsymbol *s = ScopeDsymbol::search(loc, ident, flags);
-
- // don't search imports of base classes
- if (flags & SearchImportsOnly)
- return s;
-
- if (!s)
- {
- // Search bases classes in depth-first, left to right order
-
- for (size_t i = 0; i < baseclasses->length; i++)
- {
- BaseClass *b = (*baseclasses)[i];
-
- if (b->sym)
- {
- if (!b->sym->symtab)
- error("base %s is forward referenced", b->sym->ident->toChars());
- else
- {
- s = b->sym->search(loc, ident, flags);
- if (!s)
- continue;
- else if (s == this) // happens if s is nested in this and derives from this
- s = NULL;
- else if (!(flags & IgnoreSymbolVisibility) && !(s->prot().kind == Prot::protected_) && !symbolIsVisible(this, s))
- s = NULL;
- else
- break;
- }
- }
- }
- }
- return s;
-}
-
-/************************************
- * Search base classes in depth-first, left-to-right order for
- * a class or interface named 'ident'.
- * Stops at first found. Does not look for additional matches.
- * Params:
- * ident = identifier to search for
- * Returns:
- * ClassDeclaration if found, null if not
- */
-ClassDeclaration *ClassDeclaration::searchBase(Identifier *ident)
-{
- for (size_t i = 0; i < baseclasses->length; i++)
- {
- BaseClass *b = (*baseclasses)[i];
- ClassDeclaration *cdb = b->type->isClassHandle();
- if (!cdb) // Bugzilla 10616
- return NULL;
- if (cdb->ident->equals(ident))
- return cdb;
- cdb = cdb->searchBase(ident);
- if (cdb)
- return cdb;
- }
- return NULL;
-}
-
-/****
- * Runs through the inheritance graph to set the BaseClass.offset fields.
- * Recursive in order to account for the size of the interface classes, if they are
- * more than just interfaces.
- * Params:
- * cd = interface to look at
- * baseOffset = offset of where cd will be placed
- * Returns:
- * subset of instantiated size used by cd for interfaces
- */
-static unsigned membersPlace(BaseClasses *vtblInterfaces, size_t &bi, ClassDeclaration *cd, unsigned baseOffset)
-{
- //printf(" membersPlace(%s, %d)\n", cd->toChars(), baseOffset);
- unsigned offset = baseOffset;
-
- for (size_t i = 0; i < cd->interfaces.length; i++)
- {
- BaseClass *b = cd->interfaces.ptr[i];
- if (b->sym->sizeok != SIZEOKdone)
- b->sym->finalizeSize();
- assert(b->sym->sizeok == SIZEOKdone);
-
- if (!b->sym->alignsize)
- b->sym->alignsize = target.ptrsize;
- cd->alignmember(b->sym->alignsize, b->sym->alignsize, &offset);
- assert(bi < vtblInterfaces->length);
- BaseClass *bv = (*vtblInterfaces)[bi];
- if (b->sym->interfaces.length == 0)
- {
- //printf("\tvtblInterfaces[%d] b=%p b->sym = %s, offset = %d\n", bi, bv, bv->sym->toChars(), offset);
- bv->offset = offset;
- ++bi;
- // All the base interfaces down the left side share the same offset
- for (BaseClass *b2 = bv; b2->baseInterfaces.length; )
- {
- b2 = &b2->baseInterfaces.ptr[0];
- b2->offset = offset;
- //printf("\tvtblInterfaces[%d] b=%p sym = %s, offset = %d\n", bi, b2, b2->sym->toChars(), b2->offset);
- }
- }
- membersPlace(vtblInterfaces, bi, b->sym, offset);
- //printf(" %s size = %d\n", b->sym->toChars(), b->sym->structsize);
- offset += b->sym->structsize;
- if (cd->alignsize < b->sym->alignsize)
- cd->alignsize = b->sym->alignsize;
- }
- return offset - baseOffset;
-}
-
-void ClassDeclaration::finalizeSize()
-{
- assert(sizeok != SIZEOKdone);
-
- // Set the offsets of the fields and determine the size of the class
- if (baseClass)
- {
- assert(baseClass->sizeok == SIZEOKdone);
-
- alignsize = baseClass->alignsize;
- if (classKind == ClassKind::cpp)
- structsize = target.cpp.derivedClassOffset(baseClass);
- else
- structsize = baseClass->structsize;
- }
- else if (isInterfaceDeclaration())
- {
- if (interfaces.length == 0)
- {
- alignsize = target.ptrsize;
- structsize = target.ptrsize; // allow room for __vptr
- }
- }
- else
- {
- alignsize = target.ptrsize;
- structsize = target.ptrsize; // allow room for __vptr
- if (hasMonitor())
- structsize += target.ptrsize; // allow room for __monitor
- }
-
- //printf("finalizeSize() %s, sizeok = %d\n", toChars(), sizeok);
- size_t bi = 0; // index into vtblInterfaces[]
-
- // Add vptr's for any interfaces implemented by this class
- structsize += membersPlace(vtblInterfaces, bi, this, structsize);
-
- if (isInterfaceDeclaration())
- {
- sizeok = SIZEOKdone;
- return;
- }
-
- // FIXME: Currently setFieldOffset functions need to increase fields
- // to calculate each variable offsets. It can be improved later.
- fields.setDim(0);
-
- unsigned offset = structsize;
- for (size_t i = 0; i < members->length; i++)
- {
- Dsymbol *s = (*members)[i];
- s->setFieldOffset(this, &offset, false);
- }
-
- sizeok = SIZEOKdone;
-
- // Calculate fields[i]->overlapped
- checkOverlappedFields();
-}
-
-/**************
- * Returns: true if there's a __monitor field
- */
-bool ClassDeclaration::hasMonitor()
-{
- return classKind == ClassKind::d;
-}
-
-/**********************************************************
- * fd is in the vtbl[] for this class.
- * Return 1 if function is hidden (not findable through search).
- */
-
-int isf(void *param, Dsymbol *s)
-{
- FuncDeclaration *fd = s->isFuncDeclaration();
- if (!fd)
- return 0;
- //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars());
- return (RootObject *)param == fd;
-}
-
-bool ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
-{
- //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toPrettyChars());
- Dsymbol *s = search(Loc(), fd->ident, IgnoreAmbiguous | IgnoreErrors);
- if (!s)
- {
- //printf("not found\n");
- /* Because, due to a hack, if there are multiple definitions
- * of fd->ident, NULL is returned.
- */
- return false;
- }
- s = s->toAlias();
- OverloadSet *os = s->isOverloadSet();
- if (os)
- {
- for (size_t i = 0; i < os->a.length; i++)
- {
- Dsymbol *s2 = os->a[i];
- FuncDeclaration *f2 = s2->isFuncDeclaration();
- if (f2 && overloadApply(f2, (void *)fd, &isf))
- return false;
- }
- return true;
- }
- else
- {
- FuncDeclaration *fdstart = s->isFuncDeclaration();
- //printf("%s fdstart = %p\n", s->kind(), fdstart);
- if (overloadApply(fdstart, (void *)fd, &isf))
- return false;
-
- return !fd->parent->isTemplateMixin();
- }
-}
-
-/****************
- * Find virtual function matching identifier and type.
- * Used to build virtual function tables for interface implementations.
- */
-
-FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
-{
- //printf("ClassDeclaration::findFunc(%s, %s) %s\n", ident->toChars(), tf->toChars(), toChars());
- FuncDeclaration *fdmatch = NULL;
- FuncDeclaration *fdambig = NULL;
-
- ClassDeclaration *cd = this;
- Dsymbols *vtbl = &cd->vtbl;
- while (1)
- {
- for (size_t i = 0; i < vtbl->length; i++)
- {
- FuncDeclaration *fd = (*vtbl)[i]->isFuncDeclaration();
- if (!fd)
- continue; // the first entry might be a ClassInfo
-
- //printf("\t[%d] = %s\n", i, fd->toChars());
- if (ident == fd->ident &&
- fd->type->covariant(tf) == 1)
- {
- //printf("fd->parent->isClassDeclaration() = %p\n", fd->parent->isClassDeclaration());
- if (!fdmatch)
- goto Lfd;
- if (fd == fdmatch)
- goto Lfdmatch;
-
- {
- // Function type matcing: exact > covariant
- MATCH m1 = tf->equals(fd ->type) ? MATCHexact : MATCHnomatch;
- MATCH m2 = tf->equals(fdmatch->type) ? MATCHexact : MATCHnomatch;
- if (m1 > m2)
- goto Lfd;
- else if (m1 < m2)
- goto Lfdmatch;
- }
-
- {
- MATCH m1 = (tf->mod == fd ->type->mod) ? MATCHexact : MATCHnomatch;
- MATCH m2 = (tf->mod == fdmatch->type->mod) ? MATCHexact : MATCHnomatch;
- if (m1 > m2)
- goto Lfd;
- else if (m1 < m2)
- goto Lfdmatch;
- }
-
- {
- // The way of definition: non-mixin > mixin
- MATCH m1 = fd ->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
- MATCH m2 = fdmatch->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
- if (m1 > m2)
- goto Lfd;
- else if (m1 < m2)
- goto Lfdmatch;
- }
-
- fdambig = fd;
- //printf("Lambig fdambig = %s %s [%s]\n", fdambig->toChars(), fdambig->type->toChars(), fdambig->loc.toChars());
- continue;
-
- Lfd:
- fdmatch = fd;
- fdambig = NULL;
- //printf("Lfd fdmatch = %s %s [%s]\n", fdmatch->toChars(), fdmatch->type->toChars(), fdmatch->loc.toChars());
- continue;
-
- Lfdmatch:
- continue;
- }
- //else printf("\t\t%d\n", fd->type->covariant(tf));
- }
- if (!cd)
- break;
- vtbl = &cd->vtblFinal;
- cd = cd->baseClass;
- }
-
- if (fdambig)
- error("ambiguous virtual function %s", fdambig->toChars());
- return fdmatch;
-}
-
-/****************************************
- */
-
-bool ClassDeclaration::isCOMclass() const
-{
- return com;
-}
-
-bool ClassDeclaration::isCOMinterface() const
-{
- return false;
-}
-
-bool ClassDeclaration::isCPPclass() const
-{
- return classKind == ClassKind::cpp;
-}
-
-bool ClassDeclaration::isCPPinterface() const
-{
- return false;
-}
-
-
-/****************************************
- */
-
-bool ClassDeclaration::isAbstract()
-{
- if (isabstract != ABSfwdref)
- return isabstract == ABSyes;
-
- /* Bugzilla 11169: Resolve forward references to all class member functions,
- * and determine whether this class is abstract.
- */
- struct SearchAbstract
- {
- static int fp(Dsymbol *s, void *)
- {
- FuncDeclaration *fd = s->isFuncDeclaration();
- if (!fd)
- return 0;
- if (fd->storage_class & STCstatic)
- return 0;
-
- if (fd->_scope)
- dsymbolSemantic(fd, NULL);
-
- if (fd->isAbstract())
- return 1;
- return 0;
- }
- };
-
- for (size_t i = 0; i < members->length; i++)
- {
- Dsymbol *s = (*members)[i];
- if (s->apply(&SearchAbstract::fp, this))
- {
- isabstract = ABSyes;
- return true;
- }
- }
-
- /* Iterate inherited member functions and check their abstract attribute.
- */
- for (size_t i = 1; i < vtbl.length; i++)
- {
- FuncDeclaration *fd = vtbl[i]->isFuncDeclaration();
- //if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd->loc.toChars(), fd->toChars());
- if (!fd || fd->isAbstract())
- {
- isabstract = ABSyes;
- return true;
- }
- }
-
- isabstract = ABSno;
- return false;
-}
-
-
-/****************************************
- * Determine if slot 0 of the vtbl[] is reserved for something else.
- * For class objects, yes, this is where the classinfo ptr goes.
- * For COM interfaces, no.
- * For non-COM interfaces, yes, this is where the Interface ptr goes.
- * Returns:
- * 0 vtbl[0] is first virtual function pointer
- * 1 vtbl[0] is classinfo/interfaceinfo pointer
- */
-
-int ClassDeclaration::vtblOffset() const
-{
- return classKind == ClassKind::cpp ? 0 : 1;
-}
-
-/****************************************
- */
-
-const char *ClassDeclaration::kind() const
-{
- return "class";
-}
-
-/****************************************
- */
-
-void ClassDeclaration::addLocalClass(ClassDeclarations *aclasses)
-{
- aclasses->push(this);
-}
-
-/********************************* InterfaceDeclaration ****************************/
-
-InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses)
- : ClassDeclaration(loc, id, baseclasses, NULL, false)
-{
- if (id == Id::IUnknown) // IUnknown is the root of all COM interfaces
- {
- com = true;
- classKind = ClassKind::cpp; // IUnknown is also a C++ interface
- }
-}
-
-Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s)
-{
- InterfaceDeclaration *id =
- s ? (InterfaceDeclaration *)s
- : new InterfaceDeclaration(loc, ident, NULL);
- return ClassDeclaration::syntaxCopy(id);
-}
-
-Scope *InterfaceDeclaration::newScope(Scope *sc)
-{
- Scope *sc2 = ClassDeclaration::newScope(sc);
- if (com)
- sc2->linkage = LINKwindows;
- else if (classKind == ClassKind::cpp)
- sc2->linkage = LINKcpp;
- else if (classKind == ClassKind::objc)
- sc2->linkage = LINKobjc;
- return sc2;
-}
-
-/*******************************************
- * Determine if 'this' is a base class of cd.
- * (Actually, if it is an interface supported by cd)
- * Output:
- * *poffset offset to start of class
- * OFFSET_RUNTIME must determine offset at runtime
- * Returns:
- * false not a base
- * true is a base
- */
-
-bool InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
-{
- //printf("%s.InterfaceDeclaration::isBaseOf(cd = '%s')\n", toChars(), cd->toChars());
- assert(!baseClass);
- for (size_t j = 0; j < cd->interfaces.length; j++)
- {
- BaseClass *b = cd->interfaces.ptr[j];
-
- //printf("\tX base %s\n", b->sym->toChars());
- if (this == b->sym)
- {
- //printf("\tfound at offset %d\n", b->offset);
- if (poffset)
- {
- // don't return incorrect offsets https://issues.dlang.org/show_bug.cgi?id=16980
- *poffset = cd->sizeok == SIZEOKdone ? b->offset : OFFSET_FWDREF;
- }
- //printf("\tfound at offset %d\n", b->offset);
- return true;
- }
- if (isBaseOf(b, poffset))
- return true;
- }
-
- if (cd->baseClass && isBaseOf(cd->baseClass, poffset))
- return true;
-
- if (poffset)
- *poffset = 0;
- return false;
-}
-
-bool InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset)
-{
- //printf("%s.InterfaceDeclaration::isBaseOf(bc = '%s')\n", toChars(), bc->sym->toChars());
- for (size_t j = 0; j < bc->baseInterfaces.length; j++)
- {
- BaseClass *b = &bc->baseInterfaces.ptr[j];
-
- //printf("\tY base %s\n", b->sym->toChars());
- if (this == b->sym)
- {
- //printf("\tfound at offset %d\n", b->offset);
- if (poffset)
- {
- *poffset = b->offset;
- }
- return true;
- }
- if (isBaseOf(b, poffset))
- {
- return true;
- }
- }
- if (poffset)
- *poffset = 0;
- return false;
-}
-
-/****************************************
- * Determine if slot 0 of the vtbl[] is reserved for something else.
- * For class objects, yes, this is where the ClassInfo ptr goes.
- * For COM interfaces, no.
- * For non-COM interfaces, yes, this is where the Interface ptr goes.
- */
-
-int InterfaceDeclaration::vtblOffset() const
-{
- if (isCOMinterface() || isCPPinterface())
- return 0;
- return 1;
-}
-
-bool InterfaceDeclaration::isCOMinterface() const
-{
- return com;
-}
-
-bool InterfaceDeclaration::isCPPinterface() const
-{
- return classKind == ClassKind::cpp;
-}
-
-/*******************************************
- */
-
-const char *InterfaceDeclaration::kind() const
-{
- return "interface";
-}
-
-
-/******************************** BaseClass *****************************/
-
-BaseClass::BaseClass()
-{
- this->type = NULL;
- this->sym = NULL;
- this->offset = 0;
-
- this->baseInterfaces.length = 0;
- this->baseInterfaces.ptr = NULL;
-}
-
-BaseClass::BaseClass(Type *type)
-{
- //printf("BaseClass(this = %p, '%s')\n", this, type->toChars());
- this->type = type;
- this->sym = NULL;
- this->offset = 0;
-
- this->baseInterfaces.length = 0;
- this->baseInterfaces.ptr = NULL;
-}
-
-/****************************************
- * Fill in vtbl[] for base class based on member functions of class cd.
- * Input:
- * vtbl if !=NULL, fill it in
- * newinstance !=0 means all entries must be filled in by members
- * of cd, not members of any base classes of cd.
- * Returns:
- * true if any entries were filled in by members of cd (not exclusively
- * by base classes)
- */
-
-bool BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance)
-{
- bool result = false;
-
- //printf("BaseClass::fillVtbl(this='%s', cd='%s')\n", sym->toChars(), cd->toChars());
- if (vtbl)
- vtbl->setDim(sym->vtbl.length);
-
- // first entry is ClassInfo reference
- for (size_t j = sym->vtblOffset(); j < sym->vtbl.length; j++)
- {
- FuncDeclaration *ifd = sym->vtbl[j]->isFuncDeclaration();
- FuncDeclaration *fd;
- TypeFunction *tf;
-
- //printf(" vtbl[%d] is '%s'\n", j, ifd ? ifd->toChars() : "null");
-
- assert(ifd);
- // Find corresponding function in this class
- tf = ifd->type->toTypeFunction();
- fd = cd->findFunc(ifd->ident, tf);
- if (fd && !fd->isAbstract())
- {
- //printf(" found\n");
- // Check that calling conventions match
- if (fd->linkage != ifd->linkage)
- fd->error("linkage doesn't match interface function");
-
- // Check that it is current
- //printf("newinstance = %d fd->toParent() = %s ifd->toParent() = %s\n",
- //newinstance, fd->toParent()->toChars(), ifd->toParent()->toChars());
- if (newinstance && fd->toParent() != cd && ifd->toParent() == sym)
- cd->error("interface function `%s` is not implemented", ifd->toFullSignature());
-
- if (fd->toParent() == cd)
- result = true;
- }
- else
- {
- //printf(" not found %p\n", fd);
- // BUG: should mark this class as abstract?
- if (!cd->isAbstract())
- cd->error("interface function `%s` is not implemented", ifd->toFullSignature());
-
- fd = NULL;
- }
- if (vtbl)
- (*vtbl)[j] = fd;
- }
-
- return result;
-}
-
-void BaseClass::copyBaseInterfaces(BaseClasses *vtblInterfaces)
-{
- //printf("+copyBaseInterfaces(), %s\n", sym->toChars());
-// if (baseInterfaces.length)
-// return;
-
- baseInterfaces.length = sym->interfaces.length;
- baseInterfaces.ptr = (BaseClass *)mem.xcalloc(baseInterfaces.length, sizeof(BaseClass));
-
- //printf("%s.copyBaseInterfaces()\n", sym->toChars());
- for (size_t i = 0; i < baseInterfaces.length; i++)
- {
- void *pb = &baseInterfaces.ptr[i];
- BaseClass *b2 = sym->interfaces.ptr[i];
-
- assert(b2->vtbl.length == 0); // should not be filled yet
- BaseClass *b = (BaseClass *)memcpy(pb, b2, sizeof(BaseClass));
-
- if (i) // single inheritance is i==0
- vtblInterfaces->push(b); // only need for M.I.
- b->copyBaseInterfaces(vtblInterfaces);
- }
- //printf("-copyBaseInterfaces\n");
-}