commit e280dce30f7a5d5cf6fc2001bac5e3918f8b5a39 (tree)
parent 7d762648a4f8cf20df3939a5b957bc751d6e4bb5
Author: LemonBoy <LemonBoy@users.noreply.github.com>
Date: Mon, 18 Feb 2019 16:26:45 +0100
Translate parameterless C functions (#1978)
Both FunctionNoProto and FunctionProto are subclasses of FunctionType,
the only difference is that the former is parameterless.
Diffstat:
2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
@@ -982,11 +982,12 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
}
}
case clang::Type::FunctionProto:
+ case clang::Type::FunctionNoProto:
{
- const clang::FunctionProtoType *fn_proto_ty = static_cast<const clang::FunctionProtoType*>(ty);
+ const clang::FunctionType *fn_ty = static_cast<const clang::FunctionType*>(ty);
AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
- switch (fn_proto_ty->getCallConv()) {
+ switch (fn_ty->getCallConv()) {
case clang::CC_C: // __attribute__((cdecl))
proto_node->data.fn_proto.cc = CallingConventionC;
proto_node->data.fn_proto.is_extern = true;
@@ -1041,13 +1042,10 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
return nullptr;
}
- proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
- size_t param_count = fn_proto_ty->getNumParams();
-
- if (fn_proto_ty->getNoReturnAttr()) {
+ if (fn_ty->getNoReturnAttr()) {
proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
} else {
- proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(),
+ proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_ty->getReturnType(),
source_loc);
if (proto_node->data.fn_proto.return_type == nullptr) {
emit_warning(c, source_loc, "unsupported function proto return type");
@@ -1070,6 +1068,15 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
}
+ if (ty->getTypeClass() == clang::Type::FunctionNoProto) {
+ return proto_node;
+ }
+
+ const clang::FunctionProtoType *fn_proto_ty = static_cast<const clang::FunctionProtoType*>(ty);
+
+ proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
+ size_t param_count = fn_proto_ty->getNumParams();
+
for (size_t i = 0; i < param_count; i += 1) {
clang::QualType qt = fn_proto_ty->getParamType(i);
AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
@@ -1153,7 +1160,6 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
case clang::Type::DependentSizedExtVector:
case clang::Type::Vector:
case clang::Type::ExtVector:
- case clang::Type::FunctionNoProto:
case clang::Type::UnresolvedUsing:
case clang::Type::Adjusted:
case clang::Type::TypeOfExpr:
diff --git a/test/translate_c.zig b/test/translate_c.zig
@@ -1417,6 +1417,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
);
+ cases.addC("Parameterless function prototypes",
+ \\void foo() {}
+ \\void bar(void) {}
+ ,
+ \\pub export fn foo() void {}
+ \\pub export fn bar() void {}
+ );
+
// cases.add("empty array with initializer",
// "int a[4] = {};"
// ,