X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.cpp;h=7b444f8a402dfdf18efaab0ae3d171c1174972ae;hp=7529acdd4ce0ac373fad7420f5c93c4d967602e6;hb=451873ae529289f4a22d8bbce6ebf0e074da8f2b;hpb=0b94d7583cd56c5c57b35b0891d5fdf6249aaf37 diff --git a/ast.cpp b/ast.cpp index 7529acd..7b444f8 100644 --- a/ast.cpp +++ b/ast.cpp @@ -37,6 +37,8 @@ ast_expression::ast_expression(lex_ctx_t ctx, int nodetype, qc_type type) { if (OPTS_OPTION_BOOL(OPTION_COVERAGE)) m_flags |= AST_FLAG_BLOCK_COVERAGE; + if (OPTS_FLAG(DEFAULT_ERASEABLE)) + m_flags |= AST_FLAG_ERASEABLE; } ast_expression::ast_expression(lex_ctx_t ctx, int nodetype) : ast_expression(ctx, nodetype, TYPE_VOID) @@ -1130,8 +1132,10 @@ bool ast_value::generateGlobal(ir_builder *ir, bool isfield) if (m_flags & AST_FLAG_INCLUDE_DEF) m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF; - if (m_flags & AST_FLAG_ERASEABLE) + if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE)) m_ir_v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_NOREF) + m_ir_v->m_flags |= IR_FLAG_NOREF; /* initialize */ if (m_hasvalue) { @@ -1192,7 +1196,7 @@ bool ast_value::generateGlobalFunction(ir_builder *ir) m_ir_v = func->m_value; if (m_flags & AST_FLAG_INCLUDE_DEF) m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF; - if (m_flags & AST_FLAG_ERASEABLE) + if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE)) m_ir_v->m_flags |= IR_FLAG_ERASABLE; if (m_flags & AST_FLAG_BLOCK_COVERAGE) func->m_flags |= IR_FLAG_BLOCK_COVERAGE; @@ -1234,8 +1238,10 @@ bool ast_value::generateGlobalField(ir_builder *ir) if (m_flags & AST_FLAG_INCLUDE_DEF) m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF; - if (m_flags & AST_FLAG_ERASEABLE) + if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE)) m_ir_v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_NOREF) + m_ir_v->m_flags |= IR_FLAG_NOREF; const size_t namelen = m_name.length(); std::unique_ptr name(new char[namelen+16]); @@ -1254,7 +1260,9 @@ bool ast_value::generateGlobalField(ir_builder *ir) array->m_ir_values[ai]->m_unique_life = true; array->m_ir_values[ai]->m_locked = true; if (m_flags & AST_FLAG_INCLUDE_DEF) - m_ir_values[ai]->m_flags |= IR_FLAG_INCLUDE_DEF; + array->m_ir_values[ai]->m_flags |= IR_FLAG_INCLUDE_DEF; + if (m_flags & AST_FLAG_NOREF) + array->m_ir_values[ai]->m_flags |= IR_FLAG_NOREF; } } else @@ -1266,9 +1274,10 @@ bool ast_value::generateGlobalField(ir_builder *ir) m_ir_v = v; if (m_flags & AST_FLAG_INCLUDE_DEF) m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF; - - if (m_flags & AST_FLAG_ERASEABLE) + if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE)) m_ir_v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_NOREF) + m_ir_v->m_flags |= IR_FLAG_NOREF; } return true; } @@ -1298,8 +1307,10 @@ ir_value *ast_value::prepareGlobalArray(ir_builder *ir) if (m_flags & AST_FLAG_INCLUDE_DEF) v->m_flags |= IR_FLAG_INCLUDE_DEF; - if (m_flags & AST_FLAG_ERASEABLE) - m_ir_v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE)) + v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_NOREF) + v->m_flags |= IR_FLAG_NOREF; const size_t namelen = m_name.length(); std::unique_ptr name(new char[namelen+16]); @@ -1319,6 +1330,8 @@ ir_value *ast_value::prepareGlobalArray(ir_builder *ir) m_ir_values[ai]->m_locked = true; if (m_flags & AST_FLAG_INCLUDE_DEF) m_ir_values[ai]->m_flags |= IR_FLAG_INCLUDE_DEF; + if (m_flags & AST_FLAG_NOREF) + m_ir_values[ai]->m_flags |= IR_FLAG_NOREF; } return v; @@ -1365,6 +1378,9 @@ bool ast_value::generateLocal(ir_function *func, bool param) v->m_unique_life = true; v->m_locked = true; + if (m_flags & AST_FLAG_NOREF) + v->m_flags |= IR_FLAG_NOREF; + const size_t namelen = m_name.length(); std::unique_ptr name(new char[namelen+16]); util_strncpy(name.get(), m_name.c_str(), namelen); @@ -1379,7 +1395,10 @@ bool ast_value::generateLocal(ir_function *func, bool param) } m_ir_values[ai]->m_context = m_context; m_ir_values[ai]->m_unique_life = true; - m_ir_values[ai]->m_locked = true; + m_ir_values[ai]->m_locked = true; + + if (m_flags & AST_FLAG_NOREF) + m_ir_values[ai]->m_flags |= IR_FLAG_NOREF; } } else @@ -1418,6 +1437,9 @@ bool ast_value::generateLocal(ir_function *func, bool param) v->m_cvq = m_cvq; m_ir_v = v; + if (m_flags & AST_FLAG_NOREF) + m_ir_v->m_flags |= IR_FLAG_NOREF; + if (!generateAccessors(func->m_owner)) return false; return true; @@ -1490,9 +1512,9 @@ bool ast_function::generateFunction(ir_builder *ir) /* fill the parameter list */ for (auto &it : m_function_type->m_type_params) { if (it->m_vtype == TYPE_FIELD) - vec_push(irf->m_params, it->m_next->m_vtype); + irf->m_params.push_back(it->m_next->m_vtype); else - vec_push(irf->m_params, it->m_vtype); + irf->m_params.push_back(it->m_vtype); if (!m_builtin) { if (!it->generateLocal(m_ir_func, true)) return false; @@ -1562,7 +1584,7 @@ bool ast_function::generateFunction(ir_builder *ir) { return ir_block_create_return(m_curblock, m_context, nullptr); } - else if (vec_size(m_curblock->m_entries) || m_curblock == irf->m_first) + else if (m_curblock->m_entries.size() || m_curblock == irf->m_first) { if (m_return_value) { if (!m_return_value->codegen(this, false, &dummy)) @@ -1784,7 +1806,7 @@ bool ast_binary::codegen(ast_function *func, bool lvalue, ir_value **out) return false; } /* use the likely flag */ - vec_last(func->m_curblock->m_instr)->m_likely = true; + func->m_curblock->m_instr.back()->m_likely = true; /* enter the right-expression's block */ func->m_curblock = other; @@ -1912,6 +1934,7 @@ bool ast_binstore::codegen(ast_function *func, bool lvalue, ir_value **out) if (!idx->codegen(func, false, &iridx)) return false; } + if (!m_dest->codegen(func, false, &leftr)) return false; @@ -2133,19 +2156,28 @@ bool ast_member::codegen(ast_function *func, bool lvalue, ir_value **out) else m_outr = *out; return (*out != nullptr); - } else { - if (!m_owner->codegen(func, false, &vec)) - return false; } + // Vector member access + if (!m_owner->codegen(func, lvalue, &vec)) + return false; + if (vec->m_vtype != TYPE_VECTOR && !(vec->m_vtype == TYPE_FIELD && m_owner->m_next->m_vtype == TYPE_VECTOR)) { + compile_error(m_context, "vector member produced neither vector nor field"); return false; } *out = vec->vectorMember(m_field); - m_outl = *out; + if (!*out) { + compile_error(m_context, "internal error: failed to create vector member access"); + return false; + } + if (lvalue) + m_outl = *out; + else + m_outr = *out; return (*out != nullptr); }