Skip to content

Commit

Permalink
translate-c: support const ptr initializer
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewrk committed Nov 29, 2017
1 parent 26096e7 commit 7066283
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 53 deletions.
176 changes: 123 additions & 53 deletions src/translate_c.cpp
Expand Up @@ -28,36 +28,6 @@ struct Alias {
Buf *canon_name;
};

struct Context {
ImportTableEntry *import;
ZigList<ErrorMsg *> *errors;
VisibMod visib_mod;
VisibMod export_visib_mod;
AstNode *root;
HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
SourceManager *source_manager;
ZigList<Alias> aliases;
AstNode *source_node;
bool warnings_on;

CodeGen *codegen;
ASTContext *ctx;

HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
};

enum ResultUsed {
ResultUsedNo,
ResultUsedYes,
};

enum TransLRValue {
TransLValue,
TransRValue,
};

enum TransScopeId {
TransScopeIdSwitch,
TransScopeIdVar,
Expand Down Expand Up @@ -99,6 +69,37 @@ struct TransScopeWhile {
AstNode *node;
};

struct Context {
ImportTableEntry *import;
ZigList<ErrorMsg *> *errors;
VisibMod visib_mod;
VisibMod export_visib_mod;
AstNode *root;
HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
SourceManager *source_manager;
ZigList<Alias> aliases;
AstNode *source_node;
bool warnings_on;

CodeGen *codegen;
ASTContext *ctx;

TransScopeRoot *global_scope;
HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
};

enum ResultUsed {
ResultUsedNo,
ResultUsedYes,
};

enum TransLRValue {
TransLValue,
TransRValue,
};

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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<const Expr *>()) {
return trans_expr(c, ResultUsedYes, &c->global_scope->base, expr, TransRValue);
}
//const ValueDecl *value_decl = lval_base.get<const ValueDecl *>();
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));

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -4101,6 +4170,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *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<const char *> clang_argv = {0};

Expand Down
6 changes: 6 additions & 0 deletions test/translate_c.zig
Expand Up @@ -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";
);
}

0 comments on commit 7066283

Please sign in to comment.