mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
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:
parent
f189b2d080
commit
326e097ea9
6 changed files with 98 additions and 146 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -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
|
||||
|
|
|
@ -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 ~ `");`;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 $@
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue