Skip to content

Commit 7066283

Browse files
committedNov 29, 2017
translate-c: support const ptr initializer
1 parent 26096e7 commit 7066283

File tree

2 files changed

+129
-53
lines changed

2 files changed

+129
-53
lines changed
 

‎src/translate_c.cpp

+123-53
Original file line numberDiff line numberDiff line change
@@ -28,36 +28,6 @@ struct Alias {
2828
Buf *canon_name;
2929
};
3030

31-
struct 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-
51-
enum ResultUsed {
52-
ResultUsedNo,
53-
ResultUsedYes,
54-
};
55-
56-
enum TransLRValue {
57-
TransLValue,
58-
TransRValue,
59-
};
60-
6131
enum TransScopeId {
6232
TransScopeIdSwitch,
6333
TransScopeIdVar,
@@ -99,6 +69,37 @@ struct TransScopeWhile {
9969
AstNode *node;
10070
};
10171

72+
struct 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+
93+
enum ResultUsed {
94+
ResultUsedNo,
95+
ResultUsedYes,
96+
};
97+
98+
enum TransLRValue {
99+
TransLValue,
100+
TransRValue,
101+
};
102+
102103
static TransScopeRoot *trans_scope_root_create(Context *c);
103104
static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope);
104105
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) {
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

3603+
static 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+
36033690
static 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
Original file line numberDiff line numberDiff line change
@@ -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
}

0 commit comments

Comments
 (0)