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...@@ -982,11 +982,12 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
982 }982 }
983 }983 }
984 case clang::Type::FunctionProto:984 case clang::Type::FunctionProto:
985 case clang::Type::FunctionNoProto:
985 {986 {
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
988 AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);989 AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
989 switch (fn_proto_ty->getCallConv()) {990 switch (fn_ty->getCallConv()) {
990 case clang::CC_C: // __attribute__((cdecl))991 case clang::CC_C: // __attribute__((cdecl))
991 proto_node->data.fn_proto.cc = CallingConventionC;992 proto_node->data.fn_proto.cc = CallingConventionC;
992 proto_node->data.fn_proto.is_extern = true;993 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...@@ -1041,13 +1042,10 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
1041 return nullptr;1042 return nullptr;
1042 }1043 }
10431044
1044 proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();1045 if (fn_ty->getNoReturnAttr()) {
1045 size_t param_count = fn_proto_ty->getNumParams();
1046
1047 if (fn_proto_ty->getNoReturnAttr()) {
1048 proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");1046 proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
1049 } else {1047 } 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(),
1051 source_loc);1049 source_loc);
1052 if (proto_node->data.fn_proto.return_type == nullptr) {1050 if (proto_node->data.fn_proto.return_type == nullptr) {
1053 emit_warning(c, source_loc, "unsupported function proto return type");1051 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...@@ -1070,6 +1068,15 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
1070 proto_node->data.fn_proto.name = buf_create_from_str(fn_name);1068 proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
1071 }1069 }
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
1073 for (size_t i = 0; i < param_count; i += 1) {1080 for (size_t i = 0; i < param_count; i += 1) {
1074 clang::QualType qt = fn_proto_ty->getParamType(i);1081 clang::QualType qt = fn_proto_ty->getParamType(i);
1075 AstNode *param_type_node = trans_qual_type(c, qt, source_loc);1082 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...@@ -1153,7 +1160,6 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
1153 case clang::Type::DependentSizedExtVector:1160 case clang::Type::DependentSizedExtVector:
1154 case clang::Type::Vector:1161 case clang::Type::Vector:
1155 case clang::Type::ExtVector:1162 case clang::Type::ExtVector:
1156 case clang::Type::FunctionNoProto:
1157 case clang::Type::UnresolvedUsing:1163 case clang::Type::UnresolvedUsing:
1158 case clang::Type::Adjusted:1164 case clang::Type::Adjusted:
1159 case clang::Type::TypeOfExpr:1165 case clang::Type::TypeOfExpr:
test/translate_c.zig+8
...@@ -1417,6 +1417,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1417,6 +1417,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1417 \\}1417 \\}
1418 );1418 );
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
1420 // cases.add("empty array with initializer",1428 // cases.add("empty array with initializer",
1421 // "int a[4] = {};"1429 // "int a[4] = {};"
1422 // ,1430 // ,