From 70662830044418fc2d637c166fc100fe72d60fcf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 28 Nov 2017 23:44:45 -0500 Subject: [PATCH] translate-c: support const ptr initializer --- src/translate_c.cpp | 198 +++++++++++++++++++++++++++++-------------- test/translate_c.zig | 6 ++ 2 files changed, 140 insertions(+), 64 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 3295560af398c2cf759592887e905e93206d70bb..f5c1ef5810dc68458fcc4154e230290a169219a7 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -28,6 +28,47 @@ struct Alias { Buf *canon_name; }; +enum TransScopeId { + TransScopeIdSwitch, + TransScopeIdVar, + TransScopeIdBlock, + TransScopeIdRoot, + TransScopeIdWhile, +}; + +struct TransScope { + TransScopeId id; + TransScope *parent; +}; + +struct TransScopeSwitch { + TransScope base; + AstNode *switch_node; + uint32_t case_index; + bool found_default; + Buf *end_label_name; +}; + +struct TransScopeVar { + TransScope base; + Buf *c_name; + Buf *zig_name; +}; + +struct TransScopeBlock { + TransScope base; + AstNode *node; +}; + +struct TransScopeRoot { + TransScope base; +}; + +struct TransScopeWhile { + TransScope base; + AstNode *node; +}; + struct Context { ImportTableEntry *import; ZigList *errors; @@ -45,6 +86,7 @@ struct Context { CodeGen *codegen; ASTContext *ctx; + TransScopeRoot *global_scope; HashMap ptr_params; }; @@ -58,47 +100,6 @@ enum TransLRValue { TransRValue, }; -enum TransScopeId { - TransScopeIdSwitch, - TransScopeIdVar, - TransScopeIdBlock, - TransScopeIdRoot, - TransScopeIdWhile, -}; - -struct TransScope { - TransScopeId id; - TransScope *parent; -}; - -struct TransScopeSwitch { - TransScope base; - AstNode *switch_node; - uint32_t case_index; - bool found_default; - Buf *end_label_name; -}; - -struct TransScopeVar { - TransScope base; - Buf *c_name; - Buf *zig_name; -}; - -struct TransScopeBlock { - TransScope base; - AstNode *node; -}; - -struct TransScopeRoot { - TransScope base; -}; - -struct TransScopeWhile { - TransScope base; - AstNode *node; -}; - static TransScopeRoot *trans_scope_root_create(Context *c); static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope); static 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) { return; } - TransScopeRoot *root_scope = trans_scope_root_create(c); - TransScope *scope = &root_scope->base; + TransScope *scope = &c->global_scope->base; for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) { 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) { } } +static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const SourceLocation &source_loc) { + switch (ap_value->getKind()) { + case APValue::Int: + return trans_create_node_apint(c, ap_value->getInt()); + case APValue::Uninitialized: + return trans_create_node(c, NodeTypeUndefinedLiteral); + case APValue::Array: { + emit_warning(c, source_loc, "TODO add a test case for this code"); + + unsigned init_count = ap_value->getArrayInitializedElts(); + unsigned all_count = ap_value->getArraySize(); + unsigned leftover_count = all_count - init_count; + AstNode *init_node = trans_create_node(c, NodeTypeContainerInitExpr); + AstNode *arr_type_node = trans_qual_type(c, qt, source_loc); + init_node->data.container_init_expr.type = arr_type_node; + init_node->data.container_init_expr.kind = ContainerInitKindArray; + + QualType child_qt = qt.getTypePtr()->getLocallyUnqualifiedSingleStepDesugaredType(); + + for (size_t i = 0; i < init_count; i += 1) { + APValue &elem_ap_val = ap_value->getArrayInitializedElt(i); + AstNode *elem_node = trans_ap_value(c, &elem_ap_val, child_qt, source_loc); + if (elem_node == nullptr) + return nullptr; + init_node->data.container_init_expr.entries.append(elem_node); + } + if (leftover_count == 0) { + return init_node; + } + + APValue &filler_ap_val = ap_value->getArrayFiller(); + AstNode *filler_node = trans_ap_value(c, &filler_ap_val, child_qt, source_loc); + if (filler_node == nullptr) + return nullptr; + + AstNode *filler_arr_1 = trans_create_node(c, NodeTypeContainerInitExpr); + init_node->data.container_init_expr.type = arr_type_node; + init_node->data.container_init_expr.kind = ContainerInitKindArray; + init_node->data.container_init_expr.entries.append(filler_node); + + AstNode *rhs_node; + if (leftover_count == 1) { + rhs_node = filler_arr_1; + } else { + AstNode *amt_node = trans_create_node_unsigned(c, leftover_count); + rhs_node = trans_create_node_bin_op(c, filler_arr_1, BinOpTypeArrayMult, amt_node); + } + + return trans_create_node_bin_op(c, init_node, BinOpTypeArrayCat, rhs_node); + } + case APValue::LValue: { + const APValue::LValueBase lval_base = ap_value->getLValueBase(); + if (const Expr *expr = lval_base.dyn_cast()) { + return trans_expr(c, ResultUsedYes, &c->global_scope->base, expr, TransRValue); + } + //const ValueDecl *value_decl = lval_base.get(); + emit_warning(c, source_loc, "TODO handle initializer LValue ValueDecl"); + return nullptr; + } + case APValue::Float: + emit_warning(c, source_loc, "unsupported initializer value kind: Float"); + return nullptr; + case APValue::ComplexInt: + emit_warning(c, source_loc, "unsupported initializer value kind: ComplexInt"); + return nullptr; + case APValue::ComplexFloat: + emit_warning(c, source_loc, "unsupported initializer value kind: ComplexFloat"); + return nullptr; + case APValue::Vector: + emit_warning(c, source_loc, "unsupported initializer value kind: Vector"); + return nullptr; + case APValue::Struct: + emit_warning(c, source_loc, "unsupported initializer value kind: Struct"); + return nullptr; + case APValue::Union: + emit_warning(c, source_loc, "unsupported initializer value kind: Union"); + return nullptr; + case APValue::MemberPointer: + emit_warning(c, source_loc, "unsupported initializer value kind: MemberPointer"); + return nullptr; + case APValue::AddrLabelDiff: + emit_warning(c, source_loc, "unsupported initializer value kind: AddrLabelDiff"); + return nullptr; + } + zig_unreachable(); +} + static void visit_var_decl(Context *c, const VarDecl *var_decl) { Buf *name = buf_create_from_str(decl_name(var_decl)); @@ -3636,27 +3723,9 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name)); return; } - switch (ap_value->getKind()) { - case APValue::Int: - init_node = trans_create_node_apint(c, ap_value->getInt()); - break; - case APValue::Uninitialized: - init_node = trans_create_node(c, NodeTypeUndefinedLiteral); - break; - case APValue::Float: - case APValue::ComplexInt: - case APValue::ComplexFloat: - case APValue::LValue: - case APValue::Vector: - case APValue::Array: - case APValue::Struct: - case APValue::Union: - case APValue::MemberPointer: - case APValue::AddrLabelDiff: - emit_warning(c, var_decl->getLocation(), - "ignoring variable '%s' - unrecognized initializer value kind", buf_ptr(name)); - return; - } + init_node = trans_ap_value(c, ap_value, qt, var_decl->getLocation()); + if (init_node == nullptr) + return; } else { init_node = trans_create_node(c, NodeTypeUndefinedLiteral); } @@ -4101,6 +4170,7 @@ int parse_h_file(ImportTableEntry *import, ZigList *errors, const ch c->ptr_params.init(8); c->codegen = codegen; c->source_node = source_node; + c->global_scope = trans_scope_root_create(c); ZigList clang_argv = {0}; diff --git a/test/translate_c.zig b/test/translate_c.zig index 8a8d1d334bbf5255af2ecfc580c996697b2669b1..90b99b5faf5e589fa7140ee575e9577e34d06ce0 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -1172,4 +1172,10 @@ pub fn addCases(cases: &tests.TranslateCContext) { \\ return u32_0; \\} ); + + cases.add("const ptr initializer", + \\static const char *v0 = "0.0.0"; + , + \\pub var v0: ?&const u8 = c"0.0.0"; + ); } -- 2.54.0