Merge pull request #11669 from MoonlightSentinel/silent-headers

Make "ignored..." comments in the C++ header generation optional
This commit is contained in:
Sebastian Wilzbach 2020-09-02 20:45:11 +02:00 committed by GitHub
commit 8f9ad0520e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 197 additions and 2108 deletions

View 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).

View file

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

View file

@ -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)
@ -487,8 +489,11 @@ public:
if (isBuildingCompiler && s.getModule() && s.getModule().isFrontendModule())
{
buf.printf("// ignored %s %s", s.kind(), s.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignored %s %s", s.kind(), s.toPrettyChars());
buf.writenl();
}
}
}
@ -530,8 +535,11 @@ public:
linkage = ld.linkage;
if (ld.linkage != LINK.c && ld.linkage != LINK.cpp)
{
buf.printf("// ignoring %s block because of linkage", ld.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignoring %s block because of linkage", ld.toPrettyChars());
buf.writenl();
}
}
else
{
@ -573,20 +581,29 @@ public:
auto tf = cast(AST.TypeFunction)fd.type;
if (!tf || !tf.deco)
{
buf.printf("// ignoring function %s because semantic hasn't been run", fd.toPrettyChars());
buf.writenl();
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)
{
buf.printf("// ignoring function %s because of linkage", fd.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignoring function %s because of linkage", fd.toPrettyChars());
buf.writenl();
}
return;
}
if (!adparent && !fd.fbody)
{
buf.printf("// ignoring function %s because it's extern", fd.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignoring function %s because it's extern", fd.toPrettyChars());
buf.writenl();
}
return;
}
@ -699,7 +716,8 @@ public:
break;
case EnumKind.Other:
buf.printf("// ignoring enum `%s` because type `%s` is currently not supported for enum constants.\n", vd.toPrettyChars(), type.toChars());
if (printIgnored)
buf.printf("// ignoring enum `%s` because type `%s` is currently not supported for enum constants.\n", vd.toPrettyChars(), type.toChars());
return;
}
writeEnumTypeName(type);
@ -725,8 +743,11 @@ public:
{
if (linkage != LINK.c && linkage != LINK.cpp)
{
buf.printf("// ignoring variable %s because of linkage", vd.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignoring variable %s because of linkage", vd.toPrettyChars());
buf.writenl();
}
return;
}
typeToBuffer(vd.type, vd.ident);
@ -739,14 +760,20 @@ public:
{
if (vd.linkage != LINK.c && vd.linkage != LINK.cpp)
{
buf.printf("// ignoring variable %s because of linkage", vd.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignoring variable %s because of linkage", vd.toPrettyChars());
buf.writenl();
}
return;
}
if (vd.storage_class & AST.STC.tls)
{
buf.printf("// ignoring variable %s because of thread-local storage", vd.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignoring variable %s because of thread-local storage", vd.toPrettyChars());
buf.writenl();
}
return;
}
if (vd.linkage == LINK.c)
@ -848,8 +875,12 @@ public:
// Ignore. It's taken care of while visiting FuncDeclaration
return;
}
buf.printf("// ignored %s %s", ad.aliassym.kind(), ad.aliassym.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignored %s %s", ad.aliassym.kind(), ad.aliassym.toPrettyChars());
buf.writenl();
}
}
override void visit(AST.Nspace ns)
@ -929,8 +960,11 @@ public:
visited[cast(void*)sd] = true;
if (linkage != LINK.c && linkage != LINK.cpp)
{
buf.printf("// ignoring non-cpp struct %s because of linkage", sd.toChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignoring non-cpp struct %s because of linkage", sd.toChars());
buf.writenl();
}
return;
}
@ -1112,7 +1146,8 @@ public:
visited[cast(void*)cd] = true;
if (!cd.isCPPclass())
{
buf.printf("// ignoring non-cpp class %s\n", cd.toChars());
if (printIgnored)
buf.printf("// ignoring non-cpp class %s\n", cd.toChars());
return;
}
@ -1174,7 +1209,8 @@ public:
//if (linkage != LINK.c && linkage != LINK.cpp)
//{
//buf.printf("// ignoring non-cpp enum %s because of linkage\n", ed.toChars());
//if (printIgnored)
//buf.printf("// ignoring non-cpp enum %s because of linkage\n", ed.toChars());
//return;
//}
@ -1692,8 +1728,11 @@ public:
if (linkage != LINK.c && linkage != LINK.cpp)
{
buf.printf("// ignoring template %s because of linkage", td.toPrettyChars());
buf.writenl();
if (printIgnored)
{
buf.printf("// ignoring template %s because of linkage", td.toPrettyChars());
buf.writenl();
}
return;
}

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

@ -32,7 +32,6 @@ public:
C2(int32_t a);
};
// ignoring non-cpp class C3
class Aligned
{
public:

View file

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

View file

@ -16,7 +16,6 @@ struct A
{
// Ignoring var x alignment 0
T x;
// ignoring function foo because semantic hasn't been run
};
struct B

View file

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

View file

@ -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.
---
*/

View file

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

View 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;