Commit 04472f57be

dimenus <ryan.saunderson88@gmail.com>
2017-11-22 17:01:43
Added support for exporting of C field expressions
1 parent 1b0e90f
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');
src/c_tokenizer.hpp
@@ -21,6 +21,7 @@ enum CTokId {
     CTokIdLParen,
     CTokIdRParen,
     CTokIdEOF,
+    CTokIdDot,
 };
 
 enum CNumLitSuffix {
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);
         }
     }
 }
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
test/translate_c.zig
@@ -1041,9 +1041,43 @@ 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) {