From 04472f57be5e91e82adf9346e71c1421725716d5 Mon Sep 17 00:00:00 2001 From: dimenus Date: Wed, 22 Nov 2017 10:01:43 -0600 Subject: [PATCH] Added support for exporting of C field expressions --- src/c_tokenizer.cpp | 7 ++++--- src/c_tokenizer.hpp | 1 + src/ir.cpp | 3 ++- src/translate_c.cpp | 30 +++++++++++++++++++++++++++--- test/translate_c.zig | 38 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/c_tokenizer.cpp b/src/c_tokenizer.cpp index 044831f72..e5322e2b0 100644 --- a/src/c_tokenizer.cpp +++ b/src/c_tokenizer.cpp @@ -216,9 +216,8 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) { buf_append_char(&ctok->buf, '0'); break; case '.': - begin_token(ctok, CTokIdNumLitFloat); - ctok->state = CTokStateFloat; - buf_init_from_str(&ctok->buf, "0."); + begin_token(ctok, CTokIdDot); + end_token(ctok); break; case '(': begin_token(ctok, CTokIdLParen); @@ -238,6 +237,8 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) { break; case CTokStateFloat: switch (*c) { + case '.': + break; case 'e': case 'E': buf_append_char(&ctok->buf, 'e'); diff --git a/src/c_tokenizer.hpp b/src/c_tokenizer.hpp index 8eea6c56c..a3df2b94a 100644 --- a/src/c_tokenizer.hpp +++ b/src/c_tokenizer.hpp @@ -21,6 +21,7 @@ enum CTokId { CTokIdLParen, CTokIdRParen, CTokIdEOF, + CTokIdDot, }; enum CNumLitSuffix { diff --git a/src/ir.cpp b/src/ir.cpp index f632a261f..7c15b48be 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6302,8 +6302,9 @@ static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char buf_appendf(name, ")"); return name; } else { + //Note: C-imports do not have valid location information return buf_sprintf("(anonymous %s at %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", kind_name, - buf_ptr(source_node->owner->path), source_node->line + 1, source_node->column + 1); + (source_node->owner->path != nullptr) ? buf_ptr(source_node->owner->path) : "(null)", source_node->line + 1, source_node->column + 1); } } } diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 27066a08b..326cfeb63 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -3442,7 +3442,6 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { } const char *raw_name = decl_name(record_decl); - const char *container_kind_name; ContainerKind container_kind; if (record_decl->isUnion()) { @@ -3794,9 +3793,33 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { return parse_ctok_num_lit(c, ctok, tok_i, false); case CTokIdSymbol: { - *tok_i += 1; + bool need_symbol = false; + CTokId curr_id = CTokIdSymbol; Buf *symbol_name = buf_create_from_buf(&tok->data.symbol); - return trans_create_node_symbol(c, symbol_name); + AstNode *curr_node = trans_create_node_symbol(c, symbol_name); + AstNode *parent_node = curr_node; + do { + *tok_i += 1; + CTok* curr_tok = &ctok->tokens.at(*tok_i); + if (need_symbol) { + if (curr_tok->id == CTokIdSymbol) { + symbol_name = buf_create_from_buf(&curr_tok->data.symbol); + curr_node = trans_create_node_field_access(c, parent_node, buf_create_from_buf(symbol_name)); + parent_node = curr_node; + need_symbol = false; + } else { + return nullptr; + } + } else { + if (curr_tok->id == CTokIdDot) { + need_symbol = true; + continue; + } else { + break; + } + } + } while (curr_id != CTokIdEOF); + return curr_node; } case CTokIdLParen: { @@ -3810,6 +3833,7 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { *tok_i += 1; return inner_node; } + case CTokIdDot: case CTokIdEOF: case CTokIdRParen: // not able to make sense of this diff --git a/test/translate_c.zig b/test/translate_c.zig index e9f5e7de4..67c1d8431 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -1041,10 +1041,44 @@ pub fn addCases(cases: &tests.TranslateCContext) { \\ return x + 13; \\} ); + + cases.add("macros with field targets", + \\typedef unsigned int GLbitfield; + \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask); + \\typedef void(*OpenGLProc)(void); + \\union OpenGLProcs { + \\ OpenGLProc ptr[1]; + \\ struct { + \\ PFNGLCLEARPROC Clear; + \\ } gl; + \\}; + \\extern union OpenGLProcs glProcs; + \\#define glClearUnion glProcs.gl.Clear + \\#define glClearPFN PFNGLCLEARPROC + , + \\pub const GLbitfield = c_uint; + , + \\pub const PFNGLCLEARPROC = ?extern fn(GLbitfield); + , + \\pub const OpenGLProc = ?extern fn(); + , + \\pub const union_OpenGLProcs = extern union { + \\ ptr: [1]OpenGLProc, + \\ gl: extern struct { + \\ Clear: PFNGLCLEARPROC, + \\ }, + \\}; + , + \\pub extern var glProcs: union_OpenGLProcs; + , + \\pub const glClearPFN = PFNGLCLEARPROC; + , + \\pub const glClearUnion = glProcs.gl.Clear; + , + \\pub const OpenGLProcs = union_OpenGLProcs; + ); } - - // TODO //float *ptrcast(int *a) { // return (float *)a;