mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Merge pull request #11669 from MoonlightSentinel/silent-headers
Make "ignored..." comments in the C++ header generation optional
This commit is contained in:
commit
8f9ad0520e
15 changed files with 197 additions and 2108 deletions
22
changelog/cxx-header-modes.dd
Normal file
22
changelog/cxx-header-modes.dd
Normal file
|
@ -0,0 +1,22 @@
|
|||
C++ header generation omits `Ignored ...` comments by default
|
||||
|
||||
The C++ header generated used to write comments when it encountered
|
||||
non-`extern(C++)` declarations, e.g.
|
||||
|
||||
---
|
||||
// test.d
|
||||
void foo() {}
|
||||
---
|
||||
---
|
||||
// test.h
|
||||
[...]
|
||||
// ignoring function test.foo because of linkage
|
||||
---
|
||||
|
||||
This caused a lot of bloat in the generated header file and is now
|
||||
customizable via the `-HC=<mode> switch which accepts either
|
||||
`verbose` (write comments) and `silent` (omit comments). The default
|
||||
was changed to `silent`.
|
||||
|
||||
Note: The header generator is still considerer experimental, so please
|
||||
submit any bugs encountered to [the bug tracker](https://issues.dlang.org).
|
|
@ -369,8 +369,16 @@ dmd -cov -unittest myprog.d
|
|||
Option("Hf=<filename>",
|
||||
"write 'header' file to filename"
|
||||
),
|
||||
Option("HC",
|
||||
"generate C++ 'header' file"
|
||||
Option("HC[=[silent|verbose]]",
|
||||
"generate C++ 'header' file",
|
||||
`Generate C++ 'header' files using the given configuration:",
|
||||
$(DL
|
||||
$(DT silent)$(DD only list extern(C[++]) declarations (default))
|
||||
$(DT verbose)$(DD also add comments for ignored declarations (e.g. extern(D)))
|
||||
)`,
|
||||
),
|
||||
Option("HC=[?|h|help]",
|
||||
"list available modes for C++ 'header' file generation"
|
||||
),
|
||||
Option("HCd=<directory>",
|
||||
"write C++ 'header' file to directory"
|
||||
|
@ -882,4 +890,11 @@ struct CLIUsage
|
|||
=c++14 Sets `__traits(getTargetInfo, \"cppStd\")` to `201402`
|
||||
=c++17 Sets `__traits(getTargetInfo, \"cppStd\")` to `201703`
|
||||
";
|
||||
|
||||
/// Options supported by -HC
|
||||
enum hcUsage = "Available header generation modes:
|
||||
=[h|help|?] List information on all available choices
|
||||
=silent Silently ignore non-exern(C[++]) declarations
|
||||
=verbose Add a comment for ignored non-exern(C[++]) declarations
|
||||
";
|
||||
}
|
||||
|
|
|
@ -418,6 +418,7 @@ public:
|
|||
bool hasAnonNumericEnum;
|
||||
bool hasNumericConstant;
|
||||
bool hasTypedConstant;
|
||||
const bool printIgnored;
|
||||
|
||||
this(OutBuffer* checkbuf, OutBuffer* fwdbuf, OutBuffer* donebuf, OutBuffer* buf)
|
||||
{
|
||||
|
@ -425,6 +426,7 @@ public:
|
|||
this.fwdbuf = fwdbuf;
|
||||
this.donebuf = donebuf;
|
||||
this.buf = buf;
|
||||
this.printIgnored = global.params.doCxxHdrGeneration == CxxHeaderMode.verbose;
|
||||
}
|
||||
|
||||
private EnumKind getEnumKind(AST.Type type)
|
||||
|
@ -486,11 +488,14 @@ public:
|
|||
}
|
||||
|
||||
if (isBuildingCompiler && s.getModule() && s.getModule().isFrontendModule())
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignored %s %s", s.kind(), s.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override void visit(AST.Import i)
|
||||
{
|
||||
|
@ -529,10 +534,13 @@ public:
|
|||
auto save = linkage;
|
||||
linkage = ld.linkage;
|
||||
if (ld.linkage != LINK.c && ld.linkage != LINK.cpp)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring %s block because of linkage", ld.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
visit(cast(AST.AttribDeclaration)ld);
|
||||
|
@ -572,21 +580,30 @@ public:
|
|||
|
||||
auto tf = cast(AST.TypeFunction)fd.type;
|
||||
if (!tf || !tf.deco)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring function %s because semantic hasn't been run", fd.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (tf.linkage != LINK.c && tf.linkage != LINK.cpp)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring function %s because of linkage", fd.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!adparent && !fd.fbody)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring function %s because it's extern", fd.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -699,6 +716,7 @@ public:
|
|||
break;
|
||||
|
||||
case EnumKind.Other:
|
||||
if (printIgnored)
|
||||
buf.printf("// ignoring enum `%s` because type `%s` is currently not supported for enum constants.\n", vd.toPrettyChars(), type.toChars());
|
||||
return;
|
||||
}
|
||||
|
@ -724,9 +742,12 @@ public:
|
|||
if (tdparent && vd.type && !vd.type.deco)
|
||||
{
|
||||
if (linkage != LINK.c && linkage != LINK.cpp)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring variable %s because of linkage", vd.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
return;
|
||||
}
|
||||
typeToBuffer(vd.type, vd.ident);
|
||||
|
@ -738,15 +759,21 @@ public:
|
|||
vd.parent && vd.parent.isModule())
|
||||
{
|
||||
if (vd.linkage != LINK.c && vd.linkage != LINK.cpp)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring variable %s because of linkage", vd.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (vd.storage_class & AST.STC.tls)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring variable %s because of thread-local storage", vd.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (vd.linkage == LINK.c)
|
||||
|
@ -848,9 +875,13 @@ public:
|
|||
// Ignore. It's taken care of while visiting FuncDeclaration
|
||||
return;
|
||||
}
|
||||
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignored %s %s", ad.aliassym.kind(), ad.aliassym.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
}
|
||||
|
||||
override void visit(AST.Nspace ns)
|
||||
{
|
||||
|
@ -928,9 +959,12 @@ public:
|
|||
|
||||
visited[cast(void*)sd] = true;
|
||||
if (linkage != LINK.c && linkage != LINK.cpp)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring non-cpp struct %s because of linkage", sd.toChars());
|
||||
buf.writenl();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1112,6 +1146,7 @@ public:
|
|||
visited[cast(void*)cd] = true;
|
||||
if (!cd.isCPPclass())
|
||||
{
|
||||
if (printIgnored)
|
||||
buf.printf("// ignoring non-cpp class %s\n", cd.toChars());
|
||||
return;
|
||||
}
|
||||
|
@ -1174,6 +1209,7 @@ public:
|
|||
|
||||
//if (linkage != LINK.c && linkage != LINK.cpp)
|
||||
//{
|
||||
//if (printIgnored)
|
||||
//buf.printf("// ignoring non-cpp enum %s because of linkage\n", ed.toChars());
|
||||
//return;
|
||||
//}
|
||||
|
@ -1691,9 +1727,12 @@ public:
|
|||
}
|
||||
|
||||
if (linkage != LINK.c && linkage != LINK.cpp)
|
||||
{
|
||||
if (printIgnored)
|
||||
{
|
||||
buf.printf("// ignoring template %s because of linkage", td.toPrettyChars());
|
||||
buf.writenl();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
2065
src/dmd/frontend.h
2065
src/dmd/frontend.h
File diff suppressed because it is too large
Load diff
|
@ -110,6 +110,14 @@ enum CppStdRevision : uint
|
|||
cpp17 = 2017_03
|
||||
}
|
||||
|
||||
/// Configuration for the C++ header generator
|
||||
enum CxxHeaderMode : uint
|
||||
{
|
||||
none, /// Don't generate headers
|
||||
silent, /// Generate headers
|
||||
verbose /// Generate headers and add comments for hidden declarations
|
||||
}
|
||||
|
||||
// Put command line switches in here
|
||||
extern (C++) struct Param
|
||||
{
|
||||
|
@ -206,6 +214,7 @@ extern (C++) struct Param
|
|||
bool revertUsage; // print help on -revert switch
|
||||
bool previewUsage; // print help on -preview switch
|
||||
bool externStdUsage; // print help on -extern-std switch
|
||||
bool hcUsage; // print help on -HC switch
|
||||
bool logo; // print compiler logo
|
||||
|
||||
CPU cpu = CPU.baseline; // CPU instruction set to target
|
||||
|
@ -240,7 +249,7 @@ extern (C++) struct Param
|
|||
const(char)[] hdrname; // write 'header' file to docname
|
||||
bool hdrStripPlainFunctions = true; // strip the bodies of plain (non-template) functions
|
||||
|
||||
bool doCxxHdrGeneration; // write 'Cxx header' file
|
||||
CxxHeaderMode doCxxHdrGeneration; /// Generate 'Cxx header' file
|
||||
const(char)[] cxxhdrdir; // write 'header' file to docdir directory
|
||||
const(char)[] cxxhdrname; // write 'header' file to docname
|
||||
|
||||
|
|
|
@ -89,6 +89,14 @@ enum CppStdRevision
|
|||
CppStdRevisionCpp17 = 201703
|
||||
};
|
||||
|
||||
/// Configuration for the C++ header generator
|
||||
enum class CxxHeaderMode
|
||||
{
|
||||
none, /// Don't generate headers
|
||||
silent, /// Generate headers
|
||||
verbose /// Generate headers and add comments for hidden declarations
|
||||
};
|
||||
|
||||
// Put command line switches in here
|
||||
struct Param
|
||||
{
|
||||
|
@ -172,6 +180,7 @@ struct Param
|
|||
bool revertUsage; // print help on -revert switch
|
||||
bool previewUsage; // print help on -preview switch
|
||||
bool externStdUsage; // print help on -extern-std switch
|
||||
bool hcUsage; // print help on -HC switch
|
||||
bool logo; // print logo;
|
||||
|
||||
CPU cpu; // CPU instruction set to target
|
||||
|
@ -206,7 +215,7 @@ struct Param
|
|||
DString hdrname; // write 'header' file to docname
|
||||
bool hdrStripPlainFunctions; // strip the bodies of plain (non-template) functions
|
||||
|
||||
bool doCxxHdrGeneration; // write 'Cxx header' file
|
||||
CxxHeaderMode doCxxHdrGeneration; // write 'Cxx header' file
|
||||
DString cxxhdrdir; // write 'header' file to docdir directory
|
||||
DString cxxhdrname; // write 'header' file to docname
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params)
|
|||
}
|
||||
import dmd.cli : CLIUsage;
|
||||
mixin(generateUsageChecks(["mcpu", "transition", "check", "checkAction",
|
||||
"preview", "revert", "externStd"]));
|
||||
"preview", "revert", "externStd", "hc"]));
|
||||
|
||||
if (params.manual)
|
||||
{
|
||||
|
@ -2165,7 +2165,7 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param
|
|||
}
|
||||
else if (p[1] == 'H' && p[2] == 'C') // https://dlang.org/dmd.html#switch-HC
|
||||
{
|
||||
params.doCxxHdrGeneration = true;
|
||||
params.doCxxHdrGeneration = CxxHeaderMode.silent;
|
||||
switch (p[3])
|
||||
{
|
||||
case 'd': // https://dlang.org/dmd.html#switch-HCd
|
||||
|
@ -2178,6 +2178,24 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param
|
|||
goto Lnoarg;
|
||||
params.cxxhdrname = (p + 4 + (p[4] == '=')).toDString;
|
||||
break;
|
||||
case '=':
|
||||
enum len = "-HC=".length;
|
||||
mixin(checkOptionsMixin("hcUsage", "`-HC=<mode>` requires a valid mode"));
|
||||
const mode = arg[len .. $];
|
||||
switch (mode)
|
||||
{
|
||||
case "silent":
|
||||
/* already set above */
|
||||
break;
|
||||
case "verbose":
|
||||
params.doCxxHdrGeneration = CxxHeaderMode.verbose;
|
||||
break;
|
||||
default:
|
||||
errorInvalidSwitch(p);
|
||||
params.hcUsage = true;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
REQUIRED_ARGS: -HC -c -o-
|
||||
REQUIRED_ARGS: -HC=silent -c -o-
|
||||
PERMUTE_ARGS:
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
|
@ -20,13 +20,10 @@ typedef int32_t T;
|
|||
|
||||
extern "C" int32_t x;
|
||||
|
||||
// ignored variable dtoh_AliasDeclaration.x
|
||||
extern "C" int32_t foo(int32_t x);
|
||||
|
||||
// ignored function dtoh_AliasDeclaration.foo
|
||||
extern int32_t foo2(int32_t x);
|
||||
|
||||
// ignored function dtoh_AliasDeclaration.foo2
|
||||
struct S;
|
||||
|
||||
typedef S aliasS;
|
||||
|
@ -35,7 +32,6 @@ struct S2;
|
|||
|
||||
typedef S2 aliasS2;
|
||||
|
||||
// ignoring non-cpp class C
|
||||
typedef C* aliasC;
|
||||
|
||||
class C2;
|
||||
|
|
|
@ -32,7 +32,6 @@ public:
|
|||
C2(int32_t a);
|
||||
};
|
||||
|
||||
// ignoring non-cpp class C3
|
||||
class Aligned
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -64,7 +64,6 @@ struct A
|
|||
{
|
||||
int32_t a;
|
||||
S s;
|
||||
// ignoring extern () block because of linkage
|
||||
extern "C" void bar();
|
||||
void baz(int32_t x = 42);
|
||||
struct
|
||||
|
|
|
@ -16,7 +16,6 @@ struct A
|
|||
{
|
||||
// Ignoring var x alignment 0
|
||||
T x;
|
||||
// ignoring function foo because semantic hasn't been run
|
||||
};
|
||||
|
||||
struct B
|
||||
|
|
|
@ -11,8 +11,6 @@ TEST_OUTPUT:
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
// ignoring variable dtoh_VarDeclaration.x because of linkage
|
||||
// ignoring variable dtoh_VarDeclaration.y because of linkage
|
||||
extern "C" int32_t z;
|
||||
|
||||
extern int32_t t;
|
||||
|
@ -21,7 +19,6 @@ struct S;
|
|||
|
||||
struct S2;
|
||||
|
||||
// ignoring non-cpp class C
|
||||
class C2;
|
||||
|
||||
union U;
|
||||
|
|
|
@ -98,7 +98,6 @@ END_ENUM(STC, STC, stc)
|
|||
|
||||
ENUM_CONSTANT(STC, STC_D, (STC)3)
|
||||
|
||||
// ignoring non-cpp struct Foo because of linkage
|
||||
BEGIN_ENUM_TYPE(Foo, MyEnum, MYENUM, myenum)
|
||||
ENUM_KEY_TYPE(Foo, A, Foo(42), MyEnum, MYENUM, myenum, ME)
|
||||
ENUM_KEY_TYPE(Foo, B, Foo(84), MyEnum, MYENUM, myenum, ME)
|
||||
|
@ -119,12 +118,6 @@ END_ENUM_TYPE(FooCpp, MyEnumCpp, MYENUMCPP, myenumcpp)
|
|||
|
||||
ENUM_CONSTANT(MyEnum, testCpp, Foo(42))
|
||||
|
||||
// ignoring enum `dtoh_enum.b` because type `int[]` is currently not supported for enum constants.
|
||||
// ignoring enum `dtoh_enum.c` because type `int[int]` is currently not supported for enum constants.
|
||||
// ignoring function dtoh_enum.foo because it's extern
|
||||
// ignoring enum `dtoh_enum.d` because type `extern (C) void function()` is currently not supported for enum constants.
|
||||
// ignoring variable dtoh_enum.e_b because of linkage
|
||||
// ignoring enum `dtoh_enum.e` because type `immutable(bool)*` is currently not supported for enum constants.
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
|
@ -11,9 +11,6 @@ TEST_OUTPUT:
|
|||
#include <stdint.h>
|
||||
|
||||
|
||||
// ignoring function dtoh_functions.foo because of linkage
|
||||
// ignoring function dtoh_functions.fun because it's extern
|
||||
// ignoring function dtoh_functions.fun2 because it's extern
|
||||
extern "C" int32_t bar(int32_t x);
|
||||
|
||||
extern "C" int32_t bar2(int32_t x);
|
||||
|
|
42
test/compilable/dtoh_verbose.d
Normal file
42
test/compilable/dtoh_verbose.d
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
REQUIRED_ARGS: -HC=verbose
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
// Automatically generated by Digital Mars D Compiler v$n$
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// ignoring function dtoh_verbose.foo because of linkage
|
||||
// ignoring extern () block because of linkage
|
||||
// ignoring function dtoh_verbose.bar because of linkage
|
||||
// ignoring non-cpp struct S because of linkage
|
||||
// ignoring non-cpp class C
|
||||
// ignoring function dtoh_verbose.bar because it's extern
|
||||
// ignoring variable dtoh_verbose.i1 because of linkage
|
||||
// ignored function dtoh_verbose.templ!int.templ
|
||||
---
|
||||
*/
|
||||
|
||||
void foo() {}
|
||||
|
||||
extern (D) {
|
||||
int i;
|
||||
}
|
||||
|
||||
void bar();
|
||||
|
||||
struct S {}
|
||||
|
||||
class C {}
|
||||
|
||||
extern(C++) void bar();
|
||||
|
||||
int i1;
|
||||
|
||||
void templ(T)(T t) {}
|
||||
|
||||
alias inst = templ!int;
|
Loading…
Add table
Add a link
Reference in a new issue