From patchwork Tue Nov 30 14:17:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 48288 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 411D33858D28 for ; Tue, 30 Nov 2021 14:18:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 411D33858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638281937; bh=q4KBGyHkH8IJWuvbVuHbMAhNhIegMlpKfl0+x8TfIJQ=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=jNz0RnG2gU5qYk95JVcTdY0eSUCQ5gHQmGq8pv5TbksLRJq1XPFIsdlbNm3rCeN4/ MJ09QOsvfkGUrbrwQXZCjCSVbt+woQpZsFa19XO0nBZh/yBO6B8MLrt4MTI8zXbJ+X g/miIkJnvZKb2IXon6w8hcMOpjUHnJz6xihL2nks= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [80.241.56.151]) by sourceware.org (Postfix) with ESMTPS id 437A6385801F for ; Tue, 30 Nov 2021 14:18:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 437A6385801F Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:105:465:1:1:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4J3PSr5YM2zQjcN; Tue, 30 Nov 2021 15:18:04 +0100 (CET) X-Virus-Scanned: amavisd-new at heinlein-support.de To: gcc-patches@gcc.gnu.org Subject: [committed 02/19] d: Update D front-end to build with latest version Date: Tue, 30 Nov 2021 15:17:54 +0100 Message-Id: <20211130141754.576528-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Spam-Status: No, score=-14.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch updates the code generator to work with the new front-end interface. Bootstrapped, regression tested, and committed to mainline. Regards, Iain. --- gcc/d/ChangeLog: * 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. * ChangeLog.d: New file. * d-frontend.h: New file. --- gcc/d/Make-lang.in | 132 ++++++++++--------- gcc/d/config-lang.in | 2 + gcc/d/d-attribs.cc | 1 + gcc/d/d-builtins.cc | 52 ++++---- gcc/d/d-codegen.cc | 78 ++++++++---- gcc/d/d-compiler.cc | 49 ++------ gcc/d/d-convert.cc | 86 +++++++------ gcc/d/d-diagnostic.cc | 75 +---------- gcc/d/d-frontend.cc | 119 +----------------- gcc/d/d-frontend.h | 37 ++++++ gcc/d/d-incpath.cc | 5 +- gcc/d/d-lang.cc | 287 ++++++++++++++++++++++++++++++------------ gcc/d/d-longdouble.cc | 6 - gcc/d/d-system.h | 52 -------- gcc/d/d-target.cc | 112 ++++++++++------- gcc/d/d-tree.h | 1 - gcc/d/decl.cc | 166 +++++++++++++++++------- gcc/d/expr.cc | 267 +++++++++++++++++---------------------- gcc/d/imports.cc | 8 +- gcc/d/intrinsics.cc | 10 +- gcc/d/intrinsics.def | 97 +++++++------- gcc/d/lang.opt | 165 ++++++++++++++++++++++-- gcc/d/modules.cc | 22 ++-- gcc/d/runtime.def | 30 ++--- gcc/d/toir.cc | 101 +++------------ gcc/d/typeinfo.cc | 60 +++++---- gcc/d/types.cc | 74 +++++------ gcc/d/verstr.h | 1 - 28 files changed, 1082 insertions(+), 1013 deletions(-) create mode 100644 gcc/d/d-frontend.h delete mode 100644 gcc/d/verstr.h diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index 1ed813443b3..4c0a0321eba 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -46,30 +46,61 @@ gdc-cross$(exeext): gdc$(exeext) -rm -f gdc-cross$(exeext) cp gdc$(exeext) gdc-cross$(exeext) -# Filter out pedantic and virtual overload warnings. -d-warn = $(filter-out -pedantic -Woverloaded-virtual, $(STRICT_WARN)) - -# Also filter out warnings for missing format attributes in the D Frontend. -DMD_WARN_CXXFLAGS = $(filter-out -Wmissing-format-attribute, $(WARN_CXXFLAGS)) -DMD_COMPILE = $(subst $(WARN_CXXFLAGS), $(DMD_WARN_CXXFLAGS), $(COMPILE)) +# Use strict warnings. +d-warn = $(STRICT_WARN) + +# D compiler and flags for building the front-end. +ifeq ($(TREECHECKING),) +CHECKING_DFLAGS = -frelease +else +CHECKING_DFLAGS = +endif +WARN_DFLAGS = -Wall -Wdeprecated $(NOCOMMON_FLAG) + +ALL_DFLAGS = $(DFLAGS-$@) $(GDCFLAGS) -fversion=IN_GCC $(CHECKING_DFLAGS) \ + $(PICFLAG) $(ALIASING_FLAGS) $(COVERAGE_FLAGS) $(WARN_DFLAGS) + +DCOMPILE.base = $(GDC) $(NO_PIE_CFLAGS) -c $(ALL_DFLAGS) -o $@ +DCOMPILE = $(DCOMPILE.base) -MT $@ -MMD -MP -MF $(@D)/$(DEPDIR)/$(*F).TPo +DPOSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(*F).TPo $(@D)/$(DEPDIR)/$(*F).Po +DLINKER = $(GDC) $(NO_PIE_FLAG) -lstdc++ + +# Like LINKER, but use a mutex for serializing front end links. +ifeq (@DO_LINK_MUTEX@,true) +DLLINKER = $(SHELL) $(srcdir)/lock-and-run.sh linkfe.lck $(DLINKER) +else +DLLINKER = $(DLINKER) +endif # D Frontend object files. D_FRONTEND_OBJS = \ d/aav.o \ d/access.o \ + d/aggregate.o \ d/aliasthis.o \ d/apply.o \ + d/array.o \ d/arrayop.o \ + d/arraytypes.o \ d/attrib.o \ + d/ast_node.o \ + d/astcodegen.o \ + d/astenums.o \ + d/bitarray.o \ d/blockexit.o \ + d/builtin.o \ d/canthrow.o \ - d/checkedint.o \ d/chkformat.o \ d/clone.o \ + d/compiler.o \ + d/complex.o \ d/cond.o \ d/constfold.o \ + d/cparse.o \ d/cppmangle.o \ d/ctfeexpr.o \ + d/ctfloat.o \ + d/ctorflow.o \ d/dcast.o \ d/dclass.o \ d/declaration.o \ @@ -86,32 +117,49 @@ D_FRONTEND_OBJS = \ d/dsymbol.o \ d/dsymbolsem.o \ d/dtemplate.o \ + d/dtoh.o \ d/dversion.o \ d/entity.o \ + d/errors.o \ d/escape.o \ d/expression.o \ d/expressionsem.o \ d/file.o \ d/filename.o \ + d/foreachvar.o \ d/func.o \ + d/globals.o \ + d/gluelayer.o \ + d/hash.o \ d/hdrgen.o \ d/iasm.o \ d/iasmgcc.o \ + d/id.o \ d/identifier.o \ + d/impcnvtab.o \ d/imphint.o \ d/init.o \ d/initsem.o \ + d/inline.o \ d/intrange.o \ d/json.o \ + d/lambdacomp.o \ d/lexer.o \ + d/longdouble.o \ d/mtype.o \ d/nogc.o \ d/nspace.o \ + d/ob.o \ d/objc.o \ d/opover.o \ d/optimize.o \ d/outbuffer.o \ d/parse.o \ + d/parsetimevisitor.o \ + d/permissivevisitor.o \ + d/port.o \ + d/printast.o \ + d/region.o \ d/rmem.o \ d/rootobject.o \ d/safe.o \ @@ -121,20 +169,23 @@ D_FRONTEND_OBJS = \ d/sideeffect.o \ d/speller.o \ d/statement.o \ + d/statement_rewrite_walker.o \ d/statementsem.o \ d/staticassert.o \ d/staticcond.o \ + d/stmtstate.o \ + d/string.o \ d/stringtable.o \ + d/target.o \ d/templateparamsem.o \ d/tokens.o \ d/traits.o \ + d/transitivevisitor.o \ d/typesem.o \ + d/typinf.o \ d/utf.o \ - d/utils.o - -# D Frontend generated files. -D_GENERATED_SRCS = d/id.c d/id.h d/impcnvtab.c -D_GENERATED_OBJS = d/id.o d/impcnvtab.o + d/utils.o \ + d/visitor.o # Language-specific object files for D. D_OBJS = \ @@ -163,13 +214,13 @@ D_OBJS = \ d/types.o # All language-specific object files for D. -D_ALL_OBJS = $(D_FRONTEND_OBJS) $(D_GENERATED_OBJS) $(D_OBJS) $(D_TARGET_OBJS) +D_ALL_OBJS = $(D_FRONTEND_OBJS) $(D_OBJS) $(D_TARGET_OBJS) d_OBJS = $(D_ALL_OBJS) d/d-spec.o d21$(exeext): $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS) $(d.prev) @$(call LINK_PROGRESS,$(INDEX.d),start) - +$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ + +$(DLLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -static-libphobos -o $@ \ $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS) @$(call LINK_PROGRESS,$(INDEX.d),end) @@ -221,7 +272,7 @@ d.srcextra: d.tags: force cd $(srcdir)/d; \ - $(ETAGS) -o TAGS.sub *.c *.cc *.h dmd/*.c dmd/*.h dmd/root/*.h dmd/root/*.c; \ + $(ETAGS) -o TAGS.sub *.c *.cc *.h dmd/*.h dmd/root/*.h; \ $(ETAGS) --include TAGS.sub --include ../TAGS.sub d.man: doc/gdc.1 @@ -313,8 +364,6 @@ d.uninstall: d.mostlyclean: -rm -f d/*$(objext) -rm -f d/*$(coverageexts) - -rm -f $(D_GENERATED_SRCS) - -rm -f d/idgen$(build_exeext) d/impcnvgen$(build_exeext) -rm -f gdc$(exeext) gdc-cross$(exeext) d21$(exeext) d.clean: d.distclean: @@ -337,48 +386,13 @@ d.stagefeedback: stagefeedback-start -mv d/*$(objext) stagefeedback/d # Include the dfrontend and build directories for headers. -D_INCLUDES = -I$(srcdir)/d -I$(srcdir)/d/dmd -Id - -CFLAGS-d/id.o += $(D_INCLUDES) -CFLAGS-d/impcnvtab.o += $(D_INCLUDES) +D_INCLUDES = -I$(srcdir)/d -J$(srcdir)/d/dmd -J$(srcdir)/d/dmd/res # Override build rules for D frontend. -d/%.o: d/dmd/%.c $(D_GENERATED_SRCS) - $(DMD_COMPILE) $(D_INCLUDES) $< - $(POSTCOMPILE) - -d/%.o: d/dmd/root/%.c $(D_GENERATED_SRCS) - $(DMD_COMPILE) $(D_INCLUDES) $< - $(POSTCOMPILE) - -# Generated programs. -d/idgen$(build_exeext): d/idgen.dmdgen.o $(BUILD_LIBDEPS) - +$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) -o $@ \ - $(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS) - -d/impcnvgen$(build_exeext): d/impcnvgen.dmdgen.o $(BUILD_LIBDEPS) - +$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) -o $@ \ - $(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS) - -# Generated sources. -d/id.c: d/idgen$(build_exeext) - cd d && ./idgen$(build_exeext) - -# idgen also generates id.h; just verify it exists. -d/id.h: d/id.c - -d/impcnvtab.c: d/impcnvgen$(build_exeext) - cd d && ./impcnvgen$(build_exeext) - -# Compile the generator programs. -d/%.dmdgen.o: $(srcdir)/d/dmd/%.c - $(COMPILER_FOR_BUILD) -c $(BUILD_COMPILERFLAGS) $(D_INCLUDES) \ - $(BUILD_CPPFLAGS) -o $@ $< - -# Header dependencies for the generator programs. -D_SYSTEM_H = d/dmd/root/dsystem.h d/d-system.h - -d/idgen.dmdgen.o: d/dmd/idgen.c $(D_SYSTEM_H) $(BCONFIG_H) $(SYSTEM_H) +d/%.o: d/dmd/%.d + $(DCOMPILE) $(D_INCLUDES) $< + $(DPOSTCOMPILE) -d/impcnvgen.dmdgen.o: d/dmd/impcnvgen.c d/dmd/mtype.h $(D_SYSTEM_H) \ - $(BCONFIG_H) $(SYSTEM_H) +d/%.o: d/dmd/root/%.d + $(DCOMPILE) $(D_INCLUDES) $< + $(DPOSTCOMPILE) diff --git a/gcc/d/config-lang.in b/gcc/d/config-lang.in index 0568b8da1de..00a71d6b8b5 100644 --- a/gcc/d/config-lang.in +++ b/gcc/d/config-lang.in @@ -19,10 +19,12 @@ # We define several parameters used by configure: # # language - name of language as it would appear in $(LANGUAGES) +# boot_language - "yes" if we need to build this language in stage1 # compilers - value to add to $(COMPILERS) language="d" +boot_language=yes compilers="d21\$(exeext)" phobos_target_deps="target-zlib target-libbacktrace" diff --git a/gcc/d/d-attribs.cc b/gcc/d/d-attribs.cc index b79cf96f55c..04b9791ab1b 100644 --- a/gcc/d/d-attribs.cc +++ b/gcc/d/d-attribs.cc @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "dmd/attrib.h" #include "dmd/declaration.h" +#include "dmd/expression.h" #include "dmd/module.h" #include "dmd/mtype.h" #include "dmd/template.h" diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc index 33347a14c67..ab3a950689f 100644 --- a/gcc/d/d-builtins.cc +++ b/gcc/d/d-builtins.cc @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "stor-layout.h" #include "d-tree.h" +#include "d-frontend.h" #include "d-target.h" @@ -98,7 +99,7 @@ build_frontend_type (tree type) if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node) return Type::tchar->addMod (dtype->mod)->pointerTo ()->addMod (mod); - if (dtype->ty == Tfunction) + if (dtype->ty == TY::Tfunction) return (TypePointer::create (dtype))->addMod (mod); return dtype->pointerTo ()->addMod (mod); @@ -130,7 +131,7 @@ build_frontend_type (tree type) /* For now, skip support for cent/ucent until the frontend has better support for handling it. */ - for (size_t i = Tint8; i <= Tuns64; i++) + for (size_t i = (size_t) TY::Tint8; i <= (size_t) TY::Tuns64; i++) { dtype = Type::basic[i]; @@ -148,7 +149,7 @@ build_frontend_type (tree type) { unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)); - for (size_t i = Tfloat32; i <= Tfloat80; i++) + for (size_t i = (size_t) TY::Tfloat32; i <= (size_t) TY::Tfloat80; i++) { dtype = Type::basic[i]; @@ -164,7 +165,8 @@ build_frontend_type (tree type) case COMPLEX_TYPE: { unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)); - for (size_t i = Tcomplex32; i <= Tcomplex80; i++) + for (size_t i = (size_t) TY::Tcomplex32; i <= (size_t) TY::Tcomplex80; + i++) { dtype = Type::basic[i]; @@ -235,7 +237,7 @@ build_frontend_type (tree type) sdecl->structsize = int_size_in_bytes (type); sdecl->alignsize = TYPE_ALIGN_UNIT (type); sdecl->alignment = STRUCTALIGN_DEFAULT; - sdecl->sizeok = SIZEOKdone; + sdecl->sizeok = Sizeok::done; sdecl->type = (TypeStruct::create (sdecl))->addMod (mod); sdecl->type->ctype = type; sdecl->type->merge2 (); @@ -243,7 +245,7 @@ build_frontend_type (tree type) /* Add both named and anonymous fields as members of the struct. Anonymous fields still need a name in D, so call them "__pad%u". */ unsigned anonfield_id = 0; - sdecl->members = new Dsymbols; + sdecl->members = d_gc_malloc (); for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { @@ -253,7 +255,6 @@ build_frontend_type (tree type) /* Drop any field types that got cached before the conversion of this record type failed. */ builtin_converted_decls.truncate (saved_builtin_decls_length); - delete sdecl->members; return NULL; } @@ -292,7 +293,7 @@ build_frontend_type (tree type) tree parms = TYPE_ARG_TYPES (type); VarArg varargs_p = VARARGvariadic; - Parameters *args = new Parameters; + Parameters *args = d_gc_malloc (); args->reserve (list_length (parms)); /* Attempt to convert all parameter types. */ @@ -318,7 +319,6 @@ build_frontend_type (tree type) /* Drop any parameter types that got cached before the conversion of this function type failed. */ builtin_converted_decls.truncate (saved_builtin_decls_length); - delete args; return NULL; } @@ -329,7 +329,7 @@ build_frontend_type (tree type) have no named parameters, and so can't be represented in D. */ if (args->length != 0 || varargs_p == VARARGnone) { - dtype = TypeFunction::create (args, dtype, varargs_p, LINKc); + dtype = TypeFunction::create (args, dtype, varargs_p, LINK::c); return dtype->addMod (mod); } } @@ -386,7 +386,7 @@ d_eval_constant_expression (const Loc &loc, tree cst) else if (code == VECTOR_CST) { dinteger_t nunits = VECTOR_CST_NELTS (cst).to_constant (); - Expressions *elements = new Expressions; + Expressions *elements = d_gc_malloc (); elements->setDim (nunits); for (size_t i = 0; i < nunits; i++) @@ -520,7 +520,7 @@ build_alias_declaration (const char *alias, Type *type) void d_build_builtins_module (Module *m) { - Dsymbols *members = new Dsymbols; + Dsymbols *members = d_gc_malloc (); tree decl; for (size_t i = 0; vec_safe_iterate (gcc_builtins_functions, i, &decl); ++i) @@ -543,16 +543,16 @@ d_build_builtins_module (Module *m) flag_unsafe_math_optimizations. - Built-ins never use the GC or raise a D exception, and so are always marked as `nothrow' and `@nogc'. */ - tf->purity = DECL_PURE_P (decl) ? PUREstrong - : TREE_READONLY (decl) ? PUREconst - : DECL_IS_NOVOPS (decl) ? PUREweak - : !DECL_ASSEMBLER_NAME_SET_P (decl) ? PUREweak - : PUREimpure; - tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUSTsafe - : TREE_NOTHROW (decl) ? TRUSTtrusted - : TRUSTsystem; - tf->isnothrow = true; - tf->isnogc = true; + tf->purity = DECL_PURE_P (decl) ? PURE::strong + : TREE_READONLY (decl) ? PURE::const_ + : DECL_IS_NOVOPS (decl) ? PURE::weak + : !DECL_ASSEMBLER_NAME_SET_P (decl) ? PURE::weak + : PURE::impure; + tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUST::safe + : TREE_NOTHROW (decl) ? TRUST::trusted + : TRUST::system; + tf->isnothrow (true); + tf->isnogc (true); FuncDeclaration *func = FuncDeclaration::create (Loc (), Loc (), @@ -560,7 +560,7 @@ d_build_builtins_module (Module *m) STCextern, tf); DECL_LANG_SPECIFIC (decl) = build_lang_decl (func); func->csym = decl; - func->builtin = BUILTINgcc; + func->builtin = BUILTIN::gcc; members->push (func); } @@ -660,7 +660,7 @@ d_build_builtins_module (Module *m) members->push (build_alias_declaration ("__builtin_unwind_uint", t)); } - m->members->push (LinkDeclaration::create (LINKc, members)); + m->members->push (LinkDeclaration::create (Loc (), LINK::c, members)); } /* Search for any `extern(C)' functions that match any known GCC library builtin @@ -700,7 +700,7 @@ maybe_set_builtin_1 (Dsymbol *d) /* Found a match, tell the frontend this is a builtin. */ DECL_LANG_SPECIFIC (t) = build_lang_decl (fd); fd->csym = t; - fd->builtin = BUILTINgcc; + fd->builtin = BUILTIN::gcc; return; } } @@ -858,7 +858,7 @@ d_build_d_type_nodes (void) /* Calling build_ctype() links the front-end Type to the GCC node, and sets the TYPE_NAME to the D language type. */ - for (unsigned ty = 0; ty < TMAX; ty++) + for (unsigned ty = 0; ty < (unsigned) TY::TMAX; ty++) { if (Type::basic[ty] != NULL) build_ctype (Type::basic[ty]); diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index e63365055d3..403e3c74377 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -76,7 +76,7 @@ d_decl_context (Dsymbol *dsym) but only for extern(D) symbols. */ if (parent->isModule ()) { - if ((decl != NULL && decl->linkage != LINKd) + if ((decl != NULL && decl->linkage != LINK::d) || (ad != NULL && ad->classKind != ClassKind::d)) return NULL_TREE; @@ -131,7 +131,7 @@ declaration_reference_p (Declaration *decl) Type *tb = decl->type->toBasetype (); /* Declaration is a reference type. */ - if (tb->ty == Treference || decl->storage_class & (STCout | STCref)) + if (tb->ty == TY::Treference || decl->storage_class & (STCout | STCref)) return true; return false; @@ -146,7 +146,7 @@ declaration_type (Declaration *decl) if (decl->storage_class & STClazy) { TypeFunction *tf = TypeFunction::create (NULL, decl->type, - VARARGnone, LINKd); + VARARGnone, LINK::d); TypeDelegate *t = TypeDelegate::create (tf); return build_ctype (t->merge2 ()); } @@ -181,7 +181,7 @@ parameter_reference_p (Parameter *arg) Type *tb = arg->type->toBasetype (); /* Parameter is a reference type. */ - if (tb->ty == Treference || arg->storageClass & (STCout | STCref)) + if (tb->ty == TY::Treference || arg->storageClass & (STCout | STCref)) return true; return false; @@ -196,7 +196,7 @@ parameter_type (Parameter *arg) if (arg->storageClass & STClazy) { TypeFunction *tf = TypeFunction::create (NULL, arg->type, - VARARGnone, LINKd); + VARARGnone, LINK::d); TypeDelegate *t = TypeDelegate::create (tf); return build_ctype (t->merge2 ()); } @@ -319,10 +319,10 @@ get_array_length (tree exp, Type *type) switch (tb->ty) { - case Tsarray: + case TY::Tsarray: return size_int (tb->isTypeSArray ()->dim->toUInteger ()); - case Tarray: + case TY::Tarray: return d_array_length (exp); default: @@ -411,7 +411,7 @@ build_delegate_cst (tree method, tree object, Type *type) tree ctype; Type *tb = type->toBasetype (); - if (tb->ty == Tdelegate) + if (tb->ty == TY::Tdelegate) ctype = build_ctype (type); else { @@ -464,11 +464,11 @@ build_typeof_null_value (Type *type) tree value; /* For dynamic arrays, set length and pointer fields to zero. */ - if (tb->ty == Tarray) + if (tb->ty == TY::Tarray) value = d_array_value (build_ctype (type), size_int (0), null_pointer_node); /* For associative arrays, set the pointer field to null. */ - else if (tb->ty == Taarray) + else if (tb->ty == TY::Taarray) { tree ctype = build_ctype (type); gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype)); @@ -478,7 +478,7 @@ build_typeof_null_value (Type *type) } /* For delegates, set the frame and function pointer fields to null. */ - else if (tb->ty == Tdelegate) + else if (tb->ty == TY::Tdelegate) value = build_delegate_cst (null_pointer_node, null_pointer_node, type); /* Simple zero constant for all other types. */ @@ -882,7 +882,9 @@ identity_compare_p (StructDeclaration *sd) } /* Check for types that may have padding. */ - if ((tb->ty == Tcomplex80 || tb->ty == Tfloat80 || tb->ty == Timaginary80) + if ((tb->ty == TY::Tcomplex80 + || tb->ty == TY::Tfloat80 + || tb->ty == TY::Timaginary80) && target.realpad != 0) return false; @@ -960,12 +962,12 @@ lower_struct_comparison (tree_code code, StructDeclaration *sd, /* Compare inner data structures. */ tcmp = lower_struct_comparison (code, ts->sym, t1ref, t2ref); } - else if (type->ty != Tvector && type->isintegral ()) + else if (type->ty != TY::Tvector && type->isintegral ()) { /* Integer comparison, no special handling required. */ tcmp = build_boolop (code, t1ref, t2ref); } - else if (type->ty != Tvector && type->isfloating ()) + else if (type->ty != TY::Tvector && type->isfloating ()) { /* Floating-point comparison, don't compare padding in type. */ if (!type->iscomplex ()) @@ -1839,7 +1841,7 @@ static tree build_filename_from_loc (const Loc &loc) { const char *filename = loc.filename - ? loc.filename : d_function_chain->module->srcfile->toChars (); + ? loc.filename : d_function_chain->module->srcfile.toChars (); unsigned length = strlen (filename); tree str = build_string (length, filename); @@ -1862,7 +1864,6 @@ build_assert_call (const Loc &loc, libcall_fn libcall, tree msg) { case LIBCALL_ASSERT_MSG: case LIBCALL_UNITTEST_MSG: - case LIBCALL_SWITCH_ERROR: /* File location is passed as a D string. */ if (loc.filename) { @@ -1912,7 +1913,7 @@ build_array_bounds_call (const Loc &loc) /* Builds a bounds condition checking that INDEX is between 0 and LENGTH in the index expression IE. The condition returns the INDEX if true, or - throws a `RangeError`. */ + throws a `ArrayIndexError`. */ tree build_bounds_index_condition (IndexExp *ie, tree index, tree length) @@ -1927,7 +1928,16 @@ build_bounds_index_condition (IndexExp *ie, tree index, tree length) No need to check whether INDEX >= 0 as the front-end should have already taken care of implicit casts to unsigned. */ tree condition = fold_build2 (GE_EXPR, d_bool_type, index, length); - tree boundserr = build_array_bounds_call (ie->e2->loc); + tree boundserr; + + if (checkaction_trap_p ()) + boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0); + else + { + boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4, + build_filename_from_loc (ie->e2->loc), + size_int (ie->e2->loc.linnum), index, length); + } return build_condition (TREE_TYPE (index), condition, boundserr, index); } @@ -1963,7 +1973,22 @@ build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length) if (condition != NULL_TREE) { - tree boundserr = build_array_bounds_call (se->loc); + tree boundserr; + + if (checkaction_trap_p ()) + { + boundserr = + build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0); + } + else + { + boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP, + Type::tvoid, 5, + build_filename_from_loc (se->loc), + size_int (se->loc.linnum), + lower, upper, length); + } + upper = build_condition (TREE_TYPE (upper), condition, boundserr, upper); } @@ -1993,9 +2018,9 @@ array_bounds_check (void) case CHECKENABLEsafeonly: /* For D2 safe functions only. */ fd = d_function_chain->function; - if (fd && fd->type->ty == Tfunction) + if (fd && fd->type->ty == TY::Tfunction) { - if (fd->type->isTypeFunction ()->trust == TRUSTsafe) + if (fd->type->isTypeFunction ()->trust == TRUST::safe) return true; } return false; @@ -2014,6 +2039,7 @@ checkaction_trap_p (void) switch (global.params.checkAction) { case CHECKACTION_D: + case CHECKACTION_context: return false; case CHECKACTION_C: @@ -2032,11 +2058,11 @@ TypeFunction * get_function_type (Type *t) { TypeFunction *tf = NULL; - if (t->ty == Tpointer) + if (t->ty == TY::Tpointer) t = t->nextOf ()->toBasetype (); - if (t->ty == Tfunction) + if (t->ty == TY::Tfunction) tf = t->isTypeFunction (); - else if (t->ty == Tdelegate) + else if (t->ty == TY::Tdelegate) tf = t->isTypeDelegate ()->next->isTypeFunction (); return tf; } @@ -2096,7 +2122,7 @@ d_build_call (TypeFunction *tf, tree callable, tree object, gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype)); gcc_assert (tf != NULL); - gcc_assert (tf->ty == Tfunction); + gcc_assert (tf->ty == TY::Tfunction); if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE) { @@ -2195,7 +2221,7 @@ d_build_call (TypeFunction *tf, tree callable, tree object, SET_EXPR_LOCATION (result, input_location); /* Enforce left to right evaluation. */ - if (tf->linkage == LINKd) + if (tf->linkage == LINK::d) CALL_EXPR_ARGS_ORDERED (result) = 1; result = maybe_expand_intrinsic (result); diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc index 512ef4bab3e..3df40073ac5 100644 --- a/gcc/d/d-compiler.cc +++ b/gcc/d/d-compiler.cc @@ -20,7 +20,6 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "dmd/compiler.h" -#include "dmd/scope.h" #include "dmd/expression.h" #include "dmd/identifier.h" #include "dmd/module.h" @@ -34,40 +33,6 @@ along with GCC; see the file COPYING3. If not see /* Implements the Compiler interface used by the frontend. */ -/* Generate C main() in response to seeing D main(). This used to be in - libdruntime, but contained a reference to _Dmain which didn't work when - druntime was made into a shared library and was linked to a program, such - as a C++ program, that didn't have a _Dmain. */ - -void -Compiler::genCmain (Scope *sc) -{ - static bool initialized = false; - - if (initialized) - return; - - /* The D code to be generated is provided by __entrypoint.di, try to load it, - but don't fail if unfound. */ - unsigned errors = global.startGagging (); - Module *m = Module::load (Loc (), NULL, Identifier::idPool ("__entrypoint")); - - if (global.endGagging (errors)) - m = NULL; - - if (m != NULL) - { - m->importedFrom = m; - m->importAll (NULL); - dsymbolSemantic (m, NULL); - semantic2 (m, NULL); - semantic3 (m, NULL); - d_add_entrypoint_module (m, sc->_module); - } - - initialized = true; -} - /* Perform a reinterpret cast of EXPR to type TYPE for use in CTFE. The front end should have already ensured that EXPR is a constant, so we just lower the value to GCC and return the converted CST. */ @@ -123,7 +88,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type) /* Encode CST to buffer. */ int len = native_encode_expr (cst, buffer, sizeof (buffer)); - if (tb->ty == Tsarray) + if (tb->ty == TY::Tsarray) { /* Interpret value as a vector of the same size, then return the array literal. */ @@ -161,22 +126,22 @@ Compiler::onParseModule (Module *m) { ModuleDeclaration *md = m->md; - if (!md || !md->id || !md->packages) + if (!md || !md->id|| md->packages.length == 0) { Identifier *id = (md && md->id) ? md->id : m->ident; if (!strcmp (id->toChars (), "object")) create_tinfo_types (m); } - else if (md->packages->length == 1) + else if (md->packages.length == 1) { - if (!strcmp ((*md->packages)[0]->toChars (), "gcc") + if (!strcmp (md->packages.ptr[0]->toChars (), "gcc") && !strcmp (md->id->toChars (), "builtins")) d_build_builtins_module (m); } - else if (md->packages->length == 2) + else if (md->packages.length == 2) { - if (!strcmp ((*md->packages)[0]->toChars (), "core") - && !strcmp ((*md->packages)[1]->toChars (), "stdc")) + if (!strcmp (md->packages.ptr[0]->toChars (), "core") + && !strcmp (md->packages.ptr[1]->toChars (), "stdc")) d_add_builtin_module (m); } } diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc index 3b4790298a5..25fd603edfa 100644 --- a/gcc/d/d-convert.cc +++ b/gcc/d/d-convert.cc @@ -361,14 +361,14 @@ convert_expr (tree exp, Type *etype, Type *totype) switch (ebtype->ty) { - case Tdelegate: - if (tbtype->ty == Tdelegate) + case TY::Tdelegate: + if (tbtype->ty == TY::Tdelegate) { exp = d_save_expr (exp); return build_delegate_cst (delegate_method (exp), delegate_object (exp), totype); } - else if (tbtype->ty == Tpointer) + else if (tbtype->ty == TY::Tpointer) { /* The front-end converts .ptr to cast (void *). Maybe should only allow void* ? */ @@ -382,8 +382,8 @@ convert_expr (tree exp, Type *etype, Type *totype) } break; - case Tstruct: - if (tbtype->ty == Tstruct) + case TY::Tstruct: + if (tbtype->ty == TY::Tstruct) { if (totype->size () == etype->size ()) { @@ -400,8 +400,8 @@ convert_expr (tree exp, Type *etype, Type *totype) /* else, default conversion, which should produce an error. */ break; - case Tclass: - if (tbtype->ty == Tclass) + case TY::Tclass: + if (tbtype->ty == TY::Tclass) { ClassDeclaration *cdfrom = ebtype->isClassHandle (); ClassDeclaration *cdto = tbtype->isClassHandle (); @@ -460,12 +460,12 @@ convert_expr (tree exp, Type *etype, Type *totype) /* else default conversion. */ break; - case Tsarray: - if (tbtype->ty == Tpointer) + case TY::Tsarray: + if (tbtype->ty == TY::Tpointer) { result = build_nop (build_ctype (totype), build_address (exp)); } - else if (tbtype->ty == Tarray) + else if (tbtype->ty == TY::Tarray) { dinteger_t dim = ebtype->isTypeSArray ()->dim->toInteger (); dinteger_t esize = ebtype->nextOf ()->size (); @@ -490,12 +490,12 @@ convert_expr (tree exp, Type *etype, Type *totype) return d_array_value (build_ctype (totype), size_int (dim), build_nop (ptrtype, build_address (exp))); } - else if (tbtype->ty == Tsarray) + else if (tbtype->ty == TY::Tsarray) { /* D allows casting a static array to any static array type. */ return build_nop (build_ctype (totype), exp); } - else if (tbtype->ty == Tstruct) + else if (tbtype->ty == TY::Tstruct) { /* And allows casting a static array to any struct type too. Type sizes should have already been checked by the frontend. */ @@ -510,12 +510,12 @@ convert_expr (tree exp, Type *etype, Type *totype) } break; - case Tarray: - if (tbtype->ty == Tpointer) + case TY::Tarray: + if (tbtype->ty == TY::Tpointer) { return d_convert (build_ctype (totype), d_array_ptr (exp)); } - else if (tbtype->ty == Tarray) + else if (tbtype->ty == TY::Tarray) { /* Assume tvoid->size() == 1. */ d_uns64 fsize = ebtype->nextOf ()->toBasetype ()->size (); @@ -523,9 +523,18 @@ convert_expr (tree exp, Type *etype, Type *totype) if (fsize != tsize) { - /* Conversion requires a reinterpret cast of array. */ - return build_libcall (LIBCALL_ARRAYCAST, totype, 3, - size_int (tsize), size_int (fsize), exp); + /* Conversion requires a reinterpret cast of array. + This case should have been lowered in the semantic pass. */ + if (tsize != 0 && fsize % tsize == 0) + { + /* Set array dimension to (length * (fsize / tsize)). */ + tree newlength = size_mult_expr (d_array_length (exp), + size_int (fsize / tsize)); + return d_array_value (build_ctype (totype), newlength, + d_array_ptr (exp)); + } + else + gcc_unreachable (); } else { @@ -534,7 +543,7 @@ convert_expr (tree exp, Type *etype, Type *totype) return build_vconvert (build_ctype (totype), exp); } } - else if (tbtype->ty == Tsarray) + else if (tbtype->ty == TY::Tsarray) { /* Strings are treated as dynamic arrays in D2. */ if (ebtype->isString () && tbtype->isString ()) @@ -548,23 +557,23 @@ convert_expr (tree exp, Type *etype, Type *totype) } break; - case Taarray: - if (tbtype->ty == Taarray) + case TY::Taarray: + if (tbtype->ty == TY::Taarray) return build_vconvert (build_ctype (totype), exp); /* Can convert associative arrays to void pointers. */ - else if (tbtype->ty == Tpointer && tbtype->nextOf ()->ty == Tvoid) + else if (tbtype->ty == TY::Tpointer && tbtype->nextOf ()->ty == TY::Tvoid) return build_vconvert (build_ctype (totype), exp); /* Else, default conversion, which should product an error. */ break; - case Tpointer: + case TY::Tpointer: /* Can convert void pointers to associative arrays too. */ - if (tbtype->ty == Taarray && ebtype->nextOf ()->ty == Tvoid) + if (tbtype->ty == TY::Taarray && ebtype->nextOf ()->ty == TY::Tvoid) return build_vconvert (build_ctype (totype), exp); break; - case Tnull: - case Tnoreturn: + case TY::Tnull: + case TY::Tnoreturn: /* Casting from `typeof(null)' for `null' expressions, or `typeof(*null)' for `noreturn' expressions is represented as all zeros. */ result = build_typeof_null_value (totype); @@ -574,8 +583,8 @@ convert_expr (tree exp, Type *etype, Type *totype) result = compound_expr (exp, result); break; - case Tvector: - if (tbtype->ty == Tsarray) + case TY::Tvector: + if (tbtype->ty == TY::Tsarray) { if (tbtype->size () == ebtype->size ()) return build_vconvert (build_ctype (totype), exp); @@ -613,7 +622,7 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype) Type *ebtype = etype->toBasetype (); Type *tbtype = totype->toBasetype (); - if (ebtype->ty == Tbool) + if (ebtype->ty == TY::Tbool) { /* If casting from bool, the result is either 0 or 1, any other value violates @safe code, so enforce that it is never invalid. */ @@ -651,7 +660,7 @@ convert_for_assignment (tree expr, Type *etype, Type *totype) /* Assuming this only has to handle converting a non Tsarray type to arbitrarily dimensioned Tsarrays. */ - if (tbtype->ty == Tsarray) + if (tbtype->ty == TY::Tsarray) { Type *telem = tbtype->nextOf ()->baseElemOf (); @@ -685,7 +694,7 @@ convert_for_assignment (tree expr, Type *etype, Type *totype) } /* D Front end uses IntegerExp(0) to mean zero-init an array or structure. */ - if ((tbtype->ty == Tsarray || tbtype->ty == Tstruct) + if ((tbtype->ty == TY::Tsarray || tbtype->ty == TY::Tstruct) && ebtype->isintegral ()) { if (!integer_zerop (expr)) @@ -736,12 +745,12 @@ convert_for_condition (tree expr, Type *type) switch (type->toBasetype ()->ty) { - case Taarray: + case TY::Taarray: /* Checks that aa.ptr !is null. */ result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr))); break; - case Tarray: + case TY::Tarray: { /* Checks (arr.length || arr.ptr) (i.e arr !is null). */ expr = d_save_expr (expr); @@ -762,7 +771,7 @@ convert_for_condition (tree expr, Type *type) break; } - case Tdelegate: + case TY::Tdelegate: { /* Checks (function || object), but what good is it if there is a null function pointer? */ @@ -783,7 +792,7 @@ convert_for_condition (tree expr, Type *type) break; } - case Tnoreturn: + case TY::Tnoreturn: /* Front-end allows conditionals that never return, represent the conditional result value as all zeros. */ result = build_zero_cst (d_bool_type); @@ -810,10 +819,10 @@ d_array_convert (Expression *exp) { Type *tb = exp->type->toBasetype (); - if (tb->ty == Tarray) + if (tb->ty == TY::Tarray) return build_expr (exp); - if (tb->ty == Tsarray) + if (tb->ty == TY::Tsarray) { Type *totype = tb->nextOf ()->arrayOf (); return convert_expr (build_expr (exp), exp->type, totype); @@ -832,7 +841,8 @@ d_array_convert (Type *etype, Expression *exp) { Type *tb = exp->type->toBasetype (); - if ((tb->ty != Tarray && tb->ty != Tsarray) || same_type_p (tb, etype)) + if ((tb->ty != TY::Tarray && tb->ty != TY::Tsarray) + || same_type_p (tb, etype)) { /* Convert single element to an array. */ tree expr = build_expr (exp); diff --git a/gcc/d/d-diagnostic.cc b/gcc/d/d-diagnostic.cc index 1982bd954a8..947b6e21d60 100644 --- a/gcc/d/d-diagnostic.cc +++ b/gcc/d/d-diagnostic.cc @@ -222,15 +222,6 @@ d_diagnostic_report_diagnostic (const Loc &loc, int opt, const char *format, message prefix PREFIX1 and PREFIX2, increasing the global or gagged error count. */ -void ATTRIBUTE_GCC_DIAG(2,3) -error (const Loc &loc, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - verror (loc, format, ap); - va_end (ap); -} - void ATTRIBUTE_GCC_DIAG(2,0) verror (const Loc &loc, const char *format, va_list ap, const char *prefix1, const char *prefix2, const char *) @@ -263,15 +254,6 @@ verror (const Loc &loc, const char *format, va_list ap, /* Print supplementary message about the last error with explicit location LOC. This doesn't increase the global error count. */ -void ATTRIBUTE_GCC_DIAG(2,3) -errorSupplemental (const Loc &loc, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - verrorSupplemental (loc, format, ap); - va_end (ap); -} - void ATTRIBUTE_GCC_DIAG(2,0) verrorSupplemental (const Loc &loc, const char *format, va_list ap) { @@ -284,15 +266,6 @@ verrorSupplemental (const Loc &loc, const char *format, va_list ap) /* Print a warning message with explicit location LOC, increasing the global warning count. */ -void ATTRIBUTE_GCC_DIAG(2,3) -warning (const Loc &loc, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - vwarning (loc, format, ap); - va_end (ap); -} - void ATTRIBUTE_GCC_DIAG(2,0) vwarning (const Loc &loc, const char *format, va_list ap) { @@ -311,15 +284,6 @@ vwarning (const Loc &loc, const char *format, va_list ap) /* Print supplementary message about the last warning with explicit location LOC. This doesn't increase the global warning count. */ -void ATTRIBUTE_GCC_DIAG(2,3) -warningSupplemental (const Loc &loc, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - vwarningSupplemental (loc, format, ap); - va_end (ap); -} - void ATTRIBUTE_GCC_DIAG(2,0) vwarningSupplemental (const Loc &loc, const char *format, va_list ap) { @@ -333,15 +297,6 @@ vwarningSupplemental (const Loc &loc, const char *format, va_list ap) message prefix PREFIX1 and PREFIX2, increasing the global warning or error count depending on how deprecations are treated. */ -void ATTRIBUTE_GCC_DIAG(2,3) -deprecation (const Loc &loc, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - vdeprecation (loc, format, ap); - va_end (ap); -} - void ATTRIBUTE_GCC_DIAG(2,0) vdeprecation (const Loc &loc, const char *format, va_list ap, const char *prefix1, const char *prefix2) @@ -372,15 +327,6 @@ vdeprecation (const Loc &loc, const char *format, va_list ap, /* Print supplementary message about the last deprecation with explicit location LOC. This does not increase the global error count. */ -void ATTRIBUTE_GCC_DIAG(2,3) -deprecationSupplemental (const Loc &loc, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - vdeprecationSupplemental (loc, format, ap); - va_end (ap); -} - void ATTRIBUTE_GCC_DIAG(2,0) vdeprecationSupplemental (const Loc &loc, const char *format, va_list ap) { @@ -392,30 +338,19 @@ vdeprecationSupplemental (const Loc &loc, const char *format, va_list ap) /* Print a verbose message with explicit location LOC. */ -void ATTRIBUTE_GCC_DIAG(2, 3) -message (const Loc &loc, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - vmessage (loc, format, ap); - va_end (ap); -} - void ATTRIBUTE_GCC_DIAG(2,0) vmessage (const Loc &loc, const char *format, va_list ap) { d_diagnostic_report_diagnostic (loc, 0, format, ap, DK_NOTE, true); } -/* Same as above, but doesn't take a location argument. */ +/* Print a tip message with prefix and highlighing. */ -void ATTRIBUTE_GCC_DIAG(1, 2) -message (const char *format, ...) +void ATTRIBUTE_GCC_DIAG(1,0) +vtip (const char *format, va_list ap) { - va_list ap; - va_start (ap, format); - vmessage (Loc (), format, ap); - va_end (ap); + if (!global.gag) + d_diagnostic_report_diagnostic (Loc (), 0, format, ap, DK_DEBUG, true); } /* Call this after printing out fatal error messages to clean up and diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc index 30fc6d435d0..522095f12c5 100644 --- a/gcc/d/d-frontend.cc +++ b/gcc/d/d-frontend.cc @@ -27,116 +27,11 @@ along with GCC; see the file COPYING3. If not see #include "dmd/scope.h" #include "tree.h" -#include "options.h" #include "fold-const.h" #include "diagnostic.h" #include "d-tree.h" - -/* Implements the Global interface defined by the frontend. - Used for managing the state of the current compilation. */ - -Global global; - -void -Global::_init (void) -{ - this->mars_ext = "d"; - this->hdr_ext = "di"; - this->doc_ext = "html"; - this->ddoc_ext = "ddoc"; - this->json_ext = "json"; - this->obj_ext = "o"; - - this->run_noext = true; - this->version = "v" -#include "verstr.h" - ; - - this->stdmsg = stderr; -} - -/* Start gagging. Return the current number of gagged errors. */ - -unsigned -Global::startGagging (void) -{ - this->gag++; - return this->gaggedErrors; -} - -/* End gagging, restoring the old gagged state. Return true if errors - occured while gagged. */ - -bool -Global::endGagging (unsigned oldGagged) -{ - bool anyErrs = (this->gaggedErrors != oldGagged); - this->gag--; - - /* Restore the original state of gagged errors; set total errors - to be original errors + new ungagged errors. */ - this->errors -= (this->gaggedErrors - oldGagged); - this->gaggedErrors = oldGagged; - - return anyErrs; -} - -/* Increment the error count to record that an error has occured in the - current context. An error message may or may not have been printed. */ - -void -Global::increaseErrorCount (void) -{ - if (gag) - this->gaggedErrors++; - - this->errors++; -} - - -/* Implements the Loc interface defined by the frontend. - Used for keeping track of current file/line position in code. */ - -Loc::Loc (const char *filename, unsigned linnum, unsigned charnum) -{ - this->linnum = linnum; - this->charnum = charnum; - this->filename = filename; -} - -const char * -Loc::toChars (void) const -{ - OutBuffer buf; - - if (this->filename) - buf.printf ("%s", this->filename); - - if (this->linnum) - { - buf.printf (":%u", this->linnum); - if (this->charnum) - buf.printf (":%u", this->charnum); - } - - return buf.extractChars (); -} - -bool -Loc::equals (const Loc &loc) -{ - if (this->linnum != loc.linnum || this->charnum != loc.charnum) - return false; - - if (!FileName::equals (this->filename, loc.filename)) - return false; - - return true; -} - - /* Implements back-end specific interfaces used by the frontend. */ /* Determine if function FD is a builtin one that we can evaluate in CTFE. */ @@ -144,7 +39,7 @@ Loc::equals (const Loc &loc) BUILTIN isBuiltin (FuncDeclaration *fd) { - if (fd->builtin != BUILTINunknown) + if (fd->builtin != BUILTIN::unknown) return fd->builtin; maybe_set_intrinsic (fd); @@ -158,7 +53,7 @@ isBuiltin (FuncDeclaration *fd) Expression * eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments) { - if (fd->builtin == BUILTINunimp) + if (fd->builtin == BUILTIN::unimp) return NULL; tree decl = get_symbol_decl (fd); @@ -185,16 +80,8 @@ eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments) Type * getTypeInfoType (Loc loc, Type *type, Scope *sc) { - gcc_assert (type->ty != Terror); + gcc_assert (type->ty != TY::Terror); check_typeinfo_type (loc, sc); create_typeinfo (type, sc ? sc->_module->importedFrom : NULL); return type->vtinfo->type; } - -/* Return an inlined copy of a default argument for a function parameter. */ - -Expression * -inlineCopy (Expression *e, Scope *) -{ - return e->copy (); -} diff --git a/gcc/d/d-frontend.h b/gcc/d/d-frontend.h new file mode 100644 index 00000000000..3edf812212a --- /dev/null +++ b/gcc/d/d-frontend.h @@ -0,0 +1,37 @@ +/* d-frontend.h -- D frontend interface to the gcc back-end. + Copyright (C) 2019 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 +. */ + +#ifndef GCC_D_FRONTEND_H +#define GCC_D_FRONTEND_H + +/* These functions are defined in D runtime. */ +extern "C" int rt_init (void); +extern "C" int rt_term (void); +//extern "C" void gc_disable (void); +extern "C" void *gc_malloc (size_t sz, unsigned ba = 0, const void *ti = NULL); +extern "C" void gc_free (void *); +extern "C" void gc_collect (void); + +template +inline T * +d_gc_malloc (void) +{ + void *ptr = gc_malloc (sizeof (T)); + return new(ptr) T (); +} + +#endif diff --git a/gcc/d/d-incpath.cc b/gcc/d/d-incpath.cc index d86392903e3..9a65622229b 100644 --- a/gcc/d/d-incpath.cc +++ b/gcc/d/d-incpath.cc @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "dmd/globals.h" +#include "d-frontend.h" #include "cppdefault.h" @@ -71,7 +72,7 @@ add_globalpaths (Strings *paths) if (paths) { if (!global.path) - global.path = new Strings (); + global.path = d_gc_malloc (); for (size_t i = 0; i < paths->length; i++) { @@ -98,7 +99,7 @@ add_filepaths (Strings *paths) if (paths) { if (!global.filePath) - global.filePath = new Strings (); + global.filePath = d_gc_malloc (); for (size_t i = 0; i < paths->length; i++) { diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index be6330fbdfb..d20370e5d8a 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -26,12 +26,13 @@ along with GCC; see the file COPYING3. If not see #include "dmd/errors.h" #include "dmd/expression.h" #include "dmd/hdrgen.h" +#include "dmd/id.h" #include "dmd/identifier.h" #include "dmd/json.h" #include "dmd/mangle.h" -#include "dmd/mars.h" #include "dmd/module.h" #include "dmd/mtype.h" +#include "dmd/root/file.h" #include "dmd/target.h" #include "opts.h" @@ -53,7 +54,7 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #include "d-tree.h" -#include "id.h" +#include "d-frontend.h" /* Array of D frontend type/decl nodes. */ @@ -83,10 +84,6 @@ d_option; /* List of modules being compiled. */ static Modules builtin_modules; -/* Module where `C main' is defined, compiled in if needed. */ -static Module *entrypoint_module = NULL; -static Module *entrypoint_root_module = NULL; - /* The current and global binding level in effect. */ struct binding_level *current_binding_level; struct binding_level *global_binding_level; @@ -202,7 +199,7 @@ deps_write (Module *module, obstack *buffer) deps_write_string (d_option.deps_target[i], buffer, column); } else - deps_write_string (module->objfile->name->str, buffer, column); + deps_write_string (module->objfile.toChars (), buffer, column); obstack_1grow (buffer, ':'); column++; @@ -212,7 +209,7 @@ deps_write (Module *module, obstack *buffer) { Module *depmod = modlist.pop (); - const char *modstr = depmod->srcfile->name->str; + const char *modstr = depmod->srcfile.toChars (); /* Skip modules that have already been looked at. */ if (seen_modules.add (modstr)) @@ -238,9 +235,7 @@ deps_write (Module *module, obstack *buffer) Module *m = depmod->aimports[i]; /* Ignore compiler-generated modules. */ - if ((m->ident == Identifier::idPool ("__entrypoint") - || m->ident == Identifier::idPool ("__main")) - && m->parent == NULL) + if (m->ident == Identifier::idPool ("__main") && m->parent == NULL) continue; /* Don't search system installed modules, this includes @@ -251,9 +246,9 @@ deps_write (Module *module, obstack *buffer) && m->parent == NULL) continue; - if (m->md && m->md->packages) + if (m->md && m->md->packages.length) { - Identifier *package = (*m->md->packages)[0]; + Identifier *package = m->md->packages.ptr[0]; if (package == Identifier::idPool ("core") || package == Identifier::idPool ("std") @@ -291,27 +286,15 @@ deps_write (Module *module, obstack *buffer) static void d_init_options (unsigned int, cl_decoded_option *decoded_options) { + /* Initialize the D runtime. */ + rt_init (); +// gc_disable (); + /* Set default values. */ global._init (); global.vendor = lang_hooks.name; global.params.argv0 = xstrdup (decoded_options[0].arg); - global.params.link = true; - global.params.useAssert = CHECKENABLEdefault; - global.params.useInvariants = CHECKENABLEdefault; - global.params.useIn = CHECKENABLEdefault; - global.params.useOut = CHECKENABLEdefault; - global.params.useArrayBounds = CHECKENABLEdefault; - global.params.useSwitchError = CHECKENABLEdefault; - global.params.checkAction = CHECKACTION_D; - global.params.useModuleInfo = true; - global.params.useTypeInfo = true; - global.params.useExceptions = true; - global.params.useInline = false; - global.params.obj = true; - global.params.hdrStripPlainFunctions = true; - global.params.betterC = false; - global.params.allInst = false; global.params.errorLimit = flag_max_errors; /* Default extern(C++) mangling to C++14. */ @@ -320,9 +303,10 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options) /* Warnings and deprecations are disabled by default. */ global.params.useDeprecated = DIAGNOSTICinform; global.params.warnings = DIAGNOSTICoff; + global.params.messageStyle = MESSAGESTYLEgnu; - global.params.imppath = new Strings (); - global.params.fileImppath = new Strings (); + global.params.imppath = d_gc_malloc (); + global.params.fileImppath = d_gc_malloc (); /* Extra GDC-specific options. */ d_option.fonly = NULL; @@ -462,6 +446,11 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, : (value == 1) ? CHECKENABLEsafeonly : CHECKENABLEoff; break; + case OPT_fcheckaction_: + global.params.checkAction = (value == 0) ? CHECKACTION_D + : (value == 1) ? CHECKACTION_halt : CHECKACTION_context; + break; + case OPT_fdebug: global.params.debuglevel = value ? 1 : 0; break; @@ -480,7 +469,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, if (Identifier::isValidIdentifier (CONST_CAST (char *, arg))) { if (!global.params.debugids) - global.params.debugids = new Strings (); + global.params.debugids = d_gc_malloc (); global.params.debugids->push (arg); break; } @@ -510,6 +499,16 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, global.params.betterC = !value; break; + case OPT_fdump_c___spec_: + if (global.params.doCxxHdrGeneration == CxxHeaderMode::none) + global.params.doCxxHdrGeneration = CxxHeaderMode::silent; + global.params.cxxhdrname = arg; + break; + + case OPT_fdump_c___spec_verbose: + global.params.doCxxHdrGeneration = CxxHeaderMode::verbose; + break; + case OPT_fdump_d_original: global.params.vcg_ast = value; break; @@ -518,6 +517,22 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, global.params.useExceptions = value; break; + case OPT_fextern_std_: + switch (value) + { + case CppStdRevisionCpp98: + case CppStdRevisionCpp11: + case CppStdRevisionCpp14: + case CppStdRevisionCpp17: + case CppStdRevisionCpp20: + global.params.cplusplus = (CppStdRevision) value; + break; + + default: + error ("bad argument for %<-fextern-std%>: %qs", arg); + } + break; + case OPT_fignore_unknown_pragmas: global.params.ignoreUnsupportedPragmas = value; break; @@ -552,35 +567,115 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, global.params.useIn = value ? CHECKENABLEon : CHECKENABLEoff; break; + case OPT_fpreview_all: + global.params.ehnogc = value; + global.params.useDIP25 = FeatureState::enabled; + global.params.useDIP1000 = FeatureState::enabled; + global.params.useDIP1021 = value; + global.params.dtorFields = FeatureState::enabled; + global.params.fieldwise = value; + global.params.fixAliasThis = value; + global.params.previewIn = value; + global.params.fix16997 = value; + global.params.markdown = value; + global.params.noSharedAccess = value; + global.params.rvalueRefParam = value; + global.params.inclusiveInContracts = value; + global.params.shortenedMethods = value; + break; + + case OPT_fpreview_dip1000: + global.params.useDIP1000 = FeatureState::enabled; + break; + + case OPT_fpreview_dip1008: + global.params.ehnogc = value; + break; + + case OPT_fpreview_dip1021: + global.params.useDIP1021 = value; + break; + + case OPT_fpreview_dip25: + global.params.useDIP25 = FeatureState::enabled; + break; + + case OPT_fpreview_dtorfields: + global.params.dtorFields = FeatureState::enabled; + break; + + case OPT_fpreview_fieldwise: + global.params.fieldwise = value; + break; + + case OPT_fpreview_fixaliasthis: + global.params.fixAliasThis = value; + break; + + case OPT_fpreview_in: + global.params.previewIn = value; + break; + + case OPT_fpreview_inclusiveincontracts: + global.params.inclusiveInContracts = value; + break; + + case OPT_fpreview_intpromote: + global.params.fix16997 = value; + break; + + case OPT_fpreview_nosharedaccess: + global.params.noSharedAccess = value; + break; + + case OPT_fpreview_rvaluerefparam: + global.params.rvalueRefParam = value; + break; + + case OPT_fpreview_shortenedmethods: + global.params.shortenedMethods = value; + break; + case OPT_frelease: global.params.release = value; break; - case OPT_frtti: - global.params.useTypeInfo = value; + case OPT_frevert_all: + global.params.useDIP25 = FeatureState::disabled; + global.params.markdown = !value; + global.params.dtorFields = FeatureState::disabled; break; - case OPT_fswitch_errors: - global.params.useSwitchError = value ? CHECKENABLEon : CHECKENABLEoff; + case OPT_frevert_dip25: + global.params.useDIP25 = FeatureState::disabled; break; - case OPT_ftransition_all: - global.params.vtls = value; - global.params.vfield = value; - global.params.vcomplex = value; + case OPT_frevert_dtorfields: + global.params.dtorFields = FeatureState::disabled; + break; + + case OPT_frevert_markdown: + global.params.markdown = !value; break; - case OPT_ftransition_complex: - global.params.vcomplex = value; + case OPT_frtti: + global.params.useTypeInfo = value; break; - case OPT_ftransition_dip1000: - global.params.vsafe = value; - global.params.useDIP25 = value; + case OPT_fsave_mixins_: + global.params.mixinFile = arg; + global.params.mixinOut = d_gc_malloc (); break; - case OPT_ftransition_dip25: - global.params.useDIP25 = value; + case OPT_fswitch_errors: + global.params.useSwitchError = value ? CHECKENABLEon : CHECKENABLEoff; + break; + + case OPT_ftransition_all: + global.params.vfield = value; + global.params.vgc = value; + global.params.vmarkdown= value; + global.params.vtls = value; break; case OPT_ftransition_field: @@ -591,6 +686,14 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, global.params.vgc = value; break; + case OPT_ftransition_vmarkdown: + global.params.vmarkdown = value; + break; + + case OPT_ftransition_templates: + global.params.vtemplates = value; + break; + case OPT_ftransition_tls: global.params.vtls = value; break; @@ -613,7 +716,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, if (Identifier::isValidIdentifier (CONST_CAST (char *, arg))) { if (!global.params.versionids) - global.params.versionids = new Strings (); + global.params.versionids = d_gc_malloc (); global.params.versionids->push (arg); break; } @@ -804,6 +907,14 @@ d_post_options (const char ** fn) global.params.checkAction = CHECKACTION_C; } + /* Enabling DIP1021 implies DIP1000. */ + if (global.params.useDIP1021) + global.params.useDIP1000 = FeatureState::enabled; + + /* Enabling DIP1000 implies DIP25. */ + if (global.params.useDIP1000 == FeatureState::enabled) + global.params.useDIP25 = FeatureState::enabled; + /* Keep in sync with existing -fbounds-check flag. */ flag_bounds_check = (global.params.useArrayBounds == CHECKENABLEon); @@ -828,6 +939,7 @@ d_post_options (const char ** fn) global.params.symdebug = write_symbols != NO_DEBUG; global.params.useInline = flag_inline_functions; global.params.showColumns = flag_show_column; + global.params.printErrorContext = flag_diagnostics_show_caret; if (global.params.useInline) global.params.hdrStripPlainFunctions = false; @@ -872,17 +984,6 @@ d_add_builtin_module (Module *m) builtin_modules.push (m); } -/* Record the entrypoint module ENTRY which will be compiled in the current - compilation. ROOT is the module scope where this was requested from. */ - -void -d_add_entrypoint_module (Module *entry, Module *root) -{ - /* We are emitting this straight to object file. */ - entrypoint_module = entry; - entrypoint_root_module = root; -} - /* Implements the lang_hooks.parse_file routine for language D. */ static void @@ -891,7 +992,7 @@ d_parse_file (void) if (global.params.verbose) { message ("binary %s", global.params.argv0.ptr); - message ("version %s", global.version.ptr); + message ("version %s", global.versionChars ()); if (global.versionids) { @@ -955,16 +1056,16 @@ d_parse_file (void) /* Handling stdin, generate a unique name for the module. */ Module *m = Module::create (in_fnames[i], - Identifier::generateId ("__stdin"), + Identifier::idPool ("__stdin"), global.params.doDocComments, global.params.doHdrGeneration); modules.push (m); /* Overwrite the source file for the module, the one created by Module::create would have a forced a `.d' suffix. */ - m->srcfile = File::create (""); - m->srcfile->len = len; - m->srcfile->buffer = buffer; + m->srcBuffer = FileBuffer::create (); + m->srcBuffer->data.length = len; + m->srcBuffer->data.ptr = buffer; } else { @@ -1011,15 +1112,16 @@ d_parse_file (void) } /* Load the module containing D main. */ + Module *main_module = NULL; if (global.params.addMain) { unsigned errors = global.startGagging (); - Module *m = Module::load (Loc (), NULL, Identifier::idPool ("__main")); + main_module = Module::load (Loc (), NULL, Identifier::idPool ("__main")); if (!global.endGagging (errors)) { - m->importedFrom = m; - modules.push (m); + main_module->importedFrom = main_module; + modules.push (main_module); } } @@ -1038,7 +1140,7 @@ d_parse_file (void) for (size_t i = 0; i < modules.length; i++) { Module *m = modules[i]; - if (d_option.fonly && m != Module::rootModule) + if (m->isHdrFile || (d_option.fonly && m != Module::rootModule)) continue; if (global.params.verbose) @@ -1203,7 +1305,7 @@ d_parse_file (void) if (name && (name[0] != '-' || name[1] != '\0')) { const char *nameext - = FileName::defaultExt (name, global.json_ext.ptr); + = FileName::defaultExt (name, json_ext.ptr); json_stream = fopen (nameext, "w"); if (!json_stream) { @@ -1245,22 +1347,25 @@ d_parse_file (void) } } + /* Generate C++ header files. */ + if (global.params.doCxxHdrGeneration != CxxHeaderMode::none) + genCppHdrFiles (modules); + + if (global.errors) + goto had_errors; + for (size_t i = 0; i < modules.length; i++) { Module *m = modules[i]; - if (d_option.fonly && m != Module::rootModule) + if ((m->isHdrFile && m != main_module) + || (d_option.fonly && m != Module::rootModule)) continue; if (global.params.verbose) message ("code %s", m->toChars ()); if (!flag_syntax_only) - { - if ((entrypoint_module != NULL) && (m == entrypoint_root_module)) - build_decl_tree (entrypoint_module); - - build_decl_tree (m); - } + build_decl_tree (m); } /* And end the main input file, if the debug writer wants it. */ @@ -1272,16 +1377,37 @@ d_parse_file (void) exit with an error status. */ errorcount += (global.errors + global.warnings); + /* We want to write the mixin expansion file also on error. */ + if (global.params.mixinOut) + { + FILE *mixin_stream = fopen (global.params.mixinFile, "w"); + + if (mixin_stream) + { + OutBuffer *buf = global.params.mixinOut; + fprintf (mixin_stream, "%s", buf->peekChars ()); + + if (ferror (mixin_stream) || fclose (mixin_stream)) + fatal_error (input_location, "closing mixin file %s: %m", + global.params.mixinFile); + } + else + { + fatal_error (input_location, "opening mixin file %s: %m", + global.params.mixinFile); + } + } + /* Remove generated .di files on error. */ if (errorcount && dump_headers) { for (size_t i = 0; i < modules.length; i++) { Module *m = modules[i]; - if (d_option.fonly && m != Module::rootModule) + if (m->isHdrFile || (d_option.fonly && m != Module::rootModule)) continue; - remove (m->hdrfile->toChars ()); + remove (m->hdrfile.toChars ()); } } @@ -1406,7 +1532,7 @@ d_type_promotes_to (tree type) /* Promotions are only applied on unnamed function arguments for declarations with `extern(C)' or `extern(C++)' linkage. */ if (cfun && DECL_LANG_FRONTEND (cfun->decl) - && DECL_LANG_FRONTEND (cfun->decl)->linkage != LINKd) + && DECL_LANG_FRONTEND (cfun->decl)->linkage != LINK::d) { /* In [type/integer-promotions], integer promotions are conversions of the following types: @@ -1559,7 +1685,8 @@ d_types_compatible_p (tree x, tree y) return true; /* Type system allows implicit conversion between. */ - if (tx->implicitConvTo (ty) || ty->implicitConvTo (tx)) + if (tx->implicitConvTo (ty) != MATCH::nomatch + || ty->implicitConvTo (tx) != MATCH::nomatch) return true; } diff --git a/gcc/d/d-longdouble.cc b/gcc/d/d-longdouble.cc index 471544ef79a..27c8d17a065 100644 --- a/gcc/d/d-longdouble.cc +++ b/gcc/d/d-longdouble.cc @@ -30,12 +30,6 @@ along with GCC; see the file COPYING3. If not see #include "longdouble.h" -/* Constant real values 0, 1, -1 and 0.5. */ -real_t CTFloat::zero; -real_t CTFloat::one; -real_t CTFloat::minusone; -real_t CTFloat::half; - /* Truncate longdouble to the highest precision supported by target. */ longdouble diff --git a/gcc/d/d-system.h b/gcc/d/d-system.h index a6a9fccc6b8..d7a0079ecf3 100644 --- a/gcc/d/d-system.h +++ b/gcc/d/d-system.h @@ -26,60 +26,8 @@ #endif #include "system.h" -/* Used by the dmd front-end to determine if we have POSIX-style IO. */ -#define POSIX (__linux__ || __GLIBC__ || __gnu_hurd__ || __APPLE__ \ - || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ \ - || __sun || __unix__) - /* Forward assert invariants to gcc_assert. */ #undef assert #define assert(EXPR) gcc_assert(EXPR) -/* Use libiberty's lrealpath to avoid portability problems. */ -#undef realpath -#define realpath(a, b) lrealpath((a)) - -/* Forward ctype.h macros used by the dmd front-end to safe-ctype.h. */ -#undef isalpha -#define isalpha(c) ISALPHA(c) -#undef isalnum -#define isalnum(c) ISALNUM(c) -#undef isdigit -#define isdigit(c) ISDIGIT(c) -#undef islower -#define islower(c) ISLOWER(c) -#undef isprint -#define isprint(c) ISPRINT(c) -#undef isspace -#define isspace(c) ISSPACE(c) -#undef isupper -#define isupper(c) ISUPPER(c) -#undef isxdigit -#define isxdigit(c) ISXDIGIT(c) -#undef tolower -#define tolower(c) TOLOWER(c) - -/* Forward _mkdir on MinGW to mkdir in system.h. */ -#ifdef _WIN32 -#undef _mkdir -#define _mkdir(p) mkdir(p, 0) -#endif - -/* Define any missing _MAX and _MIN macros. */ -#ifndef INT32_MAX -# define INT32_MAX INTTYPE_MAXIMUM (int32_t) -#endif -#ifndef INT32_MIN -# define INT32_MIN INTTYPE_MINIMUM (int32_t) -#endif -#ifndef INT64_MIN -# define INT64_MIN INTTYPE_MINIMUM (int64_t) -#endif -#ifndef UINT32_MAX -# define UINT32_MAX INTTYPE_MAXIMUM (uint32_t) -#endif -#ifndef UINT64_MAX -# define UINT64_MAX INTTYPE_MAXIMUM (uint64_t) -#endif - #endif /* GCC_D_SYSTEM_H */ diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index 1488bcebb2c..21417dddf78 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tm_p.h" #include "target.h" +#include "calls.h" #include "d-tree.h" #include "d-target.h" @@ -42,8 +43,6 @@ along with GCC; see the file COPYING3. If not see /* Implements the Target interface defined by the front end. Used for retrieving target-specific information. */ -Target target; - /* Internal key handlers for `__traits(getTargetInfo)'. */ static tree d_handle_target_cpp_std (void); static tree d_handle_target_cpp_runtime_library (void); @@ -89,9 +88,6 @@ define_float_constants (T &f, tree type) /* Floating-point NaN. */ real_nan (&f.nan.rv (), "", 1, mode); - /* Signalling floating-point NaN. */ - real_nan (&f.snan.rv (), "", 0, mode); - /* Floating-point +Infinity if the target supports infinities. */ real_inf (&f.infinity.rv ()); @@ -142,19 +138,19 @@ Target::_init (const Param &) /* Define what type to use for size_t, ptrdiff_t. */ if (this->ptrsize == 8) { - global.params.isLP64 = true; - Type::tsize_t = Type::basic[Tuns64]; - Type::tptrdiff_t = Type::basic[Tint64]; + this->isLP64 = true; + Type::tsize_t = Type::basic[(int)TY::Tuns64]; + Type::tptrdiff_t = Type::basic[(int)TY::Tint64]; } else if (this->ptrsize == 4) { - Type::tsize_t = Type::basic[Tuns32]; - Type::tptrdiff_t = Type::basic[Tint32]; + Type::tsize_t = Type::basic[(int)TY::Tuns32]; + Type::tptrdiff_t = Type::basic[(int)TY::Tint32]; } else if (this->ptrsize == 2) { - Type::tsize_t = Type::basic[Tuns16]; - Type::tptrdiff_t = Type::basic[Tint16]; + Type::tsize_t = Type::basic[(int)TY::Tuns16]; + Type::tptrdiff_t = Type::basic[(int)TY::Tint16]; } else sorry ("D does not support pointers on this target."); @@ -164,15 +160,7 @@ Target::_init (const Param &) /* Set-up target C ABI. */ this->c.longsize = int_size_in_bytes (long_integer_type_node); this->c.long_doublesize = int_size_in_bytes (long_double_type_node); - - /* Define what type to use for wchar_t. We don't want to support wide - characters less than "short" in D. */ - if (WCHAR_TYPE_SIZE == 32) - this->c.twchar_t = Type::basic[Tdchar]; - else if (WCHAR_TYPE_SIZE == 16) - this->c.twchar_t = Type::basic[Twchar]; - else - sorry ("D does not support wide characters on this target."); + this->c.wchar_tsize = (WCHAR_TYPE_SIZE / BITS_PER_UNIT); /* Set-up target C++ ABI. */ this->cpp.reverseOverloads = false; @@ -182,6 +170,12 @@ Target::_init (const Param &) /* Set-up target Objective-C ABI. */ this->objc.supported = false; + /* Set-up environmental settings. */ + this->obj_ext = "o"; + this->lib_ext = "a"; + this->dll_ext = "so"; + this->run_noext = true; + /* Initialize all compile-time properties for floating-point types. Should ensure that our real_t type is able to represent real_value. */ gcc_assert (sizeof (real_t) >= sizeof (real_value)); @@ -273,7 +267,7 @@ Target::isVectorTypeSupported (int sz, Type *type) type = Type::tuns8; /* No support for non-trivial types, complex types, or booleans. */ - if (!type->isTypeBasic () || type->iscomplex () || type->ty == Tbool) + if (!type->isTypeBasic () || type->iscomplex () || type->ty == TY::Tbool) return 2; /* In [simd/vector extensions], which vector types are supported depends on @@ -293,9 +287,9 @@ Target::isVectorTypeSupported (int sz, Type *type) Returns true if the operation is supported or type is not a vector. */ bool -Target::isVectorOpSupported (Type *type, TOK op, Type *) +Target::isVectorOpSupported (Type *type, unsigned op, Type *) { - if (type->ty != Tvector) + if (type->ty != TY::Tvector) return true; /* Don't support if type is non-scalar, such as __vector(void[]). */ @@ -322,18 +316,10 @@ Target::isVectorOpSupported (Type *type, TOK op, Type *) /* Logical operators must have a result type of bool. */ return false; - case TOKue: - case TOKlg: - case TOKule: - case TOKul: - case TOKuge: - case TOKug: case TOKle: case TOKlt: case TOKge: case TOKgt: - case TOKleg: - case TOKunord: case TOKequal: case TOKnotequal: case TOKidentity: @@ -379,7 +365,8 @@ TargetCPP::thunkMangle (FuncDeclaration *fd, int offset) const char * TargetCPP::typeMangle (Type *type) { - if (type->isTypeBasic () || type->ty == Tvector || type->ty == Tstruct) + if (type->isTypeBasic () || type->ty == TY::Tvector + || type->ty == TY::Tstruct) { tree ctype = build_ctype (type); return targetm.mangle_type (ctype); @@ -400,14 +387,14 @@ TargetCPP::parameterType (Parameter *arg) else if (arg->storageClass & STClazy) { /* Mangle as delegate. */ - Type *td = TypeFunction::create (NULL, t, VARARGnone, LINKd); - td = TypeDelegate::create (td); - t = t->merge2 (); + TypeFunction *tf = TypeFunction::create (NULL, t, VARARGnone, LINK::d); + TypeDelegate *td = TypeDelegate::create (tf); + t = td->merge2 (); } /* Could be a va_list, which we mangle as a pointer. */ Type *tvalist = target.va_listType (Loc (), NULL); - if (t->ty == Tsarray && tvalist->ty == Tsarray) + if (t->ty == TY::Tsarray && tvalist->ty == TY::Tsarray) { Type *tb = t->toBasetype ()->mutableOf (); if (tb == tvalist) @@ -450,10 +437,10 @@ Target::systemLinkage (void) /* In [attribute/linkage], `System' is the same as `Windows' on Windows platforms, and `C' on other platforms. */ if (link_system) - return LINKwindows; + return LINK::windows; } - return LINKc; + return LINK::c; } /* Generate a TypeTuple of the equivalent types used to determine if a @@ -477,12 +464,12 @@ Target::isReturnOnStack (TypeFunction *tf, bool) /* Need the back-end type to determine this, but this is called from the frontend before semantic processing is finished. An accurate value is not currently needed anyway. */ - if (tf->isref) + if (tf->isref ()) return false; Type *tn = tf->next->toBasetype (); - return (tn->ty == Tstruct || tn->ty == Tsarray); + return (tn->ty == TY::Tstruct || tn->ty == TY::Tsarray); } /* Add all target info in HANDLERS to D_TARGET_INFO_TABLE for use by @@ -575,12 +562,49 @@ Target::getTargetInfo (const char *key, const Loc &loc) return NULL; } -/** - * Returns true if the implementation for object monitors is always defined - * in the D runtime library (rt/monitor_.d). */ +/* Returns true if the callee invokes destructors for arguments. */ + +bool +Target::isCalleeDestroyingArgs (TypeFunction *tf) +{ + return tf->linkage == LINK::d; +} + +/* Returns true if the implementation for object monitors is always defined + in the D runtime library (rt/monitor_.d). */ bool Target::libraryObjectMonitors (FuncDeclaration *, Statement *) { return true; } + +/* Decides whether an `in' parameter of the specified POD type PARAM_TYPE is to + be passed by reference or by valie. This is used only when compiling with + `-fpreview=in' enabled. */ + +bool +Target::preferPassByRef (Type *param_type) +{ + if (param_type->size () == SIZE_INVALID) + return false; + + tree type = build_ctype (param_type); + + /* Prefer a `ref' if the type is an aggregate, and its size is greater than + its alignment. */ + if (AGGREGATE_TYPE_P (type) + && (!valid_constant_size_p (TYPE_SIZE_UNIT (type)) + || compare_tree_int (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type)) > 0)) + return true; + + /* If the back-end is always going to pass this by invisible reference. */ + if (pass_by_reference (NULL, function_arg_info (type, true))) + return true; + + /* If returning the parameter means the caller will do RVO. */ + if (targetm.calls.return_in_memory (type, NULL_TREE)) + return true; + + return false; +} diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h index 9b90ca530e6..328b6b861d2 100644 --- a/gcc/d/d-tree.h +++ b/gcc/d/d-tree.h @@ -617,7 +617,6 @@ extern void add_import_paths (const char *, const char *, bool); /* In d-lang.cc. */ extern void d_add_builtin_module (Module *); -extern void d_add_entrypoint_module (Module *, Module *); extern d_tree_node_structure_enum d_tree_node_structure (lang_tree_node *); extern struct lang_type *build_lang_type (Type *); extern struct lang_decl *build_lang_decl (Declaration *); diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 9c9205fa349..e28a581a7ec 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -106,9 +106,9 @@ gcc_attribute_p (Dsymbol *decl) { ModuleDeclaration *md = decl->getModule ()->md; - if (md && md->packages && md->packages->length == 1) + if (md && md->packages.length == 1) { - if (!strcmp ((*md->packages)[0]->toChars (), "gcc") + if (!strcmp (md->packages.ptr[0]->toChars (), "gcc") && !strcmp (md->id->toChars (), "attributes")) return true; } @@ -116,6 +116,59 @@ gcc_attribute_p (Dsymbol *decl) return false; } +/* Subroutine of pragma declaration visitor for marking the function in the + defined in SYM as a global constructor or destructor. If ISCTOR is true, + then we're applying pragma(crt_constructor). */ + +static int +apply_pragma_crt (Dsymbol *sym, bool isctor) +{ + AttribDeclaration *ad = sym->isAttribDeclaration (); + if (ad != NULL) + { + int nested = 0; + + /* Walk all declarations of the attribute scope. */ + Dsymbols *ds = ad->include (NULL); + if (ds) + { + for (size_t i = 0; i < ds->length; i++) + nested += apply_pragma_crt ((*ds)[i], isctor); + } + + return nested; + } + + FuncDeclaration *fd = sym->isFuncDeclaration (); + if (fd != NULL) + { + tree decl = get_decl_tree (fd); + + /* Apply flags to the function. */ + if (isctor) + { + DECL_STATIC_CONSTRUCTOR (decl) = 1; + decl_init_priority_insert (decl, DEFAULT_INIT_PRIORITY); + } + else + { + DECL_STATIC_DESTRUCTOR (decl) = 1; + decl_fini_priority_insert (decl, DEFAULT_INIT_PRIORITY); + } + + if (fd->linkage != LINK::c) + { + error_at (make_location_t (fd->loc), + "must be % for %", + isctor ? "crt_constructor" : "crt_destructor"); + } + + return 1; + } + + return 0; +} + /* Implements the visitor interface to lower all Declaration AST classes emitted from the D Front-end to GCC trees. All visit methods accept one parameter D, which holds the frontend AST @@ -246,19 +299,31 @@ public: } /* Pragmas are a way to pass special information to the compiler and to add - vendor specific extensions to D. We don't do anything here, yet. */ + vendor specific extensions to D. */ void visit (PragmaDeclaration *d) { - if (!global.params.ignoreUnsupportedPragmas) + if (d->ident == Identifier::idPool ("lib") + || d->ident == Identifier::idPool ("startaddress")) { - if (d->ident == Identifier::idPool ("lib") - || d->ident == Identifier::idPool ("startaddress")) + if (!global.params.ignoreUnsupportedPragmas) { warning_at (make_location_t (d->loc), OPT_Wunknown_pragmas, "pragma(%s) not implemented", d->ident->toChars ()); } } + else if (d->ident == Identifier::idPool ("crt_constructor") + || d->ident == Identifier::idPool ("crt_destructor")) + { + /* Handle pragma(crt_constructor) and pragma(crt_destructor). Apply + flag to indicate that the functions enclosed should run automatically + at the beginning or end of execution. */ + bool isctor = (d->ident == Identifier::idPool ("crt_constructor")); + + if (apply_pragma_crt (d, isctor) > 1) + error_at (make_location_t (d->loc), + "can only apply to a single declaration"); + } visit ((AttribDeclaration *) d); } @@ -311,14 +376,14 @@ public: nested members. Only applies to classes or structs. */ Type *tb = fd->type->nextOf ()->baseElemOf (); - while (tb->ty == Tarray || tb->ty == Tpointer) + while (tb->ty == TY::Tarray || tb->ty == TY::Tpointer) tb = tb->nextOf ()->baseElemOf (); TemplateInstance *ti = NULL; - if (tb->ty == Tstruct) + if (tb->ty == TY::Tstruct) ti = tb->isTypeStruct ()->sym->isInstantiated (); - else if (tb->ty == Tclass) + else if (tb->ty == TY::Tclass) ti = tb->isTypeClass ()->sym->isInstantiated (); /* Return type is instantiated from this template declaration, walk over @@ -360,7 +425,7 @@ public: if (d->semanticRun >= PASSobj) return; - if (d->type->ty == Terror) + if (d->type->ty == TY::Terror) { error_at (make_location_t (d->loc), "had semantic errors when compiling"); @@ -447,7 +512,8 @@ public: if (fd2->isFuture ()) continue; - if (fd->leastAsSpecialized (fd2) || fd2->leastAsSpecialized (fd)) + if (fd->leastAsSpecialized (fd2) != MATCH::nomatch + || fd2->leastAsSpecialized (fd) != MATCH::nomatch) { error_at (make_location_t (fd->loc), "use of %qs", fd->toPrettyChars ()); @@ -474,7 +540,7 @@ public: if (d->semanticRun >= PASSobj) return; - if (d->type->ty == Terror) + if (d->type->ty == TY::Terror) { error_at (make_location_t (d->loc), "had semantic errors when compiling"); @@ -495,7 +561,8 @@ public: /* Generate C symbols. */ d->csym = get_classinfo_decl (d); - d->vtblsym = get_vtable_decl (d); + Dsymbol *vtblsym = d->vtblSymbol (); + vtblsym->csym = get_vtable_decl (d); tree sinit = aggregate_initializer_decl (d); /* Generate static initializer. */ @@ -527,9 +594,9 @@ public: } } - DECL_INITIAL (d->vtblsym) - = build_constructor (TREE_TYPE (d->vtblsym), elms); - d_finish_decl (d->vtblsym); + DECL_INITIAL (vtblsym->csym) + = build_constructor (TREE_TYPE (vtblsym->csym), elms); + d_finish_decl (vtblsym->csym); /* Add this decl to the current binding level. */ tree ctype = TREE_TYPE (build_ctype (d->type)); @@ -547,7 +614,7 @@ public: if (d->semanticRun >= PASSobj) return; - if (d->type->ty == Terror) + if (d->type->ty == TY::Terror) { error_at (make_location_t (d->loc), "had semantic errors when compiling"); @@ -590,7 +657,7 @@ public: if (d->semanticRun >= PASSobj) return; - if (d->errors || d->type->ty == Terror) + if (d->errors || d->type->ty == TY::Terror) { error_at (make_location_t (d->loc), "had semantic errors when compiling"); @@ -629,7 +696,7 @@ public: if (d->semanticRun >= PASSobj) return; - if (d->type->ty == Terror) + if (d->type->ty == TY::Terror) { error_at (make_location_t (d->loc), "had semantic errors when compiling"); @@ -695,7 +762,7 @@ public: /* Frontend should have already caught this. */ gcc_assert (!integer_zerop (size) - || d->type->toBasetype ()->ty == Tsarray); + || d->type->toBasetype ()->ty == TY::Tsarray); d_finish_decl (decl); @@ -770,7 +837,7 @@ public: /* Check if any errors occurred when running semantic. */ if (TypeFunction *tf = d->type->isTypeFunction ()) { - if (tf->next == NULL || tf->next->ty == Terror) + if (tf->next == NULL || tf->next->ty == TY::Terror) return; } @@ -1183,6 +1250,17 @@ get_symbol_decl (Declaration *decl) } else if (TREE_CODE (decl->csym) == FUNCTION_DECL) { + /* Dual-context functions require the code generation to build an array + for the context pointer of the function, making the delicate task of + tracking which context to follow when encountering a non-local symbol, + and so are a not planned to be supported. */ + if (fd->needThis () && !fd->isMember2 ()) + { + fatal_error (make_location_t (fd->loc), + "function requires a dual-context, which is not yet " + "supported by GDC"); + } + /* The real function type may differ from its declaration. */ tree fntype = TREE_TYPE (decl->csym); tree newfntype = NULL_TREE; @@ -1238,9 +1316,9 @@ get_symbol_decl (Declaration *decl) /* In [pragma/inline], functions decorated with `pragma(inline)' affects whether they are inlined or not. */ - if (fd->inlining == PINLINEalways) + if (fd->inlining == PINLINE::always) DECL_DECLARED_INLINE_P (decl->csym) = 1; - else if (fd->inlining == PINLINEnever) + else if (fd->inlining == PINLINE::never) DECL_UNINLINABLE (decl->csym) = 1; /* Function was declared `naked'. */ @@ -1254,13 +1332,6 @@ get_symbol_decl (Declaration *decl) if (fd->generated) DECL_ARTIFICIAL (decl->csym) = 1; - /* Vector array operations are always compiler generated. */ - if (fd->isArrayOp) - { - DECL_ARTIFICIAL (decl->csym) = 1; - DECL_DECLARED_INLINE_P (decl->csym) = 1; - } - /* Ensure and require contracts are lexically nested in the function they part of, but are always publicly callable. */ if (fd->ident == Identifier::idPool ("ensure") @@ -1271,7 +1342,7 @@ get_symbol_decl (Declaration *decl) DECL_FINAL_P (decl->csym) = 1; /* Function is of type `noreturn' or `typeof(*null)'. */ - if (fd->type->nextOf ()->ty == Tnoreturn) + if (fd->type->nextOf ()->ty == TY::Tnoreturn) TREE_THIS_VOLATILE (decl->csym) = 1; /* Check whether this function is expanded by the frontend. */ @@ -1298,10 +1369,10 @@ get_symbol_decl (Declaration *decl) if (decl->storage_class & STCvolatile) TREE_THIS_VOLATILE (decl->csym) = 1; - /* Protection attributes are used by the debugger. */ - if (decl->protection.kind == Prot::private_) + /* Visibility attributes are used by the debugger. */ + if (decl->visibility.kind == Visibility::private_) TREE_PRIVATE (decl->csym) = 1; - else if (decl->protection.kind == Prot::protected_) + else if (decl->visibility.kind == Visibility::protected_) TREE_PROTECTED (decl->csym) = 1; /* Likewise, so could the deprecated attribute. */ @@ -1794,7 +1865,7 @@ make_thunk (FuncDeclaration *decl, int offset) forcing a D local thunk to be emitted. */ const char *ident; - if (decl->linkage == LINKcpp) + if (decl->linkage == LINK::cpp) ident = target.cpp.thunkMangle (decl, offset); else { @@ -1810,7 +1881,9 @@ make_thunk (FuncDeclaration *decl, int offset) SET_DECL_ASSEMBLER_NAME (thunk, DECL_NAME (thunk)); d_keep (thunk); - free (CONST_CAST (char *, ident)); + + if (decl->linkage != LINK::cpp) + free (CONST_CAST (char *, ident)); if (!DECL_EXTERNAL (function)) finish_thunk (thunk, function); @@ -1989,26 +2062,27 @@ d_mark_needed (tree decl) tree get_vtable_decl (ClassDeclaration *decl) { - if (decl->vtblsym) - return decl->vtblsym; + if (decl->vtblsym && decl->vtblsym->csym) + return decl->vtblsym->csym; tree ident = mangle_internal_decl (decl, "__vtbl", "Z"); /* Note: Using a static array type for the VAR_DECL, the DECL_INITIAL value will have a different type. However the back-end seems to accept this. */ tree type = build_ctype (Type::tvoidptr->sarrayOf (decl->vtbl.length)); - decl->vtblsym = declare_extern_var (ident, type); - DECL_LANG_SPECIFIC (decl->vtblsym) = build_lang_decl (NULL); + Dsymbol *vtblsym = decl->vtblSymbol (); + vtblsym->csym = declare_extern_var (ident, type); + DECL_LANG_SPECIFIC (vtblsym->csym) = build_lang_decl (NULL); /* Class is a reference, want the record type. */ - DECL_CONTEXT (decl->vtblsym) = TREE_TYPE (build_ctype (decl->type)); - TREE_READONLY (decl->vtblsym) = 1; - DECL_VIRTUAL_P (decl->vtblsym) = 1; + DECL_CONTEXT (vtblsym->csym) = TREE_TYPE (build_ctype (decl->type)); + TREE_READONLY (vtblsym->csym) = 1; + DECL_VIRTUAL_P (vtblsym->csym) = 1; - SET_DECL_ALIGN (decl->vtblsym, TARGET_VTABLE_ENTRY_ALIGN); - DECL_USER_ALIGN (decl->vtblsym) = true; + SET_DECL_ALIGN (vtblsym->csym, TARGET_VTABLE_ENTRY_ALIGN); + DECL_USER_ALIGN (vtblsym->csym) = true; - return decl->vtblsym; + return vtblsym->csym; } /* Helper function of build_class_instance. Find the field inside aggregate diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index ea21bd5a8a1..31680564bdd 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -249,7 +249,7 @@ public: tree t1 = build_expr (e->e1); tree t2 = build_expr (e->e2); - if (e->type->ty != Tvoid) + if (e->type->ty != TY::Tvoid) { t1 = convert_expr (t1, e->e1->type, e->type); t2 = convert_expr (t2, e->e2->type, e->type); @@ -268,8 +268,8 @@ public: Type *tb1 = e->e1->type->toBasetype (); Type *tb2 = e->e2->type->toBasetype (); - if ((tb1->ty == Tsarray || tb1->ty == Tarray) - && (tb2->ty == Tsarray || tb2->ty == Tarray)) + if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray) + && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray)) { /* For static and dynamic arrays, identity is defined as referring to the same array elements and the same number of elements. */ @@ -278,7 +278,7 @@ public: this->result_ = d_convert (build_ctype (e->type), build_boolop (code, t1, t2)); } - else if (tb1->isfloating () && tb1->ty != Tvector) + else if (tb1->isfloating () && tb1->ty != TY::Tvector) { /* For floating-point values, identity is defined as the bits in the operands being identical. */ @@ -333,8 +333,8 @@ public: Type *tb2 = e->e2->type->toBasetype (); tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR; - if ((tb1->ty == Tsarray || tb1->ty == Tarray) - && (tb2->ty == Tsarray || tb2->ty == Tarray)) + if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray) + && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray)) { /* For static and dynamic arrays, equality is defined as the lengths of the arrays matching, and all the elements are equal. */ @@ -346,8 +346,9 @@ public: e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0; Or when generating a NE expression: e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */ - if ((t1elem->isintegral () || t1elem->ty == Tvoid - || (t1elem->ty == Tstruct && !t1elem->isTypeStruct ()->sym->xeq)) + if ((t1elem->isintegral () || t1elem->ty == TY::Tvoid + || (t1elem->ty == TY::Tstruct + && !t1elem->isTypeStruct ()->sym->xeq)) && t1elem->ty == t2elem->ty) { tree t1 = d_array_convert (e->e1); @@ -368,7 +369,7 @@ public: /* Compare arrays using memcmp if possible, otherwise for structs, each field is compared inline. */ - if (t1elem->ty != Tstruct + if (t1elem->ty != TY::Tstruct || identity_compare_p (t1elem->isTypeStruct ()->sym)) { tree size = size_mult_expr (t1len, size_int (t1elem->size ())); @@ -398,7 +399,7 @@ public: /* Finally, check if lengths of both arrays match if dynamic. The frontend should have already guaranteed that static arrays have same size. */ - if (tb1->ty == Tsarray && tb2->ty == Tsarray) + if (tb1->ty == TY::Tsarray && tb2->ty == TY::Tsarray) gcc_assert (tb1->size () == tb2->size ()); else { @@ -444,7 +445,7 @@ public: this->result_ = build_struct_comparison (code, ts->sym, t1, t2); } - else if (tb1->ty == Taarray && tb2->ty == Taarray) + else if (tb1->ty == TY::Taarray && tb2->ty == TY::Taarray) { /* Use _aaEqual() for associative arrays. */ tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3, @@ -518,23 +519,14 @@ public: gcc_unreachable (); } - if ((tb1->ty == Tsarray || tb1->ty == Tarray) - && (tb2->ty == Tsarray || tb2->ty == Tarray)) + /* For static and dynamic arrays, the relational op is turned into a + library call. It is not lowered during codegen. */ + if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray) + && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray)) { - /* For static and dynamic arrays, the result of the relational op is - the result of the operator applied to the first non-equal element - of the array. If two arrays compare equal, but are of different - lengths, the shorter array compares as less than the longer. */ - Type *telem = tb1->nextOf ()->toBasetype (); - - tree call = build_libcall (LIBCALL_ADCMP2, Type::tint32, 3, - d_array_convert (e->e1), - d_array_convert (e->e2), - build_typeinfo (e->loc, telem->arrayOf ())); - result = build_boolop (code, call, integer_zero_node); - - this->result_ = d_convert (build_ctype (e->type), result); - return; + error ("cannot handle comparison of type %<%s == %s%>", + tb1->toChars (), tb2->toChars ()); + gcc_unreachable (); } /* Simple comparison. */ @@ -550,7 +542,7 @@ public: { tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; - if (e->e2->type->toBasetype ()->ty != Tvoid) + if (e->e2->type->toBasetype ()->ty != TY::Tvoid) { tree t1 = build_expr (e->e1); tree t2 = build_expr (e->e2); @@ -618,7 +610,8 @@ public: The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */ if (MinExp *me = e->e1->isMinExp ()) { - if (me->e1->type->ty == Tpointer && me->e2->type->ty == Tpointer + if (me->e1->type->ty == TY::Tpointer + && me->e2->type->ty == TY::Tpointer && e->e2->op == TOKint64) { code = EXACT_DIV_EXPR; @@ -678,7 +671,7 @@ public: Type *tb2 = e->e2->type->toBasetype (); Type *etype; - if (tb1->ty == Tarray || tb1->ty == Tsarray) + if (tb1->ty == TY::Tarray || tb1->ty == TY::Tsarray) etype = tb1->nextOf (); else etype = tb2->nextOf (); @@ -839,13 +832,13 @@ public: tree ptr = d_save_expr (build_address (lhs)); tree result = NULL_TREE; - if (tb1->ty == Tarray && tb2->ty == Tdchar - && (etype->ty == Tchar || etype->ty == Twchar)) + if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar + && (etype->ty == TY::Tchar || etype->ty == TY::Twchar)) { /* Append a dchar to a char[] or wchar[]: The assignment is handled by the D run-time library, so only need to call `_d_arrayappend[cw]d(&e1, e2)' */ - libcall_fn libcall = (etype->ty == Tchar) + libcall_fn libcall = (etype->ty == TY::Tchar) ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD; result = build_libcall (libcall, e->type, 2, @@ -853,9 +846,9 @@ public: } else { - gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray); + gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray); - if ((tb2->ty == Tarray || tb2->ty == Tsarray) + if ((tb2->ty == TY::Tarray || tb2->ty == TY::Tsarray) && same_type_p (etype, tb2->nextOf ()->toBasetype ())) { /* Append an array to another array: @@ -917,23 +910,9 @@ public: /* Look for array.length = n; */ if (e->e1->op == TOKarraylength) { - /* Assignment to an array's length property; resize the array. */ - ArrayLengthExp *ale = e->e1->isArrayLengthExp (); - tree newlength = convert_expr (build_expr (e->e2), e->e2->type, - Type::tsize_t); - tree ptr = build_address (build_expr (ale->e1)); - - /* Don't want the basetype for the element type. */ - Type *etype = ale->e1->type->toBasetype ()->nextOf (); - libcall_fn libcall = etype->isZeroInit () - ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT; - - tree result = build_libcall (libcall, ale->e1->type, 3, - build_typeinfo (ale->loc, ale->e1->type), - newlength, ptr); - - this->result_ = d_array_length (result); - return; + /* This case should have been rewritten to `_d_arraysetlengthT` in the + semantic phase. */ + gcc_unreachable (); } /* Look for array[] = n; */ @@ -947,13 +926,17 @@ public: bool postblit = needs_postblit (etype) && lvalue_p (e->e2); bool destructor = needs_dtor (etype); - if (e->memset & blockAssign) + if (e->memset == MemorySet::blockAssign) { /* Set a range of elements to one value. */ - tree t1 = d_save_expr (build_expr (e->e1)); + tree t1 = build_expr (e->e1); tree t2 = build_expr (e->e2); tree result; + /* Extract any array bounds checks from the slice expression. */ + tree init = stabilize_expr (&t1); + t1 = d_save_expr (t1); + if ((postblit || destructor) && e->op != TOKblit) { libcall_fn libcall = (e->op == TOKconstruct) @@ -962,15 +945,12 @@ public: Type *tm = etype->unSharedOf ()->mutableOf (); tree ti = build_typeinfo (e->loc, tm); - tree result = build_libcall (libcall, Type::tvoid, 4, - d_array_ptr (t1), - build_address (t2), - d_array_length (t1), ti); - this->result_ = compound_expr (result, t1); - return; + result = build_libcall (libcall, Type::tvoid, 4, + d_array_ptr (t1), + build_address (t2), + d_array_length (t1), ti); } - - if (integer_zerop (t2)) + else if (integer_zerop (t2)) { tree size = size_mult_expr (d_array_length (t1), size_int (etype->size ())); @@ -980,12 +960,13 @@ public: result = build_array_set (d_array_ptr (t1), d_array_length (t1), t2); + result = compound_expr (init, result); this->result_ = compound_expr (result, t1); } else { /* Perform a memcpy operation. */ - gcc_assert (e->e2->type->ty != Tpointer); + gcc_assert (e->e2->type->ty != TY::Tpointer); if (!postblit && !destructor) { @@ -1056,7 +1037,7 @@ public: } /* Look for reference initializations. */ - if (e->memset & referenceInit) + if (e->memset == MemorySet::referenceInit) { gcc_assert (e->op == TOKconstruct || e->op == TOKblit); gcc_assert (e->e1->op == TOKvar); @@ -1082,7 +1063,7 @@ public: tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR; /* Look for struct assignment. */ - if (tb1->ty == Tstruct) + if (tb1->ty == TY::Tstruct) { tree t1 = build_expr (e->e1); tree t2 = convert_for_assignment (build_expr (e->e2, false, true), @@ -1136,7 +1117,7 @@ public: } /* Look for static array assignment. */ - if (tb1->ty == Tsarray) + if (tb1->ty == TY::Tsarray) { /* Look for array = 0. */ if (e->e2->op == TOKint64) @@ -1148,7 +1129,7 @@ public: } Type *etype = tb1->nextOf (); - gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray); + gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray); /* Determine if we need to run postblit. */ bool postblit = needs_postblit (etype); @@ -1171,7 +1152,8 @@ public: return; } - Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type; + Type *arrtype = (e->type->ty == TY::Tsarray) + ? etype->arrayOf () : e->type; tree result; if (e->op == TOKconstruct) @@ -1198,7 +1180,7 @@ public: } /* Cast the libcall result back to a static array. */ - if (e->type->ty == Tsarray) + if (e->type->ty == TY::Tsarray) result = indirect_ref (build_ctype (e->type), d_array_ptr (result)); @@ -1243,7 +1225,7 @@ public: { Type *tb1 = e->e1->type->toBasetype (); - if (tb1->ty == Taarray) + if (tb1->ty == TY::Taarray) { /* Get the key for the associative array. */ Type *tkey = tb1->isTypeAArray ()->index->toBasetype (); @@ -1289,7 +1271,7 @@ public: tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ()); tree length = NULL_TREE; - if (tb1->ty != Tpointer) + if (tb1->ty != TY::Tpointer) length = get_array_length (array, tb1); else gcc_assert (e->lengthVar == NULL); @@ -1304,7 +1286,7 @@ public: /* If it's a static array and the index is constant, the front end has already checked the bounds. */ - if (tb1->ty != Tpointer) + if (tb1->ty != TY::Tpointer) index = build_bounds_index_condition (e, index, length); /* Index the .ptr. */ @@ -1330,7 +1312,7 @@ public: void visit (ArrayLengthExp *e) { - if (e->e1->type->toBasetype ()->ty == Tarray) + if (e->e1->type->toBasetype ()->ty == TY::Tarray) this->result_ = d_array_length (build_expr (e->e1)); else { @@ -1364,13 +1346,13 @@ public: { Type *tb = e->type->toBasetype (); Type *tb1 = e->e1->type->toBasetype (); - gcc_assert (tb->ty == Tarray || tb->ty == Tsarray); + gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray); /* Use convert-to-dynamic-array code if possible. */ if (!e->lwr) { tree result = build_expr (e->e1); - if (e->e1->type->toBasetype ()->ty == Tsarray) + if (e->e1->type->toBasetype ()->ty == TY::Tsarray) result = convert_expr (result, e->e1->type, e->type); this->result_ = result; @@ -1386,7 +1368,7 @@ public: /* Our array is already a SAVE_EXPR if necessary, so we don't make length a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */ - if (tb1->ty != Tpointer) + if (tb1->ty != TY::Tpointer) length = get_array_length (array, tb1); else gcc_assert (e->lengthVar == NULL); @@ -1415,13 +1397,13 @@ public: /* Nothing more to do for static arrays, their bounds checking has been done at compile-time. */ - if (tb->ty == Tsarray) + if (tb->ty == TY::Tsarray) { this->result_ = indirect_ref (build_ctype (e->type), ptr); return; } else - gcc_assert (tb->ty == Tarray); + gcc_assert (tb->ty == TY::Tarray); /* Generate bounds checking code. */ tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree, @@ -1440,7 +1422,7 @@ public: tree result = build_expr (e->e1, this->constp_, this->literalp_); /* Just evaluate e1 if it has any side effects. */ - if (tbtype->ty == Tvoid) + if (tbtype->ty == TY::Tvoid) this->result_ = build_nop (build_ctype (tbtype), result); else this->result_ = convert_for_rvalue (result, ebtype, tbtype); @@ -1453,7 +1435,7 @@ public: tree t1 = build_expr (e->e1); Type *tb1 = e->e1->type->toBasetype (); - if (tb1->ty == Tclass) + if (tb1->ty == TY::Tclass) { /* For class object references, if there is a destructor for that class, the destructor is called for the object instance. */ @@ -1480,7 +1462,7 @@ public: t1 = build_address (t1); this->result_ = build_libcall (libcall, Type::tvoid, 1, t1); } - else if (tb1->ty == Tarray) + else if (tb1->ty == TY::Tarray) { /* For dynamic arrays, the garbage collector is called to immediately release the memory. */ @@ -1498,7 +1480,7 @@ public: this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2, build_address (t1), ti); } - else if (tb1->ty == Tpointer) + else if (tb1->ty == TY::Tpointer) { /* For pointers to a struct instance, if the struct has overloaded operator delete, then that operator is called. */ @@ -1533,7 +1515,7 @@ public: void visit (RemoveExp *e) { /* Check that the array is actually an associative array. */ - if (e->e1->type->toBasetype ()->ty == Taarray) + if (e->e1->type->toBasetype ()->ty == TY::Taarray) { Type *tb = e->e1->type->toBasetype (); Type *tkey = tb->isTypeAArray ()->index->toBasetype (); @@ -1569,7 +1551,7 @@ public: void visit (ComExp *e) { TY ty1 = e->e1->type->toBasetype ()->ty; - gcc_assert (ty1 != Tarray && ty1 != Tsarray); + gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray); this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type), build_expr (e->e1)); @@ -1580,7 +1562,7 @@ public: void visit (NegExp *e) { TY ty1 = e->e1->type->toBasetype ()->ty; - gcc_assert (ty1 != Tarray && ty1 != Tsarray); + gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray); tree type = build_ctype (e->type); tree expr = build_expr (e->e1); @@ -1630,7 +1612,7 @@ public: /* Produce better code by converting *(#record + n) to COMPONENT_REFERENCE. Otherwise, the variable will always be allocated in memory because its address is taken. */ - if (tnext && tnext->ty == Tstruct) + if (tnext && tnext->ty == TY::Tstruct) { StructDeclaration *sd = tnext->isTypeStruct ()->sym; @@ -1716,7 +1698,7 @@ public: gcc_assert (var->isFuncDeclaration () && !var->needThis ()); } - if (e1b->op == TOKdotvar && tb->ty != Tdelegate) + if (e1b->op == TOKdotvar && tb->ty != TY::Tdelegate) { DotVarExp *dve = e1b->isDotVarExp (); @@ -1775,7 +1757,7 @@ public: /* C++ constructors return void, even though front-end semantic treats them as implicitly returning `this'. Set returnvalue to override the result of this expression. */ - if (fd->isCtorDeclaration () && fd->linkage == LINKcpp) + if (fd->isCtorDeclaration () && fd->linkage == LINK::cpp) { thisexp = d_save_expr (thisexp); returnvalue = thisexp; @@ -1805,7 +1787,7 @@ public: extract_from_method_call (callee, callee, object); } - else if (tb->ty == Tdelegate) + else if (tb->ty == TY::Tdelegate) { /* Delegate call, extract .object and .funcptr from var. */ callee = d_save_expr (callee); @@ -1850,7 +1832,7 @@ public: if (returnvalue != NULL_TREE) exp = compound_expr (exp, returnvalue); - if (tf->isref) + if (tf->isref ()) exp = build_deref (exp); /* Some library calls are defined to return a generic type. @@ -1888,7 +1870,7 @@ public: tree fndecl; tree object; - if (e->func->isNested ()) + if (e->func->isNested () && !e->func->isThis ()) { if (e->e1->op == TOKnull) object = build_expr (e->e1); @@ -1909,12 +1891,12 @@ public: object = build_expr (e->e1); /* Want reference to `this' object. */ - if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer) + if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer) object = build_address (object); /* Object reference could be the outer `this' field of a class or closure of type `void*'. Cast it to the right type. */ - if (e->e1->type->ty == Tclass) + if (e->e1->type->ty == TY::Tclass) object = d_convert (build_ctype (e->e1->type), object); fndecl = get_symbol_decl (e->func); @@ -1958,7 +1940,7 @@ public: { tree object = build_expr (e->e1); - if (e->e1->type->toBasetype ()->ty != Tstruct) + if (e->e1->type->toBasetype ()->ty != TY::Tstruct) object = build_deref (object); this->result_ = component_ref (object, get_symbol_decl (vd)); @@ -2005,7 +1987,7 @@ public: { /* If the condition is a D class or struct object with an invariant, call it if the condition result is true. */ - if (tb1->ty == Tclass) + if (tb1->ty == TY::Tclass) { ClassDeclaration *cd = tb1->isClassHandle (); if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ()) @@ -2015,7 +1997,8 @@ public: Type::tvoid, 1, arg); } } - else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct) + else if (tb1->ty == TY::Tpointer + && tb1->nextOf ()->ty == TY::Tstruct) { StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym; if (sd->inv != NULL) @@ -2093,7 +2076,7 @@ public: else if (Expression *tid = isExpression (e->obj)) { Type *type = tid->type->toBasetype (); - assert (type->ty == Tclass); + assert (type->ty == TY::Tclass); /* Generate **classptr to get the classinfo. */ tree ci = build_expr (tid); @@ -2117,7 +2100,7 @@ public: Type *ftype = e->type->toBasetype (); /* This check is for lambda's, remove `vthis' as function isn't nested. */ - if (e->fd->tok == TOKreserved && ftype->ty == Tpointer) + if (e->fd->tok == TOKreserved && ftype->ty == TY::Tpointer) { e->fd->tok = TOKfunction; e->fd->vthis = NULL; @@ -2226,7 +2209,7 @@ public: tree init = NULL_TREE; if (var && (var->isConst () || var->isImmutable ()) - && e->type->toBasetype ()->ty != Tsarray && var->_init) + && e->type->toBasetype ()->ty != TY::Tsarray && var->_init) { if (var->inuse) error_at (make_location_t (e->loc), "recursive reference %qs", @@ -2279,7 +2262,7 @@ public: result = get_decl_tree (fd->vthis); } - if (e->type->ty == Tstruct) + if (e->type->ty == TY::Tstruct) result = build_deref (result); this->result_ = result; @@ -2293,10 +2276,7 @@ public: Type *tb = e->type->toBasetype (); tree result; - if (e->allocator) - gcc_assert (e->newargs); - - if (tb->ty == Tclass) + if (tb->ty == TY::Tclass) { /* Allocating a new class. */ tb = e->newtype->toBasetype (); @@ -2315,20 +2295,13 @@ public: new_call = build_nop (type, build_address (var)); setup_exp = modify_expr (var, aggregate_initializer_decl (cd)); } - else if (e->allocator) - { - /* Call class allocator, and copy the initializer into memory. */ - new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs); - new_call = d_save_expr (new_call); - new_call = build_nop (type, new_call); - setup_exp = modify_expr (build_deref (new_call), - aggregate_initializer_decl (cd)); - } else { /* Generate: _d_newclass() */ tree arg = build_address (get_classinfo_decl (cd)); - new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg); + libcall_fn libcall = (global.params.ehnogc && e->thrownew) + ? LIBCALL_NEWTHROW : LIBCALL_NEWCLASS; + new_call = build_libcall (libcall, tb, 1, arg); } /* Set the context pointer for nested classes. */ @@ -2340,13 +2313,15 @@ public: if (e->thisexp) { ClassDeclaration *tcd = e->thisexp->type->isClassHandle (); - Dsymbol *outer = cd->toParent2 (); - int offset = 0; + /* The class or function we're nested in. */ + Dsymbol *outer = cd->toParentLocal (); value = build_expr (e->thisexp); + if (outer != tcd) { ClassDeclaration *ocd = outer->isClassDeclaration (); + int offset = 0; gcc_assert (ocd->isBaseOf (tcd, &offset)); /* Could just add offset... */ value = convert_expr (value, e->thisexp->type, ocd->type); @@ -2375,7 +2350,8 @@ public: if (e->argprefix) result = compound_expr (build_expr (e->argprefix), result); } - else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct) + else if (tb->ty == TY::Tpointer + && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct) { /* Allocating memory for a new struct. */ Type *htype = e->newtype->toBasetype (); @@ -2393,20 +2369,11 @@ public: return; } - if (e->allocator) - { - /* Call struct allocator. */ - new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs); - new_call = build_nop (build_ctype (tb), new_call); - } - else - { - /* Generate: _d_newitemT() */ - libcall_fn libcall = htype->isZeroInit () - ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; - tree arg = build_typeinfo (e->loc, e->newtype); - new_call = build_libcall (libcall, tb, 1, arg); - } + /* Generate: _d_newitemT() */ + libcall_fn libcall = htype->isZeroInit () + ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; + tree arg = build_typeinfo (e->loc, e->newtype); + new_call = build_libcall (libcall, tb, 1, arg); if (e->member || !e->arguments) { @@ -2449,13 +2416,12 @@ public: if (e->argprefix) result = compound_expr (build_expr (e->argprefix), result); } - else if (tb->ty == Tarray) + else if (tb->ty == TY::Tarray) { /* Allocating memory for a new D array. */ tb = e->newtype->toBasetype (); TypeDArray *tarray = tb->isTypeDArray (); - gcc_assert (!e->allocator); gcc_assert (e->arguments && e->arguments->length >= 1); if (e->arguments->length == 1) @@ -2492,7 +2458,7 @@ public: Expression *arg = (*e->arguments)[i]; CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg)); - gcc_assert (telem->ty == Tarray); + gcc_assert (telem->ty == TY::Tarray); telem = telem->toBasetype ()->nextOf (); gcc_assert (telem); } @@ -2517,7 +2483,7 @@ public: if (e->argprefix) result = compound_expr (build_expr (e->argprefix), result); } - else if (tb->ty == Tpointer) + else if (tb->ty == TY::Tpointer) { /* Allocating memory for a new pointer. */ TypePointer *tpointer = tb->isTypePointer (); @@ -2576,15 +2542,15 @@ public: switch (e->type->toBasetype ()->ty) { - case Tcomplex32: + case TY::Tcomplex32: tnext = (TypeBasic *) Type::tfloat32; break; - case Tcomplex64: + case TY::Tcomplex64: tnext = (TypeBasic *) Type::tfloat64; break; - case Tcomplex80: + case TY::Tcomplex80: tnext = (TypeBasic *) Type::tfloat80; break; @@ -2605,7 +2571,7 @@ public: Type *tb = e->type->toBasetype (); tree type = build_ctype (e->type); - if (tb->ty == Tsarray) + if (tb->ty == TY::Tsarray) { /* Turn the string into a constructor for the static array. */ vec *elms = NULL; @@ -2635,7 +2601,7 @@ public: TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1); value = build_address (value); - if (tb->ty == Tarray) + if (tb->ty == TY::Tarray) value = d_array_value (type, size_int (e->len), value); TREE_CONSTANT (value) = 1; @@ -2674,15 +2640,16 @@ public: Type *tb = e->type->toBasetype (); /* Implicitly convert void[n] to ubyte[n]. */ - if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid) + if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid) tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ()); - gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer); + gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray + || tb->ty == TY::Tpointer); /* Handle empty array literals. */ if (e->elements->length == 0) { - if (tb->ty == Tarray) + if (tb->ty == TY::Tarray) this->result_ = d_array_value (build_ctype (e->type), size_int (0), null_pointer_node); else @@ -2732,15 +2699,15 @@ public: tree type = build_ctype (e->type); /* Nothing else to do for static arrays. */ - if (tb->ty == Tsarray || this->constp_) + if (tb->ty == TY::Tsarray || this->constp_) { /* Can't take the address of the constructor, so create an anonymous static symbol, and then refer to it. */ - if (tb->ty != Tsarray) + if (tb->ty != TY::Tsarray) { tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A"); ctor = build_address (decl); - if (tb->ty == Tarray) + if (tb->ty == TY::Tarray) ctor = d_array_value (type, size_int (e->elements->length), ctor); d_pushdecl (decl); @@ -2789,7 +2756,7 @@ public: /* Return the array pointed to by MEM. */ result = compound_expr (result, mem); - if (tb->ty == Tarray) + if (tb->ty == TY::Tarray) result = d_array_value (type, size_int (e->elements->length), result); this->result_ = compound_expr (saved_elems, result); @@ -2882,7 +2849,7 @@ public: gcc_assert (e->elements->length <= e->sd->fields.length); Type *tb = e->type->toBasetype (); - gcc_assert (tb->ty == Tstruct); + gcc_assert (tb->ty == TY::Tstruct); for (size_t i = 0; i < e->elements->length; i++) { @@ -2895,7 +2862,7 @@ public: Type *ftype = field->type->toBasetype (); tree value = NULL_TREE; - if (ftype->ty == Tsarray && !same_type_p (type, ftype)) + if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype)) { /* Initialize a static array with a single element. */ tree elem = build_expr (exp, this->constp_, true); @@ -3126,7 +3093,7 @@ build_return_dtor (Expression *e, Type *type, TypeFunction *tf) tree result = build_expr (e); /* Convert for initializing the DECL_RESULT. */ - if (tf->isref) + if (tf->isref ()) { /* If we are returning a reference, take the address. */ result = convert_expr (result, e->type, type); diff --git a/gcc/d/imports.cc b/gcc/d/imports.cc index 2288843c61a..740a020321c 100644 --- a/gcc/d/imports.cc +++ b/gcc/d/imports.cc @@ -68,7 +68,7 @@ public: void visit (Module *m) { Loc loc = (m->md != NULL) ? m->md->loc - : Loc (m->srcfile->toChars (), 1, 0); + : Loc (m->srcfile.toChars (), 1, 0); m->isym = build_decl (make_location_t (loc), NAMESPACE_DECL, get_identifier (m->toPrettyChars ()), @@ -130,11 +130,11 @@ public: /* Type imports should really be part of their own visit method. */ if (type != NULL) { - if (type->ty == Tenum) + if (type->ty == TY::Tenum) dsym = type->isTypeEnum ()->sym; - else if (type->ty == Tstruct) + else if (type->ty == TY::Tstruct) dsym = type->isTypeStruct ()->sym; - else if (type->ty == Tclass) + else if (type->ty == TY::Tclass) dsym = type->isTypeClass ()->sym; } } diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc index 539dc0c1f37..b14b0ca5111 100644 --- a/gcc/d/intrinsics.cc +++ b/gcc/d/intrinsics.cc @@ -20,9 +20,9 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "dmd/declaration.h" +#include "dmd/expression.h" #include "dmd/identifier.h" #include "dmd/mangle.h" -#include "dmd/mangle.h" #include "dmd/module.h" #include "dmd/template.h" @@ -76,12 +76,12 @@ static const intrinsic_decl intrinsic_decls[] = void maybe_set_intrinsic (FuncDeclaration *decl) { - if (!decl->ident || decl->builtin != BUILTINunknown) + if (!decl->ident || decl->builtin != BUILTIN::unknown) return; /* The builtin flag is updated only if we can evaluate the intrinsic at compile-time. Such as the math or bitop intrinsics. */ - decl->builtin = BUILTINunimp; + decl->builtin = BUILTIN::unimp; /* Check if it's a compiler intrinsic. We only require that any internally recognised intrinsics are declared in a module with @@ -177,12 +177,12 @@ maybe_set_intrinsic (FuncDeclaration *decl) built-in function. It could be `int pow(int, int)'. */ tree rettype = TREE_TYPE (TREE_TYPE (decl->csym)); if (mathfn_built_in (rettype, BUILT_IN_POW) != NULL_TREE) - decl->builtin = BUILTINgcc; + decl->builtin = BUILTIN::gcc; break; } default: - decl->builtin = BUILTINgcc; + decl->builtin = BUILTIN::gcc; break; } diff --git a/gcc/d/intrinsics.def b/gcc/d/intrinsics.def index f5af2a5fe5c..1f350f3c236 100644 --- a/gcc/d/intrinsics.def +++ b/gcc/d/intrinsics.def @@ -77,12 +77,12 @@ DEF_D_BUILTIN (INTRINSIC_POPCNT32, BUILT_IN_NONE, "popcnt", "core.bitop", DEF_D_BUILTIN (INTRINSIC_POPCNT64, BUILT_IN_NONE, "popcnt", "core.bitop", "FNaNbNiNfmZi") -DEF_D_BUILTIN (INTRINSIC_ROL, BUILT_IN_NONE, "rol", "core.bitop", "FNaI1TkZI1T") +DEF_D_BUILTIN (INTRINSIC_ROL, BUILT_IN_NONE, "rol", "core.bitop", "FNa@1TkZ@1T") DEF_D_BUILTIN (INTRINSIC_ROL_TIARG, BUILT_IN_NONE, "rol", "core.bitop", - "FNaI1TZI1T") -DEF_D_BUILTIN (INTRINSIC_ROR, BUILT_IN_NONE, "ror", "core.bitop", "FNaI1TkZI1T") + "FNa@1TZ@1T") +DEF_D_BUILTIN (INTRINSIC_ROR, BUILT_IN_NONE, "ror", "core.bitop", "FNa@1TkZ@1T") DEF_D_BUILTIN (INTRINSIC_ROR_TIARG, BUILT_IN_NONE, "ror", "core.bitop", - "FNaI1TZI1T") + "FNa@1TZ@1T") /* core.volatile intrinsics. */ @@ -183,75 +183,74 @@ DEF_D_BUILTIN (INTRINSIC_SQRT, BUILT_IN_SQRT, "sqrt", "core.math", DEF_D_BUILTIN (INTRINSIC_SQRTL, BUILT_IN_SQRTL, "sqrt", "core.math", "FNaNbNiNfeZe") DEF_D_BUILTIN (INTRINSIC_TOPRECF, BUILT_IN_NONE, "toPrec", "core.math", - "FfZI1T") -DEF_D_BUILTIN (INTRINSIC_TOPREC, BUILT_IN_NONE, "toPrec", "core.math", "FdZI1T") + "FfZ@1T") +DEF_D_BUILTIN (INTRINSIC_TOPREC, BUILT_IN_NONE, "toPrec", "core.math", "FdZ@1T") DEF_D_BUILTIN (INTRINSIC_TOPRECL, BUILT_IN_NONE, "toPrec", "core.math", - "FeZI1T") + "FeZ@1T") /* std.math intrinsics. */ -DEF_CTFE_BUILTIN (INTRINSIC_TAN, BUILT_IN_TANL, "tan", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_TAN, BUILT_IN_TANL, "tan", "std.math.trigonometry", "FNaNbNiNeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_ISNAN, BUILT_IN_ISNAN, "isNaN", "std.math", - "FNaNbNiNeI1XZb") + +DEF_CTFE_BUILTIN (INTRINSIC_ISNAN, BUILT_IN_ISNAN, "isNaN", "std.math.traits", + "FNaNbNiNe@1XZb") DEF_CTFE_BUILTIN (INTRINSIC_ISINFINITY, BUILT_IN_ISINF, "isInfinity", - "std.math", "FNaNbNiNeI1XZb") -DEF_CTFE_BUILTIN (INTRINSIC_ISFINITE, BUILT_IN_ISFINITE, "isFinite", "std.math", - "FNaNbNiNeI1XZb") + "std.math.traits", "FNaNbNiNe@1XZb") +DEF_CTFE_BUILTIN (INTRINSIC_ISFINITE, BUILT_IN_ISFINITE, "isFinite", + "std.math.traits", "FNaNbNiNe@1XZb") +DEF_CTFE_BUILTIN (INTRINSIC_COPYSIGN, BUILT_IN_NONE, "copysign", + "std.math.traits", "FNaNbNiNe@1R@1XZ@1R") +DEF_CTFE_BUILTIN (INTRINSIC_COPYSIGNI, BUILT_IN_NONE, "copysign", + "std.math.traits", "FNaNbNiNe@1X@1RZ@1R") -DEF_CTFE_BUILTIN (INTRINSIC_EXP, BUILT_IN_EXPL, "exp", "std.math", - "FNaNbNiNeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_EXPM1, BUILT_IN_EXPM1L, "expm1", "std.math", - "FNaNbNiNeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_EXP2, BUILT_IN_EXP2L, "exp2", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_EXP, BUILT_IN_EXPL, "exp", "std.math.exponential", "FNaNbNiNeeZe") - -DEF_CTFE_BUILTIN (INTRINSIC_LOG, BUILT_IN_LOGL, "log", "std.math", - "FNaNbNiNfeZe") -DEF_CTFE_BUILTIN (INTRINSIC_LOG2, BUILT_IN_LOG2L, "log2", "std.math", - "FNaNbNiNfeZe") -DEF_CTFE_BUILTIN (INTRINSIC_LOG10, BUILT_IN_LOG10L, "log10", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_EXPM1, BUILT_IN_EXPM1L, "expm1", + "std.math.exponential", "FNaNbNiNeeZe") +DEF_CTFE_BUILTIN (INTRINSIC_EXP2, BUILT_IN_EXP2L, "exp2", + "std.math.exponential", "FNaNbNiNeeZe") +DEF_CTFE_BUILTIN (INTRINSIC_LOG, BUILT_IN_LOGL, "log", "std.math.exponential", "FNaNbNiNfeZe") +DEF_CTFE_BUILTIN (INTRINSIC_LOG2, BUILT_IN_LOG2L, "log2", + "std.math.exponential", "FNaNbNiNfeZe") +DEF_CTFE_BUILTIN (INTRINSIC_LOG10, BUILT_IN_LOG10L, "log10", + "std.math.exponential", "FNaNbNiNfeZe") +DEF_CTFE_BUILTIN (INTRINSIC_POW, BUILT_IN_NONE, "pow", "std.math.exponential", + "FNaNbNiNe@1F@1GZ@") -DEF_CTFE_BUILTIN (INTRINSIC_ROUND, BUILT_IN_ROUNDL, "round", "std.math", - "FNbNiNeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_FLOORF, BUILT_IN_FLOORF, "floor", "std.math", - "FNaNbNiNefZf") -DEF_CTFE_BUILTIN (INTRINSIC_FLOOR, BUILT_IN_FLOOR, "floor", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_ROUND, BUILT_IN_ROUNDL, "round", + "std.math.rounding", "FNaNbNiNeeZe") +DEF_CTFE_BUILTIN (INTRINSIC_FLOORF, BUILT_IN_FLOORF, "floor", + "std.math.rounding", "FNaNbNiNefZf") +DEF_CTFE_BUILTIN (INTRINSIC_FLOOR, BUILT_IN_FLOOR, "floor", "std.math.rounding", "FNaNbNiNedZd") -DEF_CTFE_BUILTIN (INTRINSIC_FLOORL, BUILT_IN_FLOORL, "floor", "std.math", - "FNaNbNiNeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_CEILF, BUILT_IN_CEILF, "ceil", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_FLOORL, BUILT_IN_FLOORL, "floor", + "std.math.rounding", "FNaNbNiNeeZe") +DEF_CTFE_BUILTIN (INTRINSIC_CEILF, BUILT_IN_CEILF, "ceil", "std.math.rounding", "FNaNbNiNefZf") -DEF_CTFE_BUILTIN (INTRINSIC_CEIL, BUILT_IN_CEIL, "ceil", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_CEIL, BUILT_IN_CEIL, "ceil", "std.math.rounding", "FNaNbNiNedZd") -DEF_CTFE_BUILTIN (INTRINSIC_CEILL, BUILT_IN_CEILL, "ceil", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_CEILL, BUILT_IN_CEILL, "ceil", "std.math.rounding", "FNaNbNiNeeZe") +DEF_CTFE_BUILTIN (INTRINSIC_TRUNC, BUILT_IN_TRUNCL, "trunc", + "std.math.rounding", "FNaNbNiNeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_TRUNC, BUILT_IN_TRUNCL, "trunc", "std.math", - "FNbNiNeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_FMIN, BUILT_IN_FMINL, "fmin", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_FMIN, BUILT_IN_FMINL, "fmin", "std.math.operations", "FNaNbNiNfeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_FMAX, BUILT_IN_FMAXL, "fmax", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_FMAX, BUILT_IN_FMAXL, "fmax", "std.math.operations", "FNaNbNiNfeeZe") -DEF_CTFE_BUILTIN (INTRINSIC_COPYSIGN, BUILT_IN_NONE, "copysign", "std.math", - "FNaNbNiNeI1RI1XZI1R") -DEF_CTFE_BUILTIN (INTRINSIC_COPYSIGNI, BUILT_IN_NONE, "copysign", "std.math", - "FNaNbNiNeI1XI1RZI1R") - -DEF_CTFE_BUILTIN (INTRINSIC_POW, BUILT_IN_NONE, "pow", "std.math", - "FNaNbNiNeI1FI1GZ@") -DEF_CTFE_BUILTIN (INTRINSIC_FMA, BUILT_IN_FMAL, "fma", "std.math", +DEF_CTFE_BUILTIN (INTRINSIC_FMA, BUILT_IN_FMAL, "fma", "std.math.operations", "FNaNbNiNfeeeZe") /* core.stdc.stdarg intrinsics. */ DEF_D_BUILTIN (INTRINSIC_VA_ARG, BUILT_IN_NONE, "va_arg", "core.stdc.stdarg", - "FKI7va_listKI1TZv") + "FK@7va_listK@1TZv") DEF_D_BUILTIN (INTRINSIC_C_VA_ARG, BUILT_IN_NONE, "va_arg", "core.stdc.stdarg", - "FKI7va_listZI1T") + "FK@7va_listZ@1T") DEF_D_BUILTIN (INTRINSIC_VASTART, BUILT_IN_NONE, "va_start", "core.stdc.stdarg", - "FJI7va_listKI1TZv") + "FJ@7va_listK@1TZv") #undef DEF_D_BUILTIN #undef DEF_CTFE_BUILTIN diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt index ded218fc5e3..f7f90fb08c3 100644 --- a/gcc/d/lang.opt +++ b/gcc/d/lang.opt @@ -209,6 +209,40 @@ fbuiltin D Var(flag_no_builtin, 0) ; Documented in C +fcheck=assert +D Alias(fassert) + +fcheck=bounds +D Alias(fbounds-check) + +fcheck=in +D Alias(fpreconditions) + +fcheck=invariant +D Alias(finvariants) + +fcheck=out +D Alias(fpostconditions) + +fcheck=switch +D Alias(fswitch-errors) + +fcheckaction= +D Joined RejectNegative Enum(check_action) Var(flag_check_action) +-fcheckaction=[throw,halt,context] Behavior on contract failure. + +Enum +Name(check_action) Type(int) UnknownError(unknown checkaction setting %qs) + +EnumValue +Enum(check_action) String(throw) Value(0) + +EnumValue +Enum(check_action) String(halt) Value(1) + +EnumValue +Enum(check_action) String(context) Value(2) + fdebug D Compile in debug code. @@ -237,10 +271,43 @@ fdruntime D Assume that standard D runtime libraries and \"D main\" exist. +fdump-c++-spec-verbose +D RejectNegative +Add comments for ignored declarations in the generated C++ header. + +fdump-c++-spec= +D RejectNegative Joined +-fdump-cxx-spec= Write all declarations as C++ code to . + fdump-d-original D Display the frontend AST after parsing and semantic passes. +fextern-std= +D Joined RejectNegative Enum(extern_stdcpp) Var(flag_extern_stdcpp) +-fextern-std= Set C++ name mangling compatibility with . + +Enum +Name(extern_stdcpp) Type(int) UnknownError(unknown C++ standard %qs) + +EnumValue +Enum(extern_stdcpp) String(c++98) Value(199711) + +EnumValue +Enum(extern_stdcpp) String(c++03) Value(199711) + +EnumValue +Enum(extern_stdcpp) String(c++11) Value(201103) + +EnumValue +Enum(extern_stdcpp) String(c++14) Value(201402) + +EnumValue +Enum(extern_stdcpp) String(c++17) Value(201703) + +EnumValue +Enum(extern_stdcpp) String(c++20) Value(202002) + fignore-unknown-pragmas D Ignore unsupported pragmas. @@ -273,33 +340,97 @@ fpreconditions D Var(flag_preconditions) Generate code for precondition contracts. +fpreview=all +D RejectNegative +Turn on all upcoming D language features. + +fpreview=dip1000 +D RejectNegative +Implement DIP1000: Scoped pointers. + +fpreview=dip1008 +D RejectNegative +Implement DIP1008: Allow exceptions in @nogc code. + +fpreview=dip1021 +D RejectNegative +Implement DIP1021: Mutable function arguments. + +fpreview=dip25 +D RejectNegative +Implement DIP25: Sealed references. + +fpreview=dtorfields +D RejectNegative +Destruct fields of partially constructed objects. + +fpreview=fieldwise +D RejectNegative +Use field-wise comparisons for struct equality. + +fpreview=fixaliasthis +D RejectNegative +When a symbol is resolved, check alias this scope before going to upper scopes. + +fpreview=in +D RejectNegative +Implement 'in' parameters to mean scope const. + +fpreview=inclusiveincontracts +D RejectNegative +Implement 'in' contracts of overridden methods to be a superset of parent contract. + +fpreview=intpromote +D RejectNegative +Use C-style integral promotion for unary '+', '-' and '~'. + +fpreview=nosharedaccess +D RejectNegative +Disable access to shared memory objects. + +fpreview=rvaluerefparam +D RejectNegative +Enable rvalue arguments to ref parameters. + +fpreview=shortenedmethods +D RejectNegative +Allow use of '=>' for methods and top-level functions in addition to lambdas. + frelease D Compile release version. +frevert=all +D RejectNegative +Turn off all revertable D language features. + +frevert=dip25 +D RejectNegative +Revert DIP25: Sealed references. + +frevert=dtorfields +D RejectNegative +Don't destruct fields of partially constructed objects. + +frevert=markdown +D RejectNegative +Disable Markdown replacements in Ddoc. + frtti D ; Documented in C +fsave-mixins= +D Joined RejectNegative +-fsave-mixins= Expand and save mixins to file specified by . + fswitch-errors D Var(flag_switch_errors) Generate code for switches without a default case. ftransition=all D RejectNegative -List information on all language changes. - -ftransition=complex -D RejectNegative -List all usages of complex or imaginary types. - -ftransition=dip1000 -D RejectNegative -Implement DIP1000: Scoped pointers (experimental). - -ftransition=dip25 -D RejectNegative -Implement DIP25: Sealed references (experimental). +List information on all D language transitions. ftransition=field D RejectNegative @@ -309,10 +440,18 @@ ftransition=nogc D RejectNegative List all hidden GC allocations. +ftransition=templates +D RejectNegative +List statistics on template instantiations. + ftransition=tls D RejectNegative List all variables going into thread local storage. +ftransition=vmarkdown +D RejectNegative +List instances of Markdown replacements in Ddoc. + funittest D Compile in unittest code. diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc index 8786344d954..06eb5ae3424 100644 --- a/gcc/d/modules.cc +++ b/gcc/d/modules.cc @@ -125,7 +125,7 @@ static Module *current_module_decl; by both module initialization and dso handlers. */ static FuncDeclaration * -get_internal_fn (tree ident, const Prot &prot) +get_internal_fn (tree ident, const Visibility &visibility) { Module *mod = current_module_decl; const char *name = IDENTIFIER_POINTER (ident); @@ -142,9 +142,9 @@ get_internal_fn (tree ident, const Prot &prot) FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid, Identifier::idPool (name)); fd->generated = true; - fd->loc = Loc (mod->srcfile->toChars (), 1, 0); + fd->loc = Loc (mod->srcfile.toChars (), 1, 0); fd->parent = mod; - fd->protection = prot; + fd->visibility = visibility; fd->semanticRun = PASSsemantic3done; return fd; @@ -156,7 +156,9 @@ get_internal_fn (tree ident, const Prot &prot) static tree build_internal_fn (tree ident, tree expr) { - FuncDeclaration *fd = get_internal_fn (ident, Prot (Prot::private_)); + Visibility visibility; + visibility.kind = Visibility::private_; + FuncDeclaration *fd = get_internal_fn (ident, visibility); tree decl = get_symbol_decl (fd); tree old_context = start_function (fd); @@ -338,8 +340,9 @@ build_dso_cdtor_fn (bool ctor_p) } } */ - FuncDeclaration *fd = get_internal_fn (get_identifier (name), - Prot (Prot::public_)); + Visibility visibility; + visibility.kind = Visibility::public_; + FuncDeclaration *fd = get_internal_fn (get_identifier (name), visibility); tree decl = get_symbol_decl (fd); TREE_PUBLIC (decl) = 1; @@ -740,7 +743,8 @@ build_module_tree (Module *decl) /* Associate the module info symbol with a mock module. */ const char *name = concat (GDC_PREFIX ("modtest__"), decl->ident->toChars (), NULL); - Module *tm = Module::create (decl->arg, Identifier::idPool (name), 0, 0); + Module *tm = Module::create (decl->arg.ptr, Identifier::idPool (name), + 0, 0); Dsymbols members; /* Setting parent puts module in the same package as the current, to @@ -780,9 +784,7 @@ build_module_tree (Module *decl) /* Default behavior is to always generate module info because of templates. Can be switched off for not compiling against runtime library. */ - if (global.params.useModuleInfo - && Module::moduleinfo != NULL - && decl->ident != Identifier::idPool ("__entrypoint")) + if (global.params.useModuleInfo && Module::moduleinfo != NULL) { if (mi.ctors || mi.ctorgates) decl->sctor = build_funcs_gates_fn (get_identifier ("*__modctor"), diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def index 0296233f4e2..fdff6db0626 100644 --- a/gcc/d/runtime.def +++ b/gcc/d/runtime.def @@ -34,6 +34,8 @@ along with GCC; see the file COPYING3. If not see 3, LCT_ ## T1, LCT_ ## T2, LCT_ ## T3 #define P4(T1, T2, T3, T4) \ 4, LCT_ ## T1, LCT_ ## T2, LCT_ ## T3, LCT_ ## T4 +#define P5(T1, T2, T3, T4, T5) \ + 5, LCT_ ## T1, LCT_ ## T2, LCT_ ## T3, LCT_ ## T4, LCT_ ## T5 #define RT(T1) LCT_ ## T1 /* Used when an assert() contract fails. */ @@ -51,9 +53,15 @@ DEF_D_RUNTIME (UNITTEST_MSG, "_d_unittest_msg", RT(VOID), /* Used when an array index outside the bounds of its range. */ DEF_D_RUNTIME (ARRAYBOUNDSP, "_d_arrayboundsp", RT(VOID), P2(IMMUTABLE_CHARPTR, UINT), ECF_NORETURN) +DEF_D_RUNTIME (ARRAYBOUNDS_SLICEP, "_d_arraybounds_slicep", RT(VOID), + P5(IMMUTABLE_CHARPTR, UINT, SIZE_T, SIZE_T, SIZE_T), + ECF_NORETURN) +DEF_D_RUNTIME (ARRAYBOUNDS_INDEXP, "_d_arraybounds_indexp", RT(VOID), + P4(IMMUTABLE_CHARPTR, UINT, SIZE_T, SIZE_T), ECF_NORETURN) /* Used when calling new on a class. */ DEF_D_RUNTIME (NEWCLASS, "_d_newclass", RT(OBJECT), P1(CONST_CLASSINFO), 0) +DEF_D_RUNTIME (NEWTHROW, "_d_newThrowable", RT(OBJECT), P1(CONST_CLASSINFO), 0) /* Used when calling delete on a class or interface. */ DEF_D_RUNTIME (DELCLASS, "_d_delclass", RT(VOID), P1(VOIDPTR), 0) @@ -104,13 +112,6 @@ DEF_D_RUNTIME (DELARRAYT, "_d_delarray_t", RT(VOID), arrays. Such as an array of structs or classes. */ DEF_D_RUNTIME (ADEQ2, "_adEq2", RT(INT), P3(ARRAY_VOID, ARRAY_VOID, CONST_TYPEINFO), 0) -DEF_D_RUNTIME (ADCMP2, "_adCmp2", RT(INT), - P3(ARRAY_VOID, ARRAY_VOID, CONST_TYPEINFO), 0) - -/* Used when casting from one array type to another where the index type - sizes differ. Such as from int[] to short[]. */ -DEF_D_RUNTIME (ARRAYCAST, "_d_arraycast", RT(ARRAY_VOID), - P3(SIZE_T, SIZE_T, ARRAY_VOID), 0) /* Used for (array.length = n) expressions. The `i' variant is for when the initializer is nonzero. */ @@ -206,23 +207,10 @@ DEF_D_RUNTIME (CXA_END_CATCH, "__cxa_end_catch", RT(VOID), P0(), 0) DEF_D_RUNTIME (INVARIANT, "_D9invariant12_d_invariantFC6ObjectZv", RT(VOID), P1(OBJECT), 0) -/* Used when performing a switch/cases on a string. The `u' and `d' variants - are for UTF-16 and UTF-32 strings respectively. */ -DEF_D_RUNTIME (SWITCH_STRING, "_d_switch_string", RT(INT), - P2(ARRAY_STRING, STRING), 0) -DEF_D_RUNTIME (SWITCH_USTRING, "_d_switch_ustring", RT(INT), - P2(ARRAY_WSTRING, WSTRING), 0) -DEF_D_RUNTIME (SWITCH_DSTRING, "_d_switch_dstring", RT(INT), - P2(ARRAY_DSTRING, DSTRING), 0) - -/* Used when throwing an error that a switch statement has no default case, - and yet none of the existing cases matched. */ -DEF_D_RUNTIME (SWITCH_ERROR, "_d_switch_error", RT(VOID), P2(STRING, UINT), - ECF_NORETURN) - #undef P0 #undef P1 #undef P2 #undef P3 #undef P4 +#undef P5 #undef RT diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc index 1c9da101f39..55d63f89cb7 100644 --- a/gcc/d/toir.cc +++ b/gcc/d/toir.cc @@ -413,18 +413,6 @@ public: else error_at (location, "cannot % into % block"); } - else if (s->isCaseStatement ()) - { - location = make_location_t (s->loc); - error_at (location, "case cannot be in different " - "% block level from %"); - } - else if (s->isDefaultStatement ()) - { - location = make_location_t (s->loc); - error_at (location, "default cannot be in different " - "% block level from %"); - } else gcc_unreachable (); } @@ -709,7 +697,8 @@ public: { /* The break label may actually be some levels up. eg: on a try/finally wrapping a loop. */ - LabelStatement *label = this->func_->searchLabel (s->ident)->statement; + LabelDsymbol *sym = this->func_->searchLabel (s->ident, s->loc); + LabelStatement *label = sym->statement; gcc_assert (label != NULL); Statement *stmt = label->statement->getRelatedLabeled (); this->do_jump (this->lookup_bc_label (stmt, bc_break)); @@ -725,7 +714,8 @@ public: { if (s->ident) { - LabelStatement *label = this->func_->searchLabel (s->ident)->statement; + LabelDsymbol *sym = this->func_->searchLabel (s->ident, s->loc); + LabelStatement *label = sym->statement; gcc_assert (label != NULL); this->do_jump (this->lookup_bc_label (label->statement, bc_continue)); @@ -759,7 +749,7 @@ public: if (this->is_return_label (s->ident)) sym = this->func_->returnLabel; else - sym = this->func_->searchLabel (s->ident); + sym = this->func_->searchLabel (s->ident, s->loc); /* If no label found, there was an error. */ tree label = this->define_label (sym->statement, sym->ident); @@ -784,69 +774,9 @@ public: tree condition = build_expr_dtor (s->condition); Type *condtype = s->condition->type->toBasetype (); - /* A switch statement on a string gets turned into a library call, - which does a binary lookup on list of string cases. */ - if (s->condition->type->isString ()) - { - Type *etype = condtype->nextOf ()->toBasetype (); - libcall_fn libcall; - - switch (etype->ty) - { - case Tchar: - libcall = LIBCALL_SWITCH_STRING; - break; - - case Twchar: - libcall = LIBCALL_SWITCH_USTRING; - break; - - case Tdchar: - libcall = LIBCALL_SWITCH_DSTRING; - break; - - default: - ::error ("switch statement value must be an array of " - "some character type, not %s", etype->toChars ()); - gcc_unreachable (); - } - - /* Apparently the backend is supposed to sort and set the indexes - on the case array, have to change them to be usable. */ - Type *satype = condtype->sarrayOf (s->cases->length); - vec *elms = NULL; - - s->cases->sort (); - - for (size_t i = 0; i < s->cases->length; i++) - { - CaseStatement *cs = (*s->cases)[i]; - cs->index = i; - - if (cs->exp->op != TOKstring) - s->error ("case '%s' is not a string", cs->exp->toChars ()); - else - { - tree exp = build_expr (cs->exp, true); - CONSTRUCTOR_APPEND_ELT (elms, size_int (i), exp); - } - } - - /* Build static declaration to reference constructor. */ - tree ctor = build_constructor (build_ctype (satype), elms); - tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor); - TREE_READONLY (decl) = 1; - d_pushdecl (decl); - rest_of_decl_compilation (decl, 1, 0); - - /* Pass it as a dynamic array. */ - decl = d_array_value (build_ctype (condtype->arrayOf ()), - size_int (s->cases->length), - build_address (decl)); - - condition = build_libcall (libcall, Type::tint32, 2, decl, condition); - } - else if (!condtype->isscalar ()) + /* A switch statement on a string gets turned into a library call. + It is not lowered during codegen. */ + if (!condtype->isscalar ()) { error ("cannot handle switch condition of type %s", condtype->toChars ()); @@ -992,7 +922,10 @@ public: void visit (SwitchErrorStatement *s) { - add_stmt (build_assert_call (s->loc, LIBCALL_SWITCH_ERROR)); + /* A throw SwitchError statement gets turned into a library call. + The call is wrapped in the enclosed expression. */ + gcc_assert (s->exp != NULL); + add_stmt (build_expr (s->exp)); } /* A return statement exits the current function and supplies its return @@ -1000,7 +933,7 @@ public: void visit (ReturnStatement *s) { - if (s->exp == NULL || s->exp->type->toBasetype ()->ty == Tvoid) + if (s->exp == NULL || s->exp->type->toBasetype ()->ty == TY::Tvoid) { /* Return has no value. */ add_stmt (return_expr (NULL_TREE)); @@ -1012,7 +945,7 @@ public: ? this->func_->tintro->nextOf () : tf->nextOf (); if ((this->func_->isMain () || this->func_->isCMain ()) - && type->toBasetype ()->ty == Tvoid) + && type->toBasetype ()->ty == TY::Tvoid) type = Type::tint32; if (this->func_->shidden) @@ -1020,7 +953,7 @@ public: /* Returning by hidden reference, store the result into the retval decl. The result returned then becomes the retval reference itself. */ tree decl = DECL_RESULT (get_symbol_decl (this->func_)); - gcc_assert (!tf->isref); + gcc_assert (!tf->isref ()); /* If returning via NRVO, just refer to the DECL_RESULT; this differs from using NULL_TREE in that it indicates that we care about the @@ -1096,7 +1029,7 @@ public: add_stmt (return_expr (decl)); } - else if (tf->next->ty == Tnoreturn) + else if (tf->next->ty == TY::Tnoreturn) { /* Returning an expression that has no value, but has a side effect that should never return. */ @@ -1514,7 +1447,7 @@ public: /* If the function has been annotated with `pragma(inline)', then mark the asm expression as being inline as well. */ - if (this->func_->inlining == PINLINEalways) + if (this->func_->inlining == PINLINE::always) ASM_INLINE_P (exp) = 1; add_stmt (exp); diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index fd8c746a307..065f6b3de80 100644 --- a/gcc/d/typeinfo.cc +++ b/gcc/d/typeinfo.cc @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "stor-layout.h" #include "d-tree.h" +#include "d-frontend.h" #include "d-target.h" @@ -110,37 +111,37 @@ get_typeinfo_kind (Type *type) switch (type->ty) { - case Tpointer: + case TY::Tpointer: return TK_POINTER_TYPE; - case Tarray: + case TY::Tarray: return TK_ARRAY_TYPE; - case Tsarray: + case TY::Tsarray: return TK_STATICARRAY_TYPE; - case Taarray: + case TY::Taarray: return TK_ASSOCIATIVEARRAY_TYPE; - case Tstruct: + case TY::Tstruct: return TK_STRUCT_TYPE; - case Tvector: + case TY::Tvector: return TK_VECTOR_TYPE; - case Tenum: + case TY::Tenum: return TK_ENUMERAL_TYPE; - case Tfunction: + case TY::Tfunction: return TK_FUNCTION_TYPE; - case Tdelegate: + case TY::Tdelegate: return TK_DELEGATE_TYPE; - case Ttuple: + case TY::Ttuple: return TK_TYPELIST_TYPE; - case Tclass: + case TY::Tclass: if (type->isTypeClass ()->sym->isInterfaceDeclaration ()) return TK_INTERFACE_TYPE; else @@ -216,7 +217,7 @@ make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL) = ClassDeclaration::create (loc, Identifier::idPool ("Object"), NULL, NULL, true); object->parent = object_module; - object->members = new Dsymbols; + object->members = d_gc_malloc (); object->storage_class |= STCtemp; } @@ -228,7 +229,7 @@ make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL) ClassDeclaration *tinfo = ClassDeclaration::create (loc, ident, NULL, NULL, true); tinfo->parent = object_module; - tinfo->members = new Dsymbols; + tinfo->members = d_gc_malloc (); dsymbolSemantic (tinfo, object_module->_scope); tinfo->baseClass = base; /* This is a compiler generated class, and shouldn't be mistaken for being @@ -836,7 +837,7 @@ public: /* Name of the class declaration. */ const char *name = cd->ident->toChars (); if (!(strlen (name) > 9 && memcmp (name, "TypeInfo_", 9) == 0)) - name = cd->toPrettyChars (); + name = cd->toPrettyChars (true); this->layout_string (name); /* The vtable of the class declaration. */ @@ -857,7 +858,7 @@ public: this->layout_field (base); /* void *destructor; */ - tree dtor = (cd->dtor) ? build_address (get_symbol_decl (cd->dtor)) + tree dtor = (cd->tidtor) ? build_address (get_symbol_decl (cd->tidtor)) : null_pointer_node; this->layout_field (dtor); @@ -911,10 +912,7 @@ public: this->layout_field (build_integer_cst (flags, d_uint_type)); /* void *deallocator; */ - tree ddtor = (cd->aggDelete) - ? build_address (get_symbol_decl (cd->aggDelete)) - : null_pointer_node; - this->layout_field (ddtor); + this->layout_field (null_pointer_node); /* OffsetTypeInfo[] m_offTi; (not implemented) */ this->layout_field (null_array_node); @@ -942,7 +940,7 @@ public: this->layout_field (null_array_node); /* Name of the interface declaration. */ - this->layout_string (cd->toPrettyChars ()); + this->layout_string (cd->toPrettyChars (true)); /* No vtable for interface declaration. */ this->layout_field (null_array_node); @@ -1024,7 +1022,7 @@ public: /* Layout of TypeInfo_Struct is: void **__vptr; void *__monitor; - string name; + string mangledName; void[] m_init; hash_t function(in void*) xtoHash; bool function(in void*, in void*) xopEquals; @@ -1047,8 +1045,8 @@ public: if (!sd->members) return; - /* Name of the struct declaration. */ - this->layout_string (sd->toPrettyChars ()); + /* Mangled name of the struct declaration. */ + this->layout_string (ti->deco); /* Default initializer for struct. */ tree ptr = (sd->zeroInit) ? null_pointer_node @@ -1064,7 +1062,7 @@ public: if (sd->xhash) { TypeFunction *tf = sd->xhash->type->toTypeFunction (); - if (!tf->isnothrow || tf->trust == TRUSTsystem) + if (!tf->isnothrow () || tf->trust == TRUST::system) { warning (sd->xhash->loc, "toHash() must be declared as " "extern (D) size_t toHash() const nothrow @safe, " @@ -1096,7 +1094,7 @@ public: this->layout_field (build_integer_cst (m_flags, d_uint_type)); /* void function(void*) xdtor; */ - tree dtor = (sd->dtor) ? build_address (get_symbol_decl (sd->dtor)) + tree dtor = (sd->tidtor) ? build_address (get_symbol_decl (sd->tidtor)) : null_pointer_node; this->layout_field (dtor); @@ -1298,17 +1296,17 @@ layout_classinfo_interfaces (ClassDeclaration *decl) static bool builtin_typeinfo_p (Type *type) { - if (type->isTypeBasic () || type->ty == Tclass || type->ty == Tnull) + if (type->isTypeBasic () || type->ty == TY::Tclass || type->ty == TY::Tnull) return !type->mod; - if (type->ty == Tarray) + if (type->ty == TY::Tarray) { /* Strings are so common, make them builtin. */ Type *next = type->nextOf (); return !type->mod && ((next->isTypeBasic () != NULL && !next->mod) - || (next->ty == Tchar && next->mod == MODimmutable) - || (next->ty == Tchar && next->mod == MODconst)); + || (next->ty == TY::Tchar && next->mod == MODimmutable) + || (next->ty == TY::Tchar && next->mod == MODconst)); } return false; @@ -1361,7 +1359,7 @@ get_typeinfo_decl (TypeInfoDeclaration *decl) if (decl->csym) return decl->csym; - gcc_assert (decl->tinfo->ty != Terror); + gcc_assert (decl->tinfo->ty != TY::Terror); TypeInfoDeclVisitor v = TypeInfoDeclVisitor (); decl->accept (&v); @@ -1436,7 +1434,7 @@ check_typeinfo_type (const Loc &loc, Scope *sc) tree build_typeinfo (const Loc &loc, Type *type) { - gcc_assert (type->ty != Terror); + gcc_assert (type->ty != TY::Terror); check_typeinfo_type (loc, NULL); create_typeinfo (type, NULL); return build_address (get_typeinfo_decl (type->vtinfo)); diff --git a/gcc/d/types.cc b/gcc/d/types.cc index fc8a1330696..db500ee2efe 100644 --- a/gcc/d/types.cc +++ b/gcc/d/types.cc @@ -94,7 +94,7 @@ bool valist_array_p (Type *type) { Type *tvalist = target.va_listType (Loc (), NULL); - if (tvalist->ty == Tsarray) + if (tvalist->ty == TY::Tsarray) { Type *tb = type->toBasetype (); if (same_type_p (tb, tvalist)) @@ -170,7 +170,7 @@ make_array_type (Type *type, unsigned HOST_WIDE_INT size) { /* In [arrays/void-arrays], void arrays can also be static, the length is specified in bytes. */ - if (type->toBasetype ()->ty == Tvoid) + if (type->toBasetype ()->ty == TY::Tvoid) type = Type::tuns8; /* In [arrays/static-arrays], a static array with a dimension of 0 is allowed, @@ -546,9 +546,9 @@ merge_aggregate_types (Type *type, tree deco) { AggregateDeclaration *sym; - if (type->ty == Tstruct) + if (type->ty == TY::Tstruct) sym = type->isTypeStruct ()->sym; - else if (type->ty == Tclass) + else if (type->ty == TY::Tclass) sym = type->isTypeClass ()->sym; else gcc_unreachable (); @@ -646,31 +646,31 @@ public: switch (t->ty) { - case Tvoid: t->ctype = void_type_node; break; - case Tbool: t->ctype = d_bool_type; break; - case Tint8: t->ctype = d_byte_type; break; - case Tuns8: t->ctype = d_ubyte_type; break; - case Tint16: t->ctype = d_short_type; break; - case Tuns16: t->ctype = d_ushort_type; break; - case Tint32: t->ctype = d_int_type; break; - case Tuns32: t->ctype = d_uint_type; break; - case Tint64: t->ctype = d_long_type; break; - case Tuns64: t->ctype = d_ulong_type; break; - case Tint128: t->ctype = d_cent_type; break; - case Tuns128: t->ctype = d_ucent_type; break; - case Tfloat32: t->ctype = float_type_node; break; - case Tfloat64: t->ctype = double_type_node; break; - case Tfloat80: t->ctype = long_double_type_node; break; - case Timaginary32: t->ctype = ifloat_type_node; break; - case Timaginary64: t->ctype = idouble_type_node; break; - case Timaginary80: t->ctype = ireal_type_node; break; - case Tcomplex32: t->ctype = complex_float_type_node; break; - case Tcomplex64: t->ctype = complex_double_type_node; break; - case Tcomplex80: t->ctype = complex_long_double_type_node; break; - case Tchar: t->ctype = char8_type_node; break; - case Twchar: t->ctype = char16_type_node; break; - case Tdchar: t->ctype = char32_type_node; break; - default: gcc_unreachable (); + case TY::Tvoid: t->ctype = void_type_node; break; + case TY::Tbool: t->ctype = d_bool_type; break; + case TY::Tint8: t->ctype = d_byte_type; break; + case TY::Tuns8: t->ctype = d_ubyte_type; break; + case TY::Tint16: t->ctype = d_short_type; break; + case TY::Tuns16: t->ctype = d_ushort_type; break; + case TY::Tint32: t->ctype = d_int_type; break; + case TY::Tuns32: t->ctype = d_uint_type; break; + case TY::Tint64: t->ctype = d_long_type; break; + case TY::Tuns64: t->ctype = d_ulong_type; break; + case TY::Tint128: t->ctype = d_cent_type; break; + case TY::Tuns128: t->ctype = d_ucent_type; break; + case TY::Tfloat32: t->ctype = float_type_node; break; + case TY::Tfloat64: t->ctype = double_type_node; break; + case TY::Tfloat80: t->ctype = long_double_type_node; break; + case TY::Timaginary32: t->ctype = ifloat_type_node; break; + case TY::Timaginary64: t->ctype = idouble_type_node; break; + case TY::Timaginary80: t->ctype = ireal_type_node; break; + case TY::Tcomplex32: t->ctype = complex_float_type_node; break; + case TY::Tcomplex64: t->ctype = complex_double_type_node; break; + case TY::Tcomplex80: t->ctype = complex_long_double_type_node; break; + case TY::Tchar: t->ctype = char8_type_node; break; + case TY::Twchar: t->ctype = char16_type_node; break; + case TY::Tdchar: t->ctype = char32_type_node; break; + default: gcc_unreachable (); } TYPE_NAME (t->ctype) = get_identifier (t->toChars ()); @@ -786,7 +786,7 @@ public: if (t->next != NULL) { fntype = build_ctype (t->next); - if (t->isref) + if (t->isref ()) fntype = build_reference_type (fntype); } else @@ -800,7 +800,7 @@ public: /* Handle any special support for calling conventions. */ switch (t->linkage) { - case LINKwindows: + case LINK::windows: { /* [attribute/linkage] @@ -815,10 +815,10 @@ public: break; } - case LINKc: - case LINKcpp: - case LINKd: - case LINKobjc: + case LINK::c: + case LINK::cpp: + case LINK::d: + case LINK::objc: /* [abi/function-calling-conventions] The extern (C) and extern (D) calling convention matches @@ -1013,8 +1013,8 @@ public: TYPE_CONTEXT (t->ctype) = d_decl_context (t->sym); build_type_decl (t->ctype, t->sym); - /* For structs with a user defined postblit or a destructor, - also set TREE_ADDRESSABLE on the type and all variants. + /* For structs with a user defined postblit, copy constructor, or a + destructor, also set TREE_ADDRESSABLE on the type and all variants. This will make the struct be passed around by reference. */ if (!t->sym->isPOD ()) { diff --git a/gcc/d/verstr.h b/gcc/d/verstr.h deleted file mode 100644 index 0dd41eeaebe..00000000000 --- a/gcc/d/verstr.h +++ /dev/null @@ -1 +0,0 @@ -"2.076.1"