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.
This commit is contained in:
Jacob Carlborg 2017-05-28 20:03:28 +02:00
parent f189b2d080
commit 326e097ea9
6 changed files with 98 additions and 146 deletions

2
.gitignore vendored
View file

@ -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

View file

@ -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 ~ `");`;
}

View file

@ -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

View file

@ -412,28 +412,6 @@
<Folder name="gen">
<File tool="Custom" path="..\..\VERSION" customcmd="copy ..\..\VERSION $(OutDir)\VERSION" uptodateWithSameTime="true" outfile="$(OutDir)\VERSION" />
</Folder>
<Folder name="generated">
<Folder name="Debug_Win32">
<File tool="None" path="..\..\generated\Windows\Debug\Win32\generated\ddmd\id.d" perConfig="true">
<Config name="Debug|Win32" />
</File>
</Folder>
<Folder name="Debug_x64">
<File tool="None" path="..\..\generated\Windows\Debug\x64\generated\ddmd\id.d" perConfig="true">
<Config name="Debug|x64" />
</File>
</Folder>
<Folder name="Release_Win32">
<File tool="None" path="..\..\generated\Windows\Release\Win32\generated\ddmd\id.d" perConfig="true">
<Config name="Release|Win32" />
</File>
</Folder>
<Folder name="Release_x64">
<File tool="None" path="..\..\generated\Windows\Release\x64\generated\ddmd\id.d" perConfig="true">
<Config name="Release|x64" />
</File>
</Folder>
</Folder>
<Folder name="ddmd">
<Folder name="backend">
<File path="..\ddmd\backend\bcomplex.d" />
@ -526,6 +504,7 @@
<File path="..\ddmd\gluelayer.d" />
<File path="..\ddmd\hdrgen.d" />
<File path="..\ddmd\iasm.d" />
<File path="..\ddmd\id.d" />
<File path="..\ddmd\identifier.d" />
<File path="..\ddmd\impcnvtab.d" />
<File path="..\ddmd\imphint.d" />

View file

@ -158,21 +158,9 @@
</ClCompile>
<ClCompile Include="..\ddmd\root\longdouble.c" />
<ClCompile Include="..\ddmd\root\newdelete.c" />
<CustomBuild Include="..\ddmd\idgen.d">
<Message>Building and running $(IntDir)%(Filename).exe</Message>
<Outputs>$(IntDir)generated\ddmd\id.d;$(IntDir)generated\ddmd\id.c;$(IntDir)generated\ddmd\id.h;$(IntDir)generated\%(Filename).exe;%(Outputs)</Outputs>
<Command>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</Command>
</CustomBuild>
<CustomBuild Include="..\ddmd\backend\optabgen.c">
<Message>Building and running $(IntDir)%(Filename).exe</Message>
<Command>cl /TP /I..\ddmd\tk /I..\ddmd\root /I. /I.. /FIwarnings.h /Fo"$(IntDir)%(Filename).obj" /Fe"$(IntDir)generated\%(Filename).exe" "%(FullPath)"
<Command>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</Command>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -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 $@