Commit 687e359291
Changed files (1)
src/translate_c.cpp
@@ -23,8 +23,6 @@
using namespace clang;
-struct TransScope;
-
struct MacroSymbol {
Buf *name;
Buf *value;
@@ -54,7 +52,6 @@ struct Context {
ASTContext *ctx;
HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
- TransScope *child_scope; // TODO refactor out
};
enum ResultUsed {
@@ -71,6 +68,7 @@ enum TransScopeId {
TransScopeIdSwitch,
TransScopeIdVar,
TransScopeIdBlock,
+ TransScopeIdRoot,
};
struct TransScope {
@@ -94,17 +92,27 @@ struct TransScopeBlock {
AstNode *node;
};
-static AstNode *const skip_add_to_block_node = (AstNode *) 0x2;
+struct TransScopeRoot {
+ TransScope base;
+};
+static TransScopeRoot *trans_scope_root_create(Context *c);
static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);
static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name);
//static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope);
+static TransScopeBlock *trans_scope_block_find(TransScope *scope);
+
static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);
-static AstNode *trans_stmt(Context *c, ResultUsed result_used, TransScope *scope, const Stmt *stmt, TransLRValue lrval);
+static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
+ ResultUsed result_used, TransLRValue lrval,
+ AstNode **out_node, TransScope **out_child_scope,
+ TransScope **out_node_scope);
+static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, AstNode **out_node);
+static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval);
static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
@@ -620,10 +628,6 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
}
}
-static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval) {
- return trans_stmt(c, result_used, scope, expr, lrval);
-}
-
static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {
switch (ty->getTypeClass()) {
case Type::Builtin:
@@ -961,16 +965,22 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s
return trans_type(c, qt.getTypePtr(), source_loc);
}
-static AstNode *trans_compound_stmt(Context *c, TransScope *parent_scope, const CompoundStmt *stmt) {
- TransScopeBlock *child_scope_block = trans_scope_block_create(c, parent_scope);
+static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const CompoundStmt *stmt,
+ TransScope **out_node_scope)
+{
+ TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope);
+ scope = &child_scope_block->base;
for (CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
- AstNode *child_node = trans_stmt(c, ResultUsedNo, &child_scope_block->base, *it, TransRValue);
- if (child_node == nullptr)
+ AstNode *child_node;
+ scope = trans_stmt(c, scope, *it, &child_node);
+ if (scope == nullptr)
return nullptr;
- if (child_node != skip_add_to_block_node)
+ if (child_node != nullptr)
child_scope_block->node->data.block.statements.append(child_node);
}
- c->child_scope = &child_scope_block->base;
+ if (out_node_scope != nullptr) {
+ *out_node_scope = &child_scope_block->base;
+ }
return child_scope_block->node;
}
@@ -1809,7 +1819,15 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
zig_unreachable();
}
-static AstNode *trans_local_declaration(Context *c, TransScope *scope, const DeclStmt *stmt) {
+static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt *stmt,
+ AstNode **out_node, TransScope **out_scope)
+{
+ // declarations are added via the scope
+ *out_node = nullptr;
+
+ TransScopeBlock *scope_block = trans_scope_block_find(scope);
+ assert(scope_block != nullptr);
+
for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
Decl *decl = *iter;
switch (decl->getKind()) {
@@ -1820,245 +1838,246 @@ static AstNode *trans_local_declaration(Context *c, TransScope *scope, const Dec
if (var_decl->hasInit()) {
init_node = trans_expr(c, ResultUsedYes, scope, var_decl->getInit(), TransRValue);
if (init_node == nullptr)
- return nullptr;
+ return ErrorUnexpected;
}
AstNode *type_node = trans_qual_type(c, qual_type, stmt->getLocStart());
if (type_node == nullptr)
- return nullptr;
+ return ErrorUnexpected;
+
+ Buf *c_symbol_name = buf_create_from_str(decl_name(var_decl));
- Buf *symbol_name = buf_create_from_str(decl_name(var_decl));
+ TransScopeVar *var_scope = trans_scope_var_create(c, scope, c_symbol_name);
+ scope = &var_scope->base;
AstNode *node = trans_create_node_var_decl_local(c, qual_type.isConstQualified(),
- symbol_name, type_node, init_node);
+ var_scope->zig_name, type_node, init_node);
- assert(scope->id == TransScopeIdBlock);
- TransScopeBlock *scope_block = (TransScopeBlock *)scope;
scope_block->node->data.block.statements.append(node);
continue;
}
case Decl::AccessSpec:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind AccessSpec");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Block:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Block");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Captured:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Captured");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ClassScopeFunctionSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ClassScopeFunctionSpecialization");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Empty:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Empty");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Export:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Export");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ExternCContext:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ExternCContext");
- return nullptr;
+ return ErrorUnexpected;
case Decl::FileScopeAsm:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind FileScopeAsm");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Friend:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Friend");
- return nullptr;
+ return ErrorUnexpected;
case Decl::FriendTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind FriendTemplate");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Import:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Import");
- return nullptr;
+ return ErrorUnexpected;
case Decl::LinkageSpec:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind LinkageSpec");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Label:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Label");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Namespace:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Namespace");
- return nullptr;
+ return ErrorUnexpected;
case Decl::NamespaceAlias:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind NamespaceAlias");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCCompatibleAlias:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCCompatibleAlias");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCCategory:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCCategory");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCCategoryImpl:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCCategoryImpl");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCImplementation:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCImplementation");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCInterface:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCInterface");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCProtocol:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCProtocol");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCMethod:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCMethod");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCProperty:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCProperty");
- return nullptr;
+ return ErrorUnexpected;
case Decl::BuiltinTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind BuiltinTemplate");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ClassTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ClassTemplate");
- return nullptr;
+ return ErrorUnexpected;
case Decl::FunctionTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind FunctionTemplate");
- return nullptr;
+ return ErrorUnexpected;
case Decl::TypeAliasTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TypeAliasTemplate");
- return nullptr;
+ return ErrorUnexpected;
case Decl::VarTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind VarTemplate");
- return nullptr;
+ return ErrorUnexpected;
case Decl::TemplateTemplateParm:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TemplateTemplateParm");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Enum:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Enum");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Record:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Record");
- return nullptr;
+ return ErrorUnexpected;
case Decl::CXXRecord:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXRecord");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ClassTemplateSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ClassTemplateSpecialization");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ClassTemplatePartialSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ClassTemplatePartialSpecialization");
- return nullptr;
+ return ErrorUnexpected;
case Decl::TemplateTypeParm:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TemplateTypeParm");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCTypeParam:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCTypeParam");
- return nullptr;
+ return ErrorUnexpected;
case Decl::TypeAlias:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TypeAlias");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Typedef:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Typedef");
- return nullptr;
+ return ErrorUnexpected;
case Decl::UnresolvedUsingTypename:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UnresolvedUsingTypename");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Using:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Using");
- return nullptr;
+ return ErrorUnexpected;
case Decl::UsingDirective:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UsingDirective");
- return nullptr;
+ return ErrorUnexpected;
case Decl::UsingPack:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UsingPack");
- return nullptr;
+ return ErrorUnexpected;
case Decl::UsingShadow:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UsingShadow");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ConstructorUsingShadow:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ConstructorUsingShadow");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Binding:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Binding");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Field:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Field");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCAtDefsField:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCAtDefsField");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCIvar:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCIvar");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Function:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Function");
- return nullptr;
+ return ErrorUnexpected;
case Decl::CXXDeductionGuide:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXDeductionGuide");
- return nullptr;
+ return ErrorUnexpected;
case Decl::CXXMethod:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXMethod");
- return nullptr;
+ return ErrorUnexpected;
case Decl::CXXConstructor:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXConstructor");
- return nullptr;
+ return ErrorUnexpected;
case Decl::CXXConversion:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXConversion");
- return nullptr;
+ return ErrorUnexpected;
case Decl::CXXDestructor:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXDestructor");
- return nullptr;
+ return ErrorUnexpected;
case Decl::MSProperty:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind MSProperty");
- return nullptr;
+ return ErrorUnexpected;
case Decl::NonTypeTemplateParm:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind NonTypeTemplateParm");
- return nullptr;
+ return ErrorUnexpected;
case Decl::Decomposition:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Decomposition");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ImplicitParam:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ImplicitParam");
- return nullptr;
+ return ErrorUnexpected;
case Decl::OMPCapturedExpr:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind OMPCapturedExpr");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ParmVar:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ParmVar");
- return nullptr;
+ return ErrorUnexpected;
case Decl::VarTemplateSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind VarTemplateSpecialization");
- return nullptr;
+ return ErrorUnexpected;
case Decl::VarTemplatePartialSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind VarTemplatePartialSpecialization");
- return nullptr;
+ return ErrorUnexpected;
case Decl::EnumConstant:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind EnumConstant");
- return nullptr;
+ return ErrorUnexpected;
case Decl::IndirectField:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind IndirectField");
- return nullptr;
+ return ErrorUnexpected;
case Decl::OMPDeclareReduction:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind OMPDeclareReduction");
- return nullptr;
+ return ErrorUnexpected;
case Decl::UnresolvedUsingValue:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UnresolvedUsingValue");
- return nullptr;
+ return ErrorUnexpected;
case Decl::OMPThreadPrivate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind OMPThreadPrivate");
- return nullptr;
+ return ErrorUnexpected;
case Decl::ObjCPropertyImpl:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCPropertyImpl");
- return nullptr;
+ return ErrorUnexpected;
case Decl::PragmaComment:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind PragmaComment");
- return nullptr;
+ return ErrorUnexpected;
case Decl::PragmaDetectMismatch:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind PragmaDetectMismatch");
- return nullptr;
+ return ErrorUnexpected;
case Decl::StaticAssert:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind StaticAssert");
- return nullptr;
+ return ErrorUnexpected;
case Decl::TranslationUnit:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TranslationUnit");
- return nullptr;
+ return ErrorUnexpected;
}
zig_unreachable();
}
- // declarations were already added
- return skip_add_to_block_node;
+ *out_scope = scope;
+ return ErrorNone;
}
static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) {
@@ -2068,8 +2087,8 @@ static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt
if (while_node->data.while_expr.condition == nullptr)
return nullptr;
- while_node->data.while_expr.body = trans_stmt(c, ResultUsedNo, scope, stmt->getBody(), TransRValue);
- if (while_node->data.while_expr.body == nullptr)
+ TransScope *body_scope = trans_stmt(c, scope, stmt->getBody(), &while_node->data.while_expr.body);
+ if (body_scope == nullptr)
return nullptr;
return while_node;
@@ -2086,13 +2105,13 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *
return nullptr;
if_node->data.if_bool_expr.condition = condition_node;
- if_node->data.if_bool_expr.then_block = trans_stmt(c, ResultUsedNo, scope, stmt->getThen(), TransRValue);
- if (if_node->data.if_bool_expr.then_block == nullptr)
+ TransScope *then_scope = trans_stmt(c, scope, stmt->getThen(), &if_node->data.if_bool_expr.then_block);
+ if (then_scope == nullptr)
return nullptr;
if (stmt->getElse() != nullptr) {
- if_node->data.if_bool_expr.else_node = trans_stmt(c, ResultUsedNo, scope, stmt->getElse(), TransRValue);
- if (if_node->data.if_bool_expr.else_node == nullptr)
+ TransScope *else_scope = trans_stmt(c, scope, stmt->getElse(), &if_node->data.if_bool_expr.else_node);
+ if (else_scope == nullptr)
return nullptr;
}
@@ -2201,10 +2220,14 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
// zig: b;
// zig: if (!cond) break;
// zig: }
- body_node = trans_stmt(c, ResultUsedNo, parent_scope, stmt->getBody(), TransRValue);
- if (body_node == nullptr) return nullptr;
+
+ // We call the low level function so that we can set child_scope to the scope of the generated block.
+ if (trans_stmt_extra(c, parent_scope, stmt->getBody(), ResultUsedNo, TransRValue, &body_node,
+ nullptr, &child_scope))
+ {
+ return nullptr;
+ }
assert(body_node->type == NodeTypeBlock);
- child_scope = c->child_scope;
} else {
// the C statement is without a block, so we need to create a block to contain it.
// c: do
@@ -2216,10 +2239,10 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
// zig: }
TransScopeBlock *child_block_scope = trans_scope_block_create(c, parent_scope);
body_node = child_block_scope->node;
- child_scope = &child_block_scope->base;
- AstNode *child_statement = trans_stmt(c, ResultUsedNo, child_scope, stmt->getBody(), TransRValue);
- if (child_statement == nullptr) return nullptr;
- child_block_scope->node->data.block.statements.append(child_statement);
+ AstNode *child_statement;
+ child_scope = trans_stmt(c, &child_block_scope->base, stmt->getBody(), &child_statement);
+ if (child_scope == nullptr) return nullptr;
+ body_node->data.block.statements.append(child_statement);
}
// if (!cond) break;
@@ -2229,10 +2252,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
terminator_node->data.if_bool_expr.condition = trans_create_node_prefix_op(c, PrefixOpBoolNot, condition_node);
terminator_node->data.if_bool_expr.then_block = trans_create_node(c, NodeTypeBreak);
- assert(child_scope->id == TransScopeIdBlock);
- TransScopeBlock *child_block_scope = (TransScopeBlock *)child_scope;
-
- child_block_scope->node->data.block.statements.append(terminator_node);
+ body_node->data.block.statements.append(terminator_node);
while_node->data.while_expr.body = body_node;
@@ -2244,10 +2264,10 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
// AstNode *switch_node = trans_create_node(c, NodeTypeSwitchExpr);
// const DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt();
// if (var_decl_stmt != nullptr) {
-// AstNode *vars_node = trans_stmt(c, ResultUsedNo, switch_block_node, var_decl_stmt, TransRValue);
+// AstNode *vars_node = trans_stmt(c, switch_block_node, var_decl_stmt);
// if (vars_node == nullptr)
// return nullptr;
-// if (vars_node != skip_add_to_block_node)
+// if (vars_node != nullptr)
// switch_block_node->data.block.statements.append(vars_node);
// }
// switch_block_node->data.block.statements.append(switch_node);
@@ -2260,10 +2280,10 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
// return nullptr;
// switch_node->data.switch_expr.expr = expr_node;
//
-// AstNode *body_node = trans_stmt(c, ResultUsedNo, switch_block_node, stmt->getBody(), TransRValue);
+// AstNode *body_node = trans_stmt(c, switch_block_node, stmt->getBody());
// if (body_node == nullptr)
// return nullptr;
-// if (body_node != skip_add_to_block_node)
+// if (body_node != nullptr)
// switch_block_node->data.block.statements.append(body_node);
//
// return switch_block_node;
@@ -2271,21 +2291,22 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForStmt *stmt) {
AstNode *loop_block_node;
- TransScope *condition_scope;
+ TransScope *inner_scope;
AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
const Stmt *init_stmt = stmt->getInit();
if (init_stmt == nullptr) {
loop_block_node = while_node;
- condition_scope = parent_scope;
+ inner_scope = parent_scope;
} else {
TransScopeBlock *child_scope = trans_scope_block_create(c, parent_scope);
loop_block_node = child_scope->node;
- condition_scope = &child_scope->base;
+ inner_scope = &child_scope->base;
- AstNode *vars_node = trans_stmt(c, ResultUsedNo, &child_scope->base, init_stmt, TransRValue);
- if (vars_node == nullptr)
+ AstNode *vars_node;
+ inner_scope = trans_stmt(c, &child_scope->base, init_stmt, &vars_node);
+ if (inner_scope == nullptr)
return nullptr;
- if (vars_node != skip_add_to_block_node)
+ if (vars_node != nullptr)
child_scope->node->data.block.statements.append(vars_node);
child_scope->node->data.block.statements.append(while_node);
@@ -2297,21 +2318,23 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt
true_node->data.bool_literal.value = true;
while_node->data.while_expr.condition = true_node;
} else {
- while_node->data.while_expr.condition = trans_stmt(c, ResultUsedNo, condition_scope, cond_stmt, TransRValue);
- if (while_node->data.while_expr.condition == nullptr)
+ TransScope *cond_scope = trans_stmt(c, inner_scope, cond_stmt, &while_node->data.while_expr.condition);
+ if (cond_scope == nullptr)
return nullptr;
}
const Stmt *inc_stmt = stmt->getInc();
if (inc_stmt != nullptr) {
- AstNode *inc_node = trans_stmt(c, ResultUsedNo, condition_scope, inc_stmt, TransRValue);
- if (inc_node == nullptr)
+ AstNode *inc_node;
+ TransScope *inc_scope = trans_stmt(c, inner_scope, inc_stmt, &inc_node);
+ if (inc_scope == nullptr)
return nullptr;
while_node->data.while_expr.continue_expr = inc_node;
}
- AstNode *child_statement = trans_stmt(c, ResultUsedNo, condition_scope, stmt->getBody(), TransRValue);
- if (child_statement == nullptr)
+ AstNode *child_statement;
+ TransScope *body_scope = trans_stmt(c, inner_scope, stmt->getBody(), &child_statement);
+ if (body_scope == nullptr)
return nullptr;
while_node->data.while_expr.body = child_statement;
@@ -2344,578 +2367,636 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const Continu
return trans_create_node(c, NodeTypeContinue);
}
-static AstNode *trans_stmt(Context *c, ResultUsed result_used, TransScope *scope, const Stmt *stmt, TransLRValue lrvalue) {
- c->child_scope = scope; // TODO refactor out
+static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) {
+ if (result_node == nullptr)
+ return ErrorUnexpected;
+ *out_node = result_node;
+ if (out_scope != nullptr) {
+ *out_scope = in_scope;
+ }
+ return ErrorNone;
+}
+
+static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
+ ResultUsed result_used, TransLRValue lrvalue,
+ AstNode **out_node, TransScope **out_child_scope,
+ TransScope **out_node_scope)
+{
Stmt::StmtClass sc = stmt->getStmtClass();
switch (sc) {
case Stmt::ReturnStmtClass:
- return trans_return_stmt(c, scope, (const ReturnStmt *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_return_stmt(c, scope, (const ReturnStmt *)stmt));
case Stmt::CompoundStmtClass:
- return trans_compound_stmt(c, scope, (const CompoundStmt *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_compound_stmt(c, scope, (const CompoundStmt *)stmt, out_node_scope));
case Stmt::IntegerLiteralClass:
- return trans_integer_literal(c, (const IntegerLiteral *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_integer_literal(c, (const IntegerLiteral *)stmt));
case Stmt::ConditionalOperatorClass:
- return trans_conditional_operator(c, result_used, scope, (const ConditionalOperator *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_conditional_operator(c, result_used, scope, (const ConditionalOperator *)stmt));
case Stmt::BinaryOperatorClass:
- return trans_binary_operator(c, result_used, scope, (const BinaryOperator *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_binary_operator(c, result_used, scope, (const BinaryOperator *)stmt));
case Stmt::CompoundAssignOperatorClass:
- return trans_compound_assign_operator(c, result_used, scope, (const CompoundAssignOperator *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_compound_assign_operator(c, result_used, scope, (const CompoundAssignOperator *)stmt));
case Stmt::ImplicitCastExprClass:
- return trans_implicit_cast_expr(c, scope, (const ImplicitCastExpr *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_implicit_cast_expr(c, scope, (const ImplicitCastExpr *)stmt));
case Stmt::DeclRefExprClass:
- return trans_decl_ref_expr(c, (const DeclRefExpr *)stmt, lrvalue);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_decl_ref_expr(c, (const DeclRefExpr *)stmt, lrvalue));
case Stmt::UnaryOperatorClass:
- return trans_unary_operator(c, result_used, scope, (const UnaryOperator *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_unary_operator(c, result_used, scope, (const UnaryOperator *)stmt));
case Stmt::DeclStmtClass:
- return trans_local_declaration(c, scope, (const DeclStmt *)stmt);
+ return trans_local_declaration(c, scope, (const DeclStmt *)stmt, out_node, out_child_scope);
case Stmt::WhileStmtClass:
- return trans_while_loop(c, scope, (const WhileStmt *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_while_loop(c, scope, (const WhileStmt *)stmt));
case Stmt::IfStmtClass:
- return trans_if_statement(c, scope, (const IfStmt *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_if_statement(c, scope, (const IfStmt *)stmt));
case Stmt::CallExprClass:
- return trans_call_expr(c, result_used, scope, (const CallExpr *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_call_expr(c, result_used, scope, (const CallExpr *)stmt));
case Stmt::NullStmtClass:
- return skip_add_to_block_node;
+ *out_node = nullptr;
+ *out_child_scope = scope;
+ return ErrorNone;
case Stmt::MemberExprClass:
- return trans_member_expr(c, scope, (const MemberExpr *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_member_expr(c, scope, (const MemberExpr *)stmt));
case Stmt::ArraySubscriptExprClass:
- return trans_array_subscript_expr(c, scope, (const ArraySubscriptExpr *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_array_subscript_expr(c, scope, (const ArraySubscriptExpr *)stmt));
case Stmt::CStyleCastExprClass:
- return trans_c_style_cast_expr(c, result_used, scope, (const CStyleCastExpr *)stmt, lrvalue);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_c_style_cast_expr(c, result_used, scope, (const CStyleCastExpr *)stmt, lrvalue));
case Stmt::UnaryExprOrTypeTraitExprClass:
- return trans_unary_expr_or_type_trait_expr(c, scope, (const UnaryExprOrTypeTraitExpr *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_unary_expr_or_type_trait_expr(c, scope, (const UnaryExprOrTypeTraitExpr *)stmt));
case Stmt::DoStmtClass:
- return trans_do_loop(c, scope, (const DoStmt *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_do_loop(c, scope, (const DoStmt *)stmt));
case Stmt::ForStmtClass:
- return trans_for_loop(c, scope, (const ForStmt *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_for_loop(c, scope, (const ForStmt *)stmt));
case Stmt::StringLiteralClass:
- return trans_string_literal(c, scope, (const StringLiteral *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_string_literal(c, scope, (const StringLiteral *)stmt));
case Stmt::BreakStmtClass:
- return trans_break_stmt(c, scope, (const BreakStmt *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_break_stmt(c, scope, (const BreakStmt *)stmt));
case Stmt::ContinueStmtClass:
- return trans_continue_stmt(c, scope, (const ContinueStmt *)stmt);
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_continue_stmt(c, scope, (const ContinueStmt *)stmt));
+ case Stmt::ParenExprClass:
+ return wrap_stmt(out_node, out_child_scope, scope,
+ trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue));
// case Stmt::SwitchStmtClass:
-// return trans_switch_stmt(c, scope, (const SwitchStmt *)stmt);
+// return wrap_stmt(out_node, out_child_scope, scope,
+// trans_switch_stmt(c, scope, (const SwitchStmt *)stmt));
case Stmt::SwitchStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SwitchStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CaseStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::DefaultStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DefaultStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::NoStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::GCCAsmStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C GCCAsmStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::MSAsmStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MSAsmStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::AttributedStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AttributedStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXCatchStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXCatchStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXForRangeStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXForRangeStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXTryStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXTryStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CapturedStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CapturedStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CoreturnStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CoreturnStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CoroutineBodyStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CoroutineBodyStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::BinaryConditionalOperatorClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C BinaryConditionalOperatorClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::AddrLabelExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AddrLabelExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ArrayInitIndexExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ArrayInitIndexExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ArrayInitLoopExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ArrayInitLoopExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ArrayTypeTraitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ArrayTypeTraitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::AsTypeExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AsTypeExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::AtomicExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AtomicExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::BlockExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C BlockExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXBindTemporaryExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXBindTemporaryExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXBoolLiteralExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXBoolLiteralExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXConstructExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXConstructExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXTemporaryObjectExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXTemporaryObjectExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXDefaultArgExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDefaultArgExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXDefaultInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDefaultInitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXDeleteExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDeleteExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXDependentScopeMemberExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDependentScopeMemberExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXFoldExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXFoldExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXInheritedCtorInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXInheritedCtorInitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXNewExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXNewExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXNoexceptExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXNoexceptExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXNullPtrLiteralExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXNullPtrLiteralExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXPseudoDestructorExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXPseudoDestructorExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXScalarValueInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXScalarValueInitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXStdInitializerListExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXStdInitializerListExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXThisExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXThisExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXThrowExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXThrowExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXTypeidExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXTypeidExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXUnresolvedConstructExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXUnresolvedConstructExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXUuidofExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXUuidofExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CUDAKernelCallExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CUDAKernelCallExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXMemberCallExprClass:
- (void)result_used;
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXMemberCallExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXOperatorCallExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXOperatorCallExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::UserDefinedLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C UserDefinedLiteralClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXFunctionalCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXFunctionalCastExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXConstCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXConstCastExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXDynamicCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDynamicCastExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXReinterpretCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXReinterpretCastExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CXXStaticCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXStaticCastExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCBridgedCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCBridgedCastExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CharacterLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CharacterLiteralClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ChooseExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ChooseExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CompoundLiteralExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CompoundLiteralExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ConvertVectorExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ConvertVectorExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CoawaitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CoawaitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::CoyieldExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CoyieldExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::DependentCoawaitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DependentCoawaitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::DependentScopeDeclRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DependentScopeDeclRefExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::DesignatedInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DesignatedInitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::DesignatedInitUpdateExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DesignatedInitUpdateExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ExprWithCleanupsClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ExprWithCleanupsClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ExpressionTraitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ExpressionTraitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ExtVectorElementExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ExtVectorElementExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::FloatingLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C FloatingLiteralClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::FunctionParmPackExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C FunctionParmPackExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::GNUNullExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C GNUNullExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::GenericSelectionExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C GenericSelectionExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ImaginaryLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ImaginaryLiteralClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ImplicitValueInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ImplicitValueInitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::InitListExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C InitListExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::LambdaExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C LambdaExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::MSPropertyRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MSPropertyRefExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::MSPropertySubscriptExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MSPropertySubscriptExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::MaterializeTemporaryExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MaterializeTemporaryExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::NoInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C NoInitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPArraySectionExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPArraySectionExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCArrayLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCArrayLiteralClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCAvailabilityCheckExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAvailabilityCheckExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCBoolLiteralExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCBoolLiteralExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCBoxedExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCBoxedExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCDictionaryLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCDictionaryLiteralClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCEncodeExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCEncodeExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCIndirectCopyRestoreExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCIndirectCopyRestoreExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCIsaExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCIsaExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCIvarRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCIvarRefExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCMessageExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCMessageExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCPropertyRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCPropertyRefExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCProtocolExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCProtocolExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCSelectorExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCSelectorExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCStringLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCStringLiteralClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCSubscriptRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCSubscriptRefExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OffsetOfExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OffsetOfExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OpaqueValueExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OpaqueValueExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::UnresolvedLookupExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C UnresolvedLookupExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::UnresolvedMemberExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C UnresolvedMemberExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::PackExpansionExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C PackExpansionExprClass");
- return nullptr;
- case Stmt::ParenExprClass:
- return trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue);
+ return ErrorUnexpected;
case Stmt::ParenListExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::PredefinedExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C PredefinedExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::PseudoObjectExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ShuffleVectorExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ShuffleVectorExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::SizeOfPackExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::StmtExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::SubstNonTypeTemplateParmExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::SubstNonTypeTemplateParmPackExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmPackExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::TypeTraitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C TypeTraitExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::TypoExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C TypoExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::VAArgExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C VAArgExprClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::GotoStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C GotoStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::IndirectGotoStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C IndirectGotoStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::LabelStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C LabelStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::MSDependentExistsStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MSDependentExistsStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPAtomicDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPAtomicDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPBarrierDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPBarrierDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPCancelDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPCancelDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPCancellationPointDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPCancellationPointDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPCriticalDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPCriticalDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPFlushDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPFlushDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPDistributeDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPDistributeDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPDistributeParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPDistributeParallelForDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPDistributeParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPDistributeParallelForSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPDistributeSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPDistributeSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPForDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPForSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPParallelForDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPParallelForSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetParallelForSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetTeamsDistributeDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDistributeDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTaskLoopDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskLoopDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTaskLoopSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskLoopSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTeamsDistributeDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDistributeDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTeamsDistributeSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDistributeSimdDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPMasterDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPMasterDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPOrderedDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPOrderedDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPParallelDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPParallelDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPParallelSectionsDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPParallelSectionsDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPSectionDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPSectionDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPSectionsDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPSectionsDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPSingleDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPSingleDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetDataDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetDataDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetEnterDataDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetEnterDataDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetExitDataDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetExitDataDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetParallelDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetParallelDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetParallelForDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetTeamsDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTargetUpdateDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetUpdateDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTaskDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTaskgroupDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskgroupDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTaskwaitDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskwaitDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTaskyieldDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskyieldDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::OMPTeamsDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDirectiveClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCAtCatchStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtCatchStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCAtFinallyStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtFinallyStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCAtSynchronizedStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtSynchronizedStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCAtThrowStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtThrowStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCAtTryStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtTryStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCAutoreleasePoolStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAutoreleasePoolStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::ObjCForCollectionStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCForCollectionStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::SEHExceptStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SEHExceptStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::SEHFinallyStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SEHFinallyStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::SEHLeaveStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SEHLeaveStmtClass");
- return nullptr;
+ return ErrorUnexpected;
case Stmt::SEHTryStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SEHTryStmtClass");
- return nullptr;
+ return ErrorUnexpected;
}
zig_unreachable();
}
+// Returns null if there was an error
+static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr,
+ TransLRValue lrval)
+{
+ AstNode *result_node;
+ if (trans_stmt_extra(c, scope, expr, result_used, lrval, &result_node, nullptr, nullptr)) {
+ return nullptr;
+ }
+ return result_node;
+}
+
+// Statements have no result and no concept of L or R value.
+// Returns child scope, or null if there was an error
+static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, AstNode **out_node) {
+ TransScope *child_scope;
+ if (trans_stmt_extra(c, scope, stmt, ResultUsedNo, TransRValue, out_node, &child_scope, nullptr)) {
+ return nullptr;
+ }
+ return child_scope;
+}
+
static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
Buf *fn_name = buf_create_from_str(decl_name(fn_decl));
@@ -2946,7 +3027,8 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
return;
}
- TransScope *scope = nullptr;
+ TransScopeRoot *root_scope = trans_scope_root_create(c);
+ TransScope *scope = &root_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);
@@ -2978,16 +3060,17 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
// actual function definition with body
c->ptr_params.clear();
Stmt *body = fn_decl->getBody();
- AstNode *actual_body_node = trans_stmt(c, ResultUsedNo, scope, body, TransRValue);
- assert(actual_body_node != skip_add_to_block_node);
- if (actual_body_node == nullptr) {
+ AstNode *actual_body_node;
+ TransScope *result_scope = trans_stmt(c, scope, body, &actual_body_node);
+ if (result_scope == nullptr) {
emit_warning(c, fn_decl->getLocation(), "unable to translate function");
return;
}
+ assert(actual_body_node != nullptr);
+ assert(actual_body_node->type == NodeTypeBlock);
// it worked
- assert(actual_body_node->type == NodeTypeBlock);
AstNode *body_node_with_param_inits = trans_create_node(c, NodeTypeBlock);
for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
@@ -3447,6 +3530,12 @@ static Buf *get_unique_name(Context *c, Buf *name, TransScope *scope) {
return proposed_name;
}
+static TransScopeRoot *trans_scope_root_create(Context *c) {
+ TransScopeRoot *result = allocate<TransScopeRoot>(1);
+ result->base.id = TransScopeIdRoot;
+ return result;
+}
+
static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope) {
TransScopeBlock *result = allocate<TransScopeBlock>(1);
result->base.id = TransScopeIdBlock;
@@ -3472,6 +3561,16 @@ static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scop
// return result;
//}
+static TransScopeBlock *trans_scope_block_find(TransScope *scope) {
+ while (scope != nullptr) {
+ if (scope->id == TransScopeIdBlock) {
+ return (TransScopeBlock *)scope;
+ }
+ scope = scope->parent;
+ }
+ return nullptr;
+}
+
static void render_aliases(Context *c) {
for (size_t i = 0; i < c->aliases.length; i += 1) {
Alias *alias = &c->aliases.at(i);