start implementing variable declaration translation

This commit is contained in:
Josh Wolfe 2017-09-01 11:39:48 -07:00
parent 60bdbe5405
commit 0d0fffe4d2

View File

@ -664,10 +664,10 @@ static bool c_is_float(Context *c, QualType qt) {
}
}
static AstNode * trans_stmt(Context *c, Stmt *stmt);
static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt);
static AstNode * trans_expr(Context *c, Expr *expr) {
return trans_stmt(c, expr);
static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) {
return trans_stmt(c, block, expr);
}
static AstNode * trans_create_node(Context *c, Stmt *stmt, NodeType id) {
@ -678,22 +678,23 @@ static AstNode * trans_create_node(Context *c, Stmt *stmt, NodeType id) {
return node;
}
static AstNode * trans_compound_stmt(Context *c, CompoundStmt *stmt) {
AstNode *block_node = trans_create_node(c, stmt, NodeTypeBlock);
static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {
AstNode *child_block = trans_create_node(c, stmt, NodeTypeBlock);
for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
AstNode *child_node = trans_stmt(c, *it);
block_node->data.block.statements.append(child_node);
AstNode *child_node = trans_stmt(c, child_block, *it);
if (child_node != nullptr)
child_block->data.block.statements.append(child_node);
}
return block_node;
return child_block;
}
static AstNode *trans_return_stmt(Context *c, ReturnStmt *stmt) {
static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) {
Expr *value_expr = stmt->getRetValue();
if (value_expr == nullptr) {
zig_panic("TODO handle C return void");
} else {
AstNode *return_node = trans_create_node(c, stmt, NodeTypeReturnExpr);
return_node->data.return_expr.expr = trans_expr(c, value_expr);
return_node->data.return_expr.expr = trans_expr(c, block, value_expr);
return return_node;
}
}
@ -726,21 +727,21 @@ static AstNode * trans_integer_literal(Context *c, IntegerLiteral *stmt) {
return node;
}
static AstNode * trans_conditional_operator(Context *c, ConditionalOperator *stmt) {
static AstNode * trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) {
AstNode *node = trans_create_node(c, stmt, NodeTypeIfBoolExpr);
Expr *cond_expr = stmt->getCond();
Expr *true_expr = stmt->getTrueExpr();
Expr *false_expr = stmt->getFalseExpr();
node->data.if_bool_expr.condition = trans_expr(c, cond_expr);
node->data.if_bool_expr.then_block = trans_expr(c, true_expr);
node->data.if_bool_expr.else_node = trans_expr(c, false_expr);
node->data.if_bool_expr.condition = trans_expr(c, block, cond_expr);
node->data.if_bool_expr.then_block = trans_expr(c, block, true_expr);
node->data.if_bool_expr.else_node = trans_expr(c, block, false_expr);
return node;
}
static AstNode * trans_binary_operator(Context *c, BinaryOperator *stmt) {
static AstNode * trans_binary_operator(Context *c, AstNode *block, BinaryOperator *stmt) {
switch (stmt->getOpcode()) {
case BO_PtrMemD:
zig_panic("TODO handle more C binary operators: BO_PtrMemD");
@ -764,8 +765,8 @@ static AstNode * trans_binary_operator(Context *c, BinaryOperator *stmt) {
{
AstNode *node = trans_create_node(c, stmt, NodeTypeBinOpExpr);
node->data.bin_op_expr.bin_op = BinOpTypeCmpLessThan;
node->data.bin_op_expr.op1 = trans_expr(c, stmt->getLHS());
node->data.bin_op_expr.op2 = trans_expr(c, stmt->getRHS());
node->data.bin_op_expr.op1 = trans_expr(c, block, stmt->getLHS());
node->data.bin_op_expr.op2 = trans_expr(c, block, stmt->getRHS());
return node;
}
case BO_GT:
@ -817,10 +818,10 @@ static AstNode * trans_binary_operator(Context *c, BinaryOperator *stmt) {
zig_unreachable();
}
static AstNode * trans_implicit_cast_expr(Context *c, ImplicitCastExpr *stmt) {
static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {
switch (stmt->getCastKind()) {
case CK_LValueToRValue:
return trans_expr(c, stmt->getSubExpr());
return trans_expr(c, block, stmt->getSubExpr());
case CK_IntegralCast:
zig_panic("TODO handle C translation cast CK_IntegralCast");
case CK_Dependent:
@ -955,7 +956,7 @@ static AstNode * trans_create_num_lit_node_unsigned(Context *c, Stmt *stmt, uint
return node;
}
static AstNode * trans_unary_operator(Context *c, UnaryOperator *stmt) {
static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {
switch (stmt->getOpcode()) {
case UO_PostInc:
zig_panic("TODO handle C translation UO_PostInc");
@ -977,13 +978,13 @@ static AstNode * trans_unary_operator(Context *c, UnaryOperator *stmt) {
if (c_is_signed_integer(c, op_expr->getType()) || c_is_float(c, op_expr->getType())) {
AstNode *node = trans_create_node(c, stmt, NodeTypePrefixOpExpr);
node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
node->data.prefix_op_expr.primary_expr = trans_expr(c, op_expr);
node->data.prefix_op_expr.primary_expr = trans_expr(c, block, op_expr);
return node;
} else if (c_is_unsigned_integer(c, op_expr->getType())) {
// we gotta emit 0 -% x
AstNode *node = trans_create_node(c, stmt, NodeTypeBinOpExpr);
node->data.bin_op_expr.op1 = trans_create_num_lit_node_unsigned(c, stmt, 0);
node->data.bin_op_expr.op2 = trans_expr(c, op_expr);
node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr);
node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
return node;
} else {
@ -1006,25 +1007,200 @@ static AstNode * trans_unary_operator(Context *c, UnaryOperator *stmt) {
zig_unreachable();
}
static AstNode *trans_stmt(Context *c, Stmt *stmt) {
static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *stmt) {
for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
Decl *decl = *iter;
switch (decl->getKind()) {
case Decl::Var: {
VarDecl *var_decl = (VarDecl *)decl;
AstNode *node = trans_create_node(c, stmt, NodeTypeVariableDeclaration);
node->data.variable_declaration.symbol = buf_create_from_str(decl_name(var_decl));
QualType qual_type = var_decl->getTypeSourceInfo()->getType();
node->data.variable_declaration.is_const = qual_type.isConstQualified();
node->data.variable_declaration.type = trans_qual_type(c, block, qual_type);
if (var_decl->hasInit()) {
node->data.variable_declaration.expr = trans_expr(c, block, var_decl->getInit());
}
//emit_warning(c, decl->getLocation(), "asdf");
block->data.block.statements.append(node);
continue;
}
case Decl::AccessSpec:
zig_panic("TODO handle decl kind AccessSpec");
case Decl::Block:
zig_panic("TODO handle decl kind Block");
case Decl::Captured:
zig_panic("TODO handle decl kind Captured");
case Decl::ClassScopeFunctionSpecialization:
zig_panic("TODO handle decl kind ClassScopeFunctionSpecialization");
case Decl::Empty:
zig_panic("TODO handle decl kind Empty");
case Decl::Export:
zig_panic("TODO handle decl kind Export");
case Decl::ExternCContext:
zig_panic("TODO handle decl kind ExternCContext");
case Decl::FileScopeAsm:
zig_panic("TODO handle decl kind FileScopeAsm");
case Decl::Friend:
zig_panic("TODO handle decl kind Friend");
case Decl::FriendTemplate:
zig_panic("TODO handle decl kind FriendTemplate");
case Decl::Import:
zig_panic("TODO handle decl kind Import");
case Decl::LinkageSpec:
zig_panic("TODO handle decl kind LinkageSpec");
case Decl::Label:
zig_panic("TODO handle decl kind Label");
case Decl::Namespace:
zig_panic("TODO handle decl kind Namespace");
case Decl::NamespaceAlias:
zig_panic("TODO handle decl kind NamespaceAlias");
case Decl::ObjCCompatibleAlias:
zig_panic("TODO handle decl kind ObjCCompatibleAlias");
case Decl::ObjCCategory:
zig_panic("TODO handle decl kind ObjCCategory");
case Decl::ObjCCategoryImpl:
zig_panic("TODO handle decl kind ObjCCategoryImpl");
case Decl::ObjCImplementation:
zig_panic("TODO handle decl kind ObjCImplementation");
case Decl::ObjCInterface:
zig_panic("TODO handle decl kind ObjCInterface");
case Decl::ObjCProtocol:
zig_panic("TODO handle decl kind ObjCProtocol");
case Decl::ObjCMethod:
zig_panic("TODO handle decl kind ObjCMethod");
case Decl::ObjCProperty:
zig_panic("TODO handle decl kind ObjCProperty");
case Decl::BuiltinTemplate:
zig_panic("TODO handle decl kind BuiltinTemplate");
case Decl::ClassTemplate:
zig_panic("TODO handle decl kind ClassTemplate");
case Decl::FunctionTemplate:
zig_panic("TODO handle decl kind FunctionTemplate");
case Decl::TypeAliasTemplate:
zig_panic("TODO handle decl kind TypeAliasTemplate");
case Decl::VarTemplate:
zig_panic("TODO handle decl kind VarTemplate");
case Decl::TemplateTemplateParm:
zig_panic("TODO handle decl kind TemplateTemplateParm");
case Decl::Enum:
zig_panic("TODO handle decl kind Enum");
case Decl::Record:
zig_panic("TODO handle decl kind Record");
case Decl::CXXRecord:
zig_panic("TODO handle decl kind CXXRecord");
case Decl::ClassTemplateSpecialization:
zig_panic("TODO handle decl kind ClassTemplateSpecialization");
case Decl::ClassTemplatePartialSpecialization:
zig_panic("TODO handle decl kind ClassTemplatePartialSpecialization");
case Decl::TemplateTypeParm:
zig_panic("TODO handle decl kind TemplateTypeParm");
case Decl::ObjCTypeParam:
zig_panic("TODO handle decl kind ObjCTypeParam");
case Decl::TypeAlias:
zig_panic("TODO handle decl kind TypeAlias");
case Decl::Typedef:
zig_panic("TODO handle decl kind Typedef");
case Decl::UnresolvedUsingTypename:
zig_panic("TODO handle decl kind UnresolvedUsingTypename");
case Decl::Using:
zig_panic("TODO handle decl kind Using");
case Decl::UsingDirective:
zig_panic("TODO handle decl kind UsingDirective");
case Decl::UsingPack:
zig_panic("TODO handle decl kind UsingPack");
case Decl::UsingShadow:
zig_panic("TODO handle decl kind UsingShadow");
case Decl::ConstructorUsingShadow:
zig_panic("TODO handle decl kind ConstructorUsingShadow");
case Decl::Binding:
zig_panic("TODO handle decl kind Binding");
case Decl::Field:
zig_panic("TODO handle decl kind Field");
case Decl::ObjCAtDefsField:
zig_panic("TODO handle decl kind ObjCAtDefsField");
case Decl::ObjCIvar:
zig_panic("TODO handle decl kind ObjCIvar");
case Decl::Function:
zig_panic("TODO handle decl kind Function");
case Decl::CXXDeductionGuide:
zig_panic("TODO handle decl kind CXXDeductionGuide");
case Decl::CXXMethod:
zig_panic("TODO handle decl kind CXXMethod");
case Decl::CXXConstructor:
zig_panic("TODO handle decl kind CXXConstructor");
case Decl::CXXConversion:
zig_panic("TODO handle decl kind CXXConversion");
case Decl::CXXDestructor:
zig_panic("TODO handle decl kind CXXDestructor");
case Decl::MSProperty:
zig_panic("TODO handle decl kind MSProperty");
case Decl::NonTypeTemplateParm:
zig_panic("TODO handle decl kind NonTypeTemplateParm");
case Decl::Decomposition:
zig_panic("TODO handle decl kind Decomposition");
case Decl::ImplicitParam:
zig_panic("TODO handle decl kind ImplicitParam");
case Decl::OMPCapturedExpr:
zig_panic("TODO handle decl kind OMPCapturedExpr");
case Decl::ParmVar:
zig_panic("TODO handle decl kind ParmVar");
case Decl::VarTemplateSpecialization:
zig_panic("TODO handle decl kind VarTemplateSpecialization");
case Decl::VarTemplatePartialSpecialization:
zig_panic("TODO handle decl kind VarTemplatePartialSpecialization");
case Decl::EnumConstant:
zig_panic("TODO handle decl kind EnumConstant");
case Decl::IndirectField:
zig_panic("TODO handle decl kind IndirectField");
case Decl::OMPDeclareReduction:
zig_panic("TODO handle decl kind OMPDeclareReduction");
case Decl::UnresolvedUsingValue:
zig_panic("TODO handle decl kind UnresolvedUsingValue");
case Decl::OMPThreadPrivate:
zig_panic("TODO handle decl kind OMPThreadPrivate");
case Decl::ObjCPropertyImpl:
zig_panic("TODO handle decl kind ObjCPropertyImpl");
case Decl::PragmaComment:
zig_panic("TODO handle decl kind PragmaComment");
case Decl::PragmaDetectMismatch:
zig_panic("TODO handle decl kind PragmaDetectMismatch");
case Decl::StaticAssert:
zig_panic("TODO handle decl kind StaticAssert");
case Decl::TranslationUnit:
zig_panic("TODO handle decl kind TranslationUnit");
}
zig_unreachable();
}
// declarations were already added
return nullptr;
}
static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
Stmt::StmtClass sc = stmt->getStmtClass();
switch (sc) {
case Stmt::ReturnStmtClass:
return trans_return_stmt(c, (ReturnStmt *)stmt);
return trans_return_stmt(c, block, (ReturnStmt *)stmt);
case Stmt::CompoundStmtClass:
return trans_compound_stmt(c, (CompoundStmt *)stmt);
return trans_compound_stmt(c, block, (CompoundStmt *)stmt);
case Stmt::IntegerLiteralClass:
return trans_integer_literal(c, (IntegerLiteral *)stmt);
case Stmt::ConditionalOperatorClass:
return trans_conditional_operator(c, (ConditionalOperator *)stmt);
return trans_conditional_operator(c, block, (ConditionalOperator *)stmt);
case Stmt::BinaryOperatorClass:
return trans_binary_operator(c, (BinaryOperator *)stmt);
return trans_binary_operator(c, block, (BinaryOperator *)stmt);
case Stmt::ImplicitCastExprClass:
return trans_implicit_cast_expr(c, (ImplicitCastExpr *)stmt);
return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);
case Stmt::DeclRefExprClass:
return trans_decl_ref_expr(c, (DeclRefExpr *)stmt);
case Stmt::UnaryOperatorClass:
return trans_unary_operator(c, (UnaryOperator *)stmt);
return trans_unary_operator(c, block, (UnaryOperator *)stmt);
case Stmt::DeclStmtClass:
return trans_local_declaration(c, block, (DeclStmt *)stmt);
case Stmt::CaseStmtClass:
zig_panic("TODO handle C CaseStmtClass");
case Stmt::DefaultStmtClass:
@ -1057,8 +1233,6 @@ static AstNode *trans_stmt(Context *c, Stmt *stmt) {
zig_panic("TODO handle C CoreturnStmtClass");
case Stmt::CoroutineBodyStmtClass:
zig_panic("TODO handle C CoroutineBodyStmtClass");
case Stmt::DeclStmtClass:
zig_panic("TODO handle C DeclStmtClass");
case Stmt::DoStmtClass:
zig_panic("TODO handle C DoStmtClass");
case Stmt::BinaryConditionalOperatorClass:
@ -1409,7 +1583,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
if (fn_decl->hasBody()) {
fprintf(stderr, "fn %s\n", buf_ptr(fn_name));
Stmt *body = fn_decl->getBody();
AstNode *body_node = trans_stmt(c, body);
AstNode *body_node = trans_stmt(c, nullptr, body);
ast_render(c->codegen, stderr, body_node, 4);
fprintf(stderr, "\n");
}