aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-01-06 14:07:56 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-01-06 14:07:56 -0500
commit0a9daeb37e997ff75dcd16d1fc3b4cc143314e85 (patch)
tree05ca7f6b64b1e40fc16a595816f3a632a986617c /src/parser.cpp
parentc30106c90665079f525129e344cc1c13e4db162b (diff)
parentd09bd3d86c4d36ad608a91b36c9a6eb6208c9626 (diff)
downloadzig-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.cpp33
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);
}