From 326e097ea9f943be91e298e47ca359dd6136bc58 Mon Sep 17 00:00:00 2001 From: Jacob Carlborg Date: Sun, 28 May 2017 20:03:28 +0200 Subject: [PATCH] Replace idgen with CTFE implementation Since id.h is not necessary anymore in DMD it's just as easy to implement the same functionality using CTFE. This will also simplify the build process because one extra build step is removed. `extern(C++)` is removed as well because it will only be called from within D code in DMD. Other compilers should keep their own cache if they want to. --- .gitignore | 2 - src/ddmd/{idgen.d => id.d} | 179 ++++++++++++++++---------------- src/posix.mak | 15 +-- src/vcbuild/dmd.visualdproj | 23 +--- src/vcbuild/dmd_backend.vcxproj | 16 +-- src/win32.mak | 9 +- 6 files changed, 98 insertions(+), 146 deletions(-) rename src/ddmd/{idgen.d => id.d} (78%) diff --git a/.gitignore b/.gitignore index c496bd8d03..fe76d8f6e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ *.[oa] *.deps src/dmd -src/ddmd/id.d -src/ddmd/id.h test/test_results test/trace.def test/trace.log diff --git a/src/ddmd/idgen.d b/src/ddmd/id.d similarity index 78% rename from src/ddmd/idgen.d rename to src/ddmd/id.d index 2ec2aa47f3..98fe739591 100644 --- a/src/ddmd/idgen.d +++ b/src/ddmd/id.d @@ -2,28 +2,51 @@ * Compiler implementation of the * $(LINK2 http://www.dlang.org, D programming language). * + * This module contains the `Id` struct with a list of predefined symbols the + * compiler knows about. + * * Copyright: Copyright (c) 1999-2017 by Digital Mars, All Rights Reserved * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) - * Source: $(DMDSRC _idgen.d) + * Source: $(DMDSRC _id.d) */ +module ddmd.id; -// Program to generate string files in d data structures. -// Saves much tedious typing, and eliminates typo problems. -// Generates: -// id.h -// id.c +import ddmd.identifier; +import ddmd.tokens; -import core.stdc.stdio; -import core.stdc.stdlib; - -struct Msgtable +/** + * Represents a list of predefined symbols the compiler knows about. + * + * All static fields in this struct represents a specific predefined symbol. + */ +struct Id { - const(char)* ident; // name to use in DMD source - const(char)* name; // name in D executable -}; + static __gshared: -Msgtable[] msgtable = + mixin(msgtable.generate(&identifier)); + + /** + * Populates the identifier pool with all predefined symbols. + * + * An identifier that corresponds to each static field in this struct will + * be placed in the identifier pool. + */ + void initialize() + { + mixin(msgtable.generate(&initializer)); + } +} + +private: + + +/** + * Each element in this array will generate one static field in the `Id` struct + * and a call to `Identifier.idPool` to populate the identifier pool in the + * `Id.initialize` method. + */ +immutable Msgtable[] msgtable = [ { "IUnknown" }, { "Object" }, @@ -372,82 +395,60 @@ Msgtable[] msgtable = ]; -int main() +/* + * Tuple of DMD source code identifier and symbol in the D executable. + * + * The first element of the tuple is the identifier to use in the DMD source + * code and the second element, if present, is the name to use in the D + * executable. If second element, `name`, is not present the identifier, + * `ident`, will be used instead + */ +struct Msgtable { + // The identifier to use in the DMD source. + string ident; + + // The name to use in the D executable + private string name_; + + /* + * Returns: the name to use in the D executable, `name_` if non-empty, + * otherwise `ident` + */ + string name() { - auto fp = fopen("ddmd/id.h","wb"); - if (!fp) - { - printf("can't open ddmd/id.h\n"); - exit(EXIT_FAILURE); - } - - fprintf(fp, "// File generated by idgen.d\n"); - fprintf(fp, "#ifndef DMD_ID_H\n"); - fprintf(fp, "#define DMD_ID_H 1\n"); - fprintf(fp, "class Identifier;\n"); - fprintf(fp, "struct Id\n"); - fprintf(fp, "{\n"); - - foreach(e; msgtable) - { - auto id = e.ident; - fprintf(fp," static Identifier *%s;\n", id); - } - - fprintf(fp, " static void initialize();\n"); - fprintf(fp, "};\n"); - fprintf(fp, "#endif\n"); - - fclose(fp); + return name_ ? name_ : ident; } - - { - auto fp = fopen("ddmd/id.d","wb"); - if (!fp) - { - printf("can't open ddmd.id.d\n"); - exit(EXIT_FAILURE); - } - - fprintf(fp, "// File generated by idgen.d\n"); - fprintf(fp, "\n"); - fprintf(fp, "module ddmd.id;\n"); - fprintf(fp, "\n"); - fprintf(fp, "import ddmd.identifier, ddmd.tokens;\n"); - fprintf(fp, "\n"); - fprintf(fp, "struct Id\n"); - fprintf(fp, "{\n"); - - foreach(e; msgtable) - { - auto id = e.ident; - auto p = e.name; - - if (!p) - p = id; - fprintf(fp, " extern (C++) static __gshared Identifier %s;\n", id); - } - - fprintf(fp, "\n"); - fprintf(fp, " extern (C++) static void initialize()\n"); - fprintf(fp, " {\n"); - - foreach(e; msgtable) - { - auto id = e.ident; - auto p = e.name; - - if (!p) - p = id; - fprintf(fp," %s = Identifier.idPool(\"%s\");\n", id, p); - } - - fprintf(fp, " }\n"); - fprintf(fp, "}\n"); - - fclose(fp); - } - - return EXIT_SUCCESS; +} + +/* + * Iterates the given Msgtable array, passes each element to the given lambda + * and accumulates a string from each return value of calling the lambda. + * Appends a newline character after each call to the lambda. + */ +string generate(immutable(Msgtable)[] msgtable, string function(Msgtable) dg) +{ + string code; + + foreach (i, m ; msgtable) + { + if (i != 0) + code ~= '\n'; + + code ~= dg(m); + } + + return code; +} + +// Used to generate the code for each identifier. +string identifier(Msgtable m) +{ + return "Identifier " ~ m.ident ~ ";"; +} + +// Used to generate the code for each initializer. +string initializer(Msgtable m) +{ + return m.ident ~ ` = Identifier.idPool("` ~ m.name ~ `");`; } diff --git a/src/posix.mak b/src/posix.mak index c85791cd77..80086570a9 100644 --- a/src/posix.mak +++ b/src/posix.mak @@ -228,7 +228,7 @@ FRONT_SRCS=$(addsuffix .d, $(addprefix $D/,access aggregate aliasthis apply argt cppmangle ctfeexpr dcast dclass declaration delegatize denum dimport \ dinifile dinterpret dmacro dmangle dmodule doc dscope dstruct dsymbol \ dtemplate dversion escape expression func \ - hdrgen impcnvtab imphint init inline inlinecost intrange \ + hdrgen id impcnvtab imphint init inline inlinecost intrange \ json lib link mars mtype nogc nspace objc opover optimize parse sapply \ sideeffect statement staticassert target traits visitor \ typinf utils statement_rewrite_walker statementsem staticcond safe blockexit asttypename printast)) @@ -288,7 +288,7 @@ endif SRC = $(addprefix $D/, win32.mak posix.mak osmodel.mak aggregate.h aliasthis.h arraytypes.h \ attrib.h complex_t.h cond.h ctfe.h ctfe.h declaration.h dsymbol.h \ - enum.h errors.h expression.h globals.h hdrgen.h identifier.h idgen.d \ + enum.h errors.h expression.h globals.h hdrgen.h identifier.h \ import.h init.h intrange.h json.h lexer.h \ mars.h module.h mtype.h nspace.h objc.h \ scope.h statement.h staticassert.h target.h template.h tokens.h \ @@ -396,7 +396,7 @@ endif clean: rm -R $(GENERATED) rm -f parser_test parser_test.o example_avg example_avg.o - rm -f dmd $(idgen_output) + rm -f dmd rm -f $(addprefix $D/backend/, $(optabgen_output)) @[ ! -d ${PGO_DIR} ] || echo You should issue manually: rm -rf ${PGO_DIR} @@ -457,15 +457,6 @@ $(optabgen_files): optabgen.out .INTERMEDIATE: optabgen.out optabgen.out : $G/optabgen -######## idgen generates some source - -idgen_output = $D/id.h $D/id.d -$(idgen_output) : $G/idgen - -$G/idgen: $D/idgen.d $(HOST_DMD_PATH) - CC=$(HOST_CXX) $(HOST_DMD_RUN) -of$@ $< - $G/idgen - ######## VERSION VERSION := $(shell cat ../VERSION) # default to checked-in VERSION file diff --git a/src/vcbuild/dmd.visualdproj b/src/vcbuild/dmd.visualdproj index d5831735b1..4f3f503268 100644 --- a/src/vcbuild/dmd.visualdproj +++ b/src/vcbuild/dmd.visualdproj @@ -412,28 +412,6 @@ - - - - - - - - - - - - - - - - - - - - - - @@ -526,6 +504,7 @@ + diff --git a/src/vcbuild/dmd_backend.vcxproj b/src/vcbuild/dmd_backend.vcxproj index 4bc3c29921..3a21194156 100644 --- a/src/vcbuild/dmd_backend.vcxproj +++ b/src/vcbuild/dmd_backend.vcxproj @@ -158,21 +158,9 @@ - - Building and running $(IntDir)%(Filename).exe - $(IntDir)generated\ddmd\id.d;$(IntDir)generated\ddmd\id.c;$(IntDir)generated\ddmd\id.h;$(IntDir)generated\%(Filename).exe;%(Outputs) - set DMDDir=$(DMDBinDir) -set PATH=%DMDDir%;%PATH% -dmd -od$(IntDir)generated -of$(IntDir)generated\%(Filename).exe %(Identity) -if errorlevel 1 exit /B %ERRORLEVEL% -pushd $(IntDir)generated -%(Filename).exe -if errorlevel 1 exit /B %ERRORLEVEL% -popd - Building and running $(IntDir)%(Filename).exe - cl /TP /I..\ddmd\tk /I..\ddmd\root /I. /I.. /FIwarnings.h /Fo"$(IntDir)%(Filename).obj" /Fe"$(IntDir)generated\%(Filename).exe" "%(FullPath)" + cl /TP /I..\ddmd\tk /I..\ddmd\root /I. /I.. /FIwarnings.h /Fo"$(IntDir)%(Filename).obj" /Fe"$(IntDir)generated\%(Filename).exe" "%(FullPath)" if errorlevel 1 exit /B %ERRORLEVEL% pushd $(IntDir)generated "%(Filename).exe" @@ -267,4 +255,4 @@ popd - \ No newline at end of file + diff --git a/src/win32.mak b/src/win32.mak index 378b437005..7cc406cb09 100644 --- a/src/win32.mak +++ b/src/win32.mak @@ -161,7 +161,7 @@ FRONT_SRCS=$D/access.d $D/aggregate.d $D/aliasthis.d $D/apply.d $D/argtypes.d $D $D/declaration.d $D/delegatize.d $D/denum.d $D/dimport.d $D/dinifile.d $D/dinterpret.d \ $D/dmacro.d $D/dmangle.d $D/dmodule.d $D/doc.d $D/dscope.d $D/dstruct.d $D/dsymbol.d \ $D/dtemplate.d $D/dversion.d $D/escape.d \ - $D/expression.d $D/func.d $D/hdrgen.d $D/imphint.d \ + $D/expression.d $D/func.d $D/hdrgen.d $D/id.d $D/imphint.d \ $D/impcnvtab.d $D/init.d $D/inline.d $D/inlinecost.d $D/intrange.d $D/json.d $D/lib.d $D/link.d \ $D/mars.d $D/mtype.d $D/nogc.d $D/nspace.d $D/objc.d $D/opover.d $D/optimize.d $D/parse.d \ $D/sapply.d $D/sideeffect.d $D/statement.d $D/staticassert.d $D/target.d \ @@ -347,7 +347,7 @@ clean: $(RD) /s /q $(GEN) $(DEL) $D\msgs.h $D\msgs.c $(DEL) optabgen.exe parser_test.exe example_avg.exe - $(DEL) $(TARGETEXE) $(DMDFRONTENDEXE) $(IDGENOUTPUT) *.map *.obj + $(DEL) $(TARGETEXE) $(DMDFRONTENDEXE) *.map *.obj install: detab install-copy @@ -417,7 +417,6 @@ $(TOOLS_DIR)\checkwhitespace.d: ############################## Generated Source ############################## OPTABGENOUTPUT = $G\elxxx.c $G\cdxxx.c $G\optab.c $G\debtab.c $G\fltables.c $G\tytab.c -IDGENOUTPUT = $D/id.d $D/id.h $(OPTABGENOUTPUT) : \ $C\cdef.h $C\cc.h $C\oper.h $C\ty.h $C\optabgen.c @@ -426,10 +425,6 @@ $(OPTABGENOUTPUT) : \ copy *.c "$G\" $(DEL) *.c -$(IDGENOUTPUT) : $D\idgen.d - $(HOST_DC) -of$G\idgen $D\idgen.d - $G/idgen - $G\VERSION : ..\VERSION $G copy ..\VERSION $@