authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-28 23:44:45-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-28 23:44:45-05:00
log70662830044418fc2d637c166fc100fe72d60fcf
tree0c4ad9185e8cb2e25270e2e9a4d3f71f3243cd77
parent26096e79d1610218106faa75f7dbb10b4b5bbe5a

translate-c: support const ptr initializer


2 files changed, 129 insertions(+), 53 deletions(-)

src/translate_c.cpp+123-53
......@@ -28,36 +28,6 @@ struct Alias {
2828 Buf *canon_name;
2929};
3030
31struct Context {
32 ImportTableEntry *import;
33 ZigList<ErrorMsg *> *errors;
34 VisibMod visib_mod;
35 VisibMod export_visib_mod;
36 AstNode *root;
37 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
38 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
39 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
40 SourceManager *source_manager;
41 ZigList<Alias> aliases;
42 AstNode *source_node;
43 bool warnings_on;
44
45 CodeGen *codegen;
46 ASTContext *ctx;
47
48 HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
49};
50
51enum ResultUsed {
52 ResultUsedNo,
53 ResultUsedYes,
54};
55
56enum TransLRValue {
57 TransLValue,
58 TransRValue,
59};
60
6131enum TransScopeId {
6232 TransScopeIdSwitch,
6333 TransScopeIdVar,
......@@ -99,6 +69,37 @@ struct TransScopeWhile {
9969 AstNode *node;
10070};
10171
72struct Context {
73 ImportTableEntry *import;
74 ZigList<ErrorMsg *> *errors;
75 VisibMod visib_mod;
76 VisibMod export_visib_mod;
77 AstNode *root;
78 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
79 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
80 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
81 SourceManager *source_manager;
82 ZigList<Alias> aliases;
83 AstNode *source_node;
84 bool warnings_on;
85
86 CodeGen *codegen;
87 ASTContext *ctx;
88
89 TransScopeRoot *global_scope;
90 HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
91};
92
93enum ResultUsed {
94 ResultUsedNo,
95 ResultUsedYes,
96};
97
98enum TransLRValue {
99 TransLValue,
100 TransRValue,
101};
102
102103static TransScopeRoot *trans_scope_root_create(Context *c);
103104static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope);
104105static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);
......@@ -3233,8 +3234,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
32333234 return;
32343235 }
32353236
3236 TransScopeRoot *root_scope = trans_scope_root_create(c);
3237 TransScope *scope = &root_scope->base;
3237 TransScope *scope = &c->global_scope->base;
32383238
32393239 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
32403240 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
......@@ -3600,6 +3600,93 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
36003600 }
36013601}
36023602
3603static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const SourceLocation &source_loc) {
3604 switch (ap_value->getKind()) {
3605 case APValue::Int:
3606 return trans_create_node_apint(c, ap_value->getInt());
3607 case APValue::Uninitialized:
3608 return trans_create_node(c, NodeTypeUndefinedLiteral);
3609 case APValue::Array: {
3610 emit_warning(c, source_loc, "TODO add a test case for this code");
3611
3612 unsigned init_count = ap_value->getArrayInitializedElts();
3613 unsigned all_count = ap_value->getArraySize();
3614 unsigned leftover_count = all_count - init_count;
3615 AstNode *init_node = trans_create_node(c, NodeTypeContainerInitExpr);
3616 AstNode *arr_type_node = trans_qual_type(c, qt, source_loc);
3617 init_node->data.container_init_expr.type = arr_type_node;
3618 init_node->data.container_init_expr.kind = ContainerInitKindArray;
3619
3620 QualType child_qt = qt.getTypePtr()->getLocallyUnqualifiedSingleStepDesugaredType();
3621
3622 for (size_t i = 0; i < init_count; i += 1) {
3623 APValue &elem_ap_val = ap_value->getArrayInitializedElt(i);
3624 AstNode *elem_node = trans_ap_value(c, &elem_ap_val, child_qt, source_loc);
3625 if (elem_node == nullptr)
3626 return nullptr;
3627 init_node->data.container_init_expr.entries.append(elem_node);
3628 }
3629 if (leftover_count == 0) {
3630 return init_node;
3631 }
3632
3633 APValue &filler_ap_val = ap_value->getArrayFiller();
3634 AstNode *filler_node = trans_ap_value(c, &filler_ap_val, child_qt, source_loc);
3635 if (filler_node == nullptr)
3636 return nullptr;
3637
3638 AstNode *filler_arr_1 = trans_create_node(c, NodeTypeContainerInitExpr);
3639 init_node->data.container_init_expr.type = arr_type_node;
3640 init_node->data.container_init_expr.kind = ContainerInitKindArray;
3641 init_node->data.container_init_expr.entries.append(filler_node);
3642
3643 AstNode *rhs_node;
3644 if (leftover_count == 1) {
3645 rhs_node = filler_arr_1;
3646 } else {
3647 AstNode *amt_node = trans_create_node_unsigned(c, leftover_count);
3648 rhs_node = trans_create_node_bin_op(c, filler_arr_1, BinOpTypeArrayMult, amt_node);
3649 }
3650
3651 return trans_create_node_bin_op(c, init_node, BinOpTypeArrayCat, rhs_node);
3652 }
3653 case APValue::LValue: {
3654 const APValue::LValueBase lval_base = ap_value->getLValueBase();
3655 if (const Expr *expr = lval_base.dyn_cast<const Expr *>()) {
3656 return trans_expr(c, ResultUsedYes, &c->global_scope->base, expr, TransRValue);
3657 }
3658 //const ValueDecl *value_decl = lval_base.get<const ValueDecl *>();
3659 emit_warning(c, source_loc, "TODO handle initializer LValue ValueDecl");
3660 return nullptr;
3661 }
3662 case APValue::Float:
3663 emit_warning(c, source_loc, "unsupported initializer value kind: Float");
3664 return nullptr;
3665 case APValue::ComplexInt:
3666 emit_warning(c, source_loc, "unsupported initializer value kind: ComplexInt");
3667 return nullptr;
3668 case APValue::ComplexFloat:
3669 emit_warning(c, source_loc, "unsupported initializer value kind: ComplexFloat");
3670 return nullptr;
3671 case APValue::Vector:
3672 emit_warning(c, source_loc, "unsupported initializer value kind: Vector");
3673 return nullptr;
3674 case APValue::Struct:
3675 emit_warning(c, source_loc, "unsupported initializer value kind: Struct");
3676 return nullptr;
3677 case APValue::Union:
3678 emit_warning(c, source_loc, "unsupported initializer value kind: Union");
3679 return nullptr;
3680 case APValue::MemberPointer:
3681 emit_warning(c, source_loc, "unsupported initializer value kind: MemberPointer");
3682 return nullptr;
3683 case APValue::AddrLabelDiff:
3684 emit_warning(c, source_loc, "unsupported initializer value kind: AddrLabelDiff");
3685 return nullptr;
3686 }
3687 zig_unreachable();
3688}
3689
36033690static void visit_var_decl(Context *c, const VarDecl *var_decl) {
36043691 Buf *name = buf_create_from_str(decl_name(var_decl));
36053692
......@@ -3636,27 +3723,9 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
36363723 "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
36373724 return;
36383725 }
3639 switch (ap_value->getKind()) {
3640 case APValue::Int:
3641 init_node = trans_create_node_apint(c, ap_value->getInt());
3642 break;
3643 case APValue::Uninitialized:
3644 init_node = trans_create_node(c, NodeTypeUndefinedLiteral);
3645 break;
3646 case APValue::Float:
3647 case APValue::ComplexInt:
3648 case APValue::ComplexFloat:
3649 case APValue::LValue:
3650 case APValue::Vector:
3651 case APValue::Array:
3652 case APValue::Struct:
3653 case APValue::Union:
3654 case APValue::MemberPointer:
3655 case APValue::AddrLabelDiff:
3656 emit_warning(c, var_decl->getLocation(),
3657 "ignoring variable '%s' - unrecognized initializer value kind", buf_ptr(name));
3658 return;
3659 }
3726 init_node = trans_ap_value(c, ap_value, qt, var_decl->getLocation());
3727 if (init_node == nullptr)
3728 return;
36603729 } else {
36613730 init_node = trans_create_node(c, NodeTypeUndefinedLiteral);
36623731 }
......@@ -4101,6 +4170,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
41014170 c->ptr_params.init(8);
41024171 c->codegen = codegen;
41034172 c->source_node = source_node;
4173 c->global_scope = trans_scope_root_create(c);
41044174
41054175 ZigList<const char *> clang_argv = {0};
41064176
test/translate_c.zig+6
......@@ -1172,4 +1172,10 @@ pub fn addCases(cases: &tests.TranslateCContext) {
11721172 \\ return u32_0;
11731173 \\}
11741174 );
1175
1176 cases.add("const ptr initializer",
1177 \\static const char *v0 = "0.0.0";
1178 ,
1179 \\pub var v0: ?&const u8 = c"0.0.0";
1180 );
11751181}