diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-01-06 14:07:56 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-01-06 14:07:56 -0500 |
| commit | 0a9daeb37e997ff75dcd16d1fc3b4cc143314e85 (patch) | |
| tree | 05ca7f6b64b1e40fc16a595816f3a632a986617c /src/parser.cpp | |
| parent | c30106c90665079f525129e344cc1c13e4db162b (diff) | |
| parent | d09bd3d86c4d36ad608a91b36c9a6eb6208c9626 (diff) | |
| download | zig-0a9daeb37e997ff75dcd16d1fc3b4cc143314e85.tar.gz zig-0a9daeb37e997ff75dcd16d1fc3b4cc143314e85.zip | |
Merge branch 'cc-work' of https://github.com/LemonBoy/zig into LemonBoy-cc-work
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index a0c5cf794b..65ea9ac203 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -92,6 +92,7 @@ static Token *ast_parse_block_label(ParseContext *pc); static AstNode *ast_parse_field_init(ParseContext *pc); static AstNode *ast_parse_while_continue_expr(ParseContext *pc); static AstNode *ast_parse_link_section(ParseContext *pc); +static AstNode *ast_parse_callconv(ParseContext *pc); static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc); static AstNode *ast_parse_param_decl(ParseContext *pc); static AstNode *ast_parse_param_type(ParseContext *pc); @@ -676,7 +677,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B fn_proto->column = first->start_column; fn_proto->data.fn_proto.visib_mod = visib_mod; fn_proto->data.fn_proto.doc_comments = *doc_comments; - fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern; + // ast_parse_fn_cc may set it + if (!fn_proto->data.fn_proto.is_extern) + fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern; fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport; switch (first->id) { case TokenIdKeywordInline: @@ -761,7 +764,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { // The extern keyword for fn CC is also used for container decls. // We therefore put it back, as allow container decl to consume it // later. - if (fn_cc.cc == CallingConventionC) { + if (fn_cc.is_extern) { fn = eat_token_if(pc, TokenIdKeywordFn); if (fn == nullptr) { put_back_token(pc); @@ -784,6 +787,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { AstNode *align_expr = ast_parse_byte_align(pc); AstNode *section_expr = ast_parse_link_section(pc); + AstNode *callconv_expr = ast_parse_callconv(pc); Token *var = eat_token_if(pc, TokenIdKeywordVar); Token *exmark = nullptr; AstNode *return_type = nullptr; @@ -798,6 +802,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { res->data.fn_proto.params = params; res->data.fn_proto.align_expr = align_expr; res->data.fn_proto.section_expr = section_expr; + res->data.fn_proto.callconv_expr = callconv_expr; res->data.fn_proto.return_var_token = var; res->data.fn_proto.auto_err_set = exmark != nullptr; res->data.fn_proto.return_type = return_type; @@ -2099,6 +2104,18 @@ static AstNode *ast_parse_link_section(ParseContext *pc) { return res; } +// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN +static AstNode *ast_parse_callconv(ParseContext *pc) { + Token *first = eat_token_if(pc, TokenIdKeywordCallconv); + if (first == nullptr) + return nullptr; + + expect_token(pc, TokenIdLParen); + AstNode *res = ast_expect(pc, ast_parse_expr); + expect_token(pc, TokenIdRParen); + return res; +} + // FnCC // <- KEYWORD_nakedcc // / KEYWORD_stdcallcc @@ -2107,19 +2124,19 @@ static AstNode *ast_parse_link_section(ParseContext *pc) { static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) { AstNodeFnProto res = {}; if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) { - res.cc = CallingConventionNaked; + res.is_nakedcc = true; return Optional<AstNodeFnProto>::some(res); } if (eat_token_if(pc, TokenIdKeywordStdcallCC) != nullptr) { - res.cc = CallingConventionStdcall; + res.is_stdcallcc = true; return Optional<AstNodeFnProto>::some(res); } - if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) { - res.cc = CallingConventionC; + if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) { + res.is_async = true; return Optional<AstNodeFnProto>::some(res); } - if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) { - res.cc = CallingConventionAsync; + if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) { + res.is_extern = true; return Optional<AstNodeFnProto>::some(res); } |
