Skip to content

Commit

Permalink
feat: support variadic functions and variadic function types
Browse files Browse the repository at this point in the history
  • Loading branch information
sdkrystian committed May 27, 2024
1 parent e0a0547 commit d456f87
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/mrdocs/Metadata/Type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ struct FunctionTypeInfo
QualifierKind CVQualifiers = QualifierKind::None;
ReferenceKind RefQualifier = ReferenceKind::None;
NoexceptInfo ExceptionSpec;
bool IsVariadic = false;

TypeInfo* innerType() const noexcept override
{
Expand Down
5 changes: 3 additions & 2 deletions mrdocs.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -432,12 +432,13 @@ grammar
"pointer" |
"member-pointer" |
"array" |
"function" |
"pack"
"function"
} ?,
ID ?,
Name ?,
attribute parent { text } ?,
attribute is-pack { "1" } ?,
attribute is-variadic { "1" } ?,
attribute cv-qualifiers { "const"|"volatile"|"const volatile" } ?,
attribute ref-qualifier { "&"|"&&" } ?,
attribute exception-spec { text } ?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{{else if (eq kind "function")~}}
({{#each param-types~}}
{{~>declarator nolink=../nolink~}}{{~#unless @last}}, {{/unless~}}
{{/each~}})
{{/each~}}{{#if is-variadic}}{{#if param-types}}, {{/if}}...{{/if}})
{{~#if cv-qualifiers}} {{cv-qualifiers}}{{/if~}}
{{#if (eq ref-qualifier "lvalue")}} &{{else if (eq ref-qualifier "rvalue")}} &&{{/if~}}
{{#if exception-spec}} {{exception-spec}}{{/if~}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{{/unless}}{{>declarator type decl-name=name~}}
{{#if default}} = {{default}}{{/if~}}
{{#unless @last}},{{/unless~}}
{{/each~}})
{{/each~}}{{#if symbol.isVariadic}}{{#if symbol.params}}, {{/if}}...{{/if}})
{{~#if symbol.isConst}} const{{/if~}}
{{#if symbol.isVolatile}} volatile{{/if~}}
{{#if symbol.refQualifier}} {{symbol.refQualifier}}{{/if~}}
Expand Down
1 change: 1 addition & 0 deletions src/lib/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3537,6 +3537,7 @@ class TypeInfoBuilder
FPT->getRefQualifier());
I->CVQualifiers = convertToQualifierKind(
FPT->getMethodQuals().getFastQualifiers());
I->IsVariadic = FPT->isVariadic();
getASTVisitor().buildNoexceptInfo(I->ExceptionSpec, FPT);
*std::exchange(Inner, &I->ReturnType) = std::move(I);
}
Expand Down
5 changes: 5 additions & 0 deletions src/lib/AST/AnyBlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,11 @@ class TypeInfoBlock
return Error("wrong TypeInfo kind");
return decodeRecord(R, static_cast<
FunctionTypeInfo&>(*I_).ExceptionSpec, Blob);
case TYPEINFO_IS_VARIADIC:
if(! I_->isFunction())
return Error("wrong TypeInfo kind");
return decodeRecord(R, static_cast<
FunctionTypeInfo&>(*I_).IsVariadic, Blob);
default:
return AnyBlock::parseRecord(R, ID, Blob);
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/AST/BitcodeIDs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ enum RecordID
TYPEINFO_CVQUAL,
TYPEINFO_NOEXCEPT,
TYPEINFO_REFQUAL,
TYPEINFO_IS_VARIADIC,
BASE_ACCESS,
BASE_IS_VIRTUAL,
FIELD_ATTRIBUTES,
Expand Down
4 changes: 3 additions & 1 deletion src/lib/AST/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ RecordIDNameMap = []()
{TYPEINFO_CVQUAL, {"TypeinfoCV", &Integer32Abbrev}},
{TYPEINFO_NOEXCEPT, {"TypeinfoNoexcept", &NoexceptAbbrev}},
{TYPEINFO_REFQUAL, {"TypeinfoRefqual", &Integer32Abbrev}},
{TYPEINFO_IS_VARIADIC, {"TypeinfoIsVariadic", &BoolAbbrev}},
{TYPEDEF_IS_USING, {"IsUsing", &BoolAbbrev}},
{VARIABLE_BITS, {"Bits", &Integer32ArrayAbbrev}},
{USING_SYMBOLS, {"UsingSymbols", &SymbolIDsAbbrev}},
Expand Down Expand Up @@ -437,7 +438,7 @@ RecordsByBlock{
// TypeInfo
{BI_TYPEINFO_BLOCK_ID,
{TYPEINFO_KIND, TYPEINFO_IS_PACK, TYPEINFO_CVQUAL,
TYPEINFO_NOEXCEPT, TYPEINFO_REFQUAL}},
TYPEINFO_NOEXCEPT, TYPEINFO_REFQUAL, TYPEINFO_IS_VARIADIC}},
{BI_TYPEINFO_PARENT_BLOCK_ID,
{}},
{BI_TYPEINFO_CHILD_BLOCK_ID,
Expand Down Expand Up @@ -1048,6 +1049,7 @@ emitBlock(

emitRecord(t.RefQualifier, TYPEINFO_REFQUAL);
emitRecord(t.ExceptionSpec, TYPEINFO_NOEXCEPT);
emitRecord(t.IsVariadic, TYPEINFO_IS_VARIADIC);
}

if constexpr(T::isNamed())
Expand Down
3 changes: 3 additions & 0 deletions src/lib/Gen/xml/CXXTags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ writeType(

if constexpr(T::isFunction())
{
if(t.IsVariadic)
attrs.push({"is-variadic", "1"});

if(t.RefQualifier != ReferenceKind::None)
attrs.push({"ref-qualifier", toString(t.RefQualifier)});

Expand Down
1 change: 1 addition & 0 deletions src/lib/Metadata/DomMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ domCreate(
toString(t.ExceptionSpec));
entries.emplace_back("ref-qualifier",
toString(t.RefQualifier));
entries.emplace_back("is-variadic", t.IsVariadic);
}
});
return dom::Object(std::move(entries));
Expand Down
8 changes: 8 additions & 0 deletions src/lib/Metadata/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ operator()(
writeFullType(**first, write);
}
}

if(t.IsVariadic)
{
if(! t.ParamTypes.empty())
write(", ");
write("...");
}

write(')');

if(t.CVQualifiers != QualifierKind::None)
Expand Down
10 changes: 10 additions & 0 deletions test-files/old-tests/variadic-function.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using T = void(...);

using U = void(int, ...);

void f(...);

void g(int, ...);

template<typename A = void(...), typename B = void(int, ...)>
struct C;
37 changes: 37 additions & 0 deletions test-files/old-tests/variadic-function.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<mrdocs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://github.com/cppalliance/mrdocs/raw/develop/mrdocs.rnc">
<namespace id="//////////////////////////8=">
<alias name="T" id="PvNOREc+JWxdkVgvSz+jC45IbGQ=">
<file path="variadic-function.cpp" line="1" class="def"/>
<type class="function" is-variadic="1">
<return-type name="void"/>
</type>
</alias>
<alias name="U" id="h6hupdyuT6SfsCGFl6UUFGtvrcc=">
<file path="variadic-function.cpp" line="3" class="def"/>
<type class="function" is-variadic="1">
<return-type name="void"/>
<param-type name="int"/>
</type>
</alias>
<function name="f" id="CMaAySU4txrIlGl6edqWDSabBRA=">
<file path="variadic-function.cpp" line="5"/>
<attr id="is-variadic"/>
</function>
<function name="g" id="lldWvRg9y+NwRnDpK3x2NF9+e08=">
<file path="variadic-function.cpp" line="7"/>
<attr id="is-variadic"/>
<param>
<type name="int"/>
</param>
</function>
<template>
<tparam name="A" class="type" default="void(...)"/>
<tparam name="B" class="type" default="void(int, ...)"/>
<struct name="C" id="8nYw0KA23eAszqSOs0wOXAD1DYQ=">
<file path="variadic-function.cpp" line="10"/>
</struct>
</template>
</namespace>
</mrdocs>

0 comments on commit d456f87

Please sign in to comment.