authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-02-18 16:26:45+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-18 10:26:45-05:00
loge280dce30f7a5d5cf6fc2001bac5e3918f8b5a39
treec21a3e70e73ecadfe2d7b9384344db0ab962786d
parent7d762648a4f8cf20df3939a5b957bc751d6e4bb5

Translate parameterless C functions (#1978)

Both FunctionNoProto and FunctionProto are subclasses of FunctionType, the only difference is that the former is parameterless.

2 files changed, 22 insertions(+), 8 deletions(-)

src/translate_c.cpp+14-8
......@@ -982,11 +982,12 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
982982 }
983983 }
984984 case clang::Type::FunctionProto:
985 case clang::Type::FunctionNoProto:
985986 {
986 const clang::FunctionProtoType *fn_proto_ty = static_cast<const clang::FunctionProtoType*>(ty);
987 const clang::FunctionType *fn_ty = static_cast<const clang::FunctionType*>(ty);
987988
988989 AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
989 switch (fn_proto_ty->getCallConv()) {
990 switch (fn_ty->getCallConv()) {
990991 case clang::CC_C: // __attribute__((cdecl))
991992 proto_node->data.fn_proto.cc = CallingConventionC;
992993 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
10411042 return nullptr;
10421043 }
10431044
1044 proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
1045 size_t param_count = fn_proto_ty->getNumParams();
1046
1047 if (fn_proto_ty->getNoReturnAttr()) {
1045 if (fn_ty->getNoReturnAttr()) {
10481046 proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
10491047 } else {
1050 proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(),
1048 proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_ty->getReturnType(),
10511049 source_loc);
10521050 if (proto_node->data.fn_proto.return_type == nullptr) {
10531051 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
10701068 proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
10711069 }
10721070
1071 if (ty->getTypeClass() == clang::Type::FunctionNoProto) {
1072 return proto_node;
1073 }
1074
1075 const clang::FunctionProtoType *fn_proto_ty = static_cast<const clang::FunctionProtoType*>(ty);
1076
1077 proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
1078 size_t param_count = fn_proto_ty->getNumParams();
1079
10731080 for (size_t i = 0; i < param_count; i += 1) {
10741081 clang::QualType qt = fn_proto_ty->getParamType(i);
10751082 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
11531160 case clang::Type::DependentSizedExtVector:
11541161 case clang::Type::Vector:
11551162 case clang::Type::ExtVector:
1156 case clang::Type::FunctionNoProto:
11571163 case clang::Type::UnresolvedUsing:
11581164 case clang::Type::Adjusted:
11591165 case clang::Type::TypeOfExpr:
test/translate_c.zig+8
......@@ -1417,6 +1417,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14171417 \\}
14181418 );
14191419
1420 cases.addC("Parameterless function prototypes",
1421 \\void foo() {}
1422 \\void bar(void) {}
1423 ,
1424 \\pub export fn foo() void {}
1425 \\pub export fn bar() void {}
1426 );
1427
14201428 // cases.add("empty array with initializer",
14211429 // "int a[4] = {};"
14221430 // ,