X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.cpp;h=7b444f8a402dfdf18efaab0ae3d171c1174972ae;hp=cbc5db9657a9af3beaf6d12b5e64bb442c4f0066;hb=092067482fddeccf1b3e42ff09a046f6555cd11e;hpb=d9127bf28ad5c1f7626487bbc5f29e72e9912d67 diff --git a/ast.cpp b/ast.cpp index cbc5db9..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,7 +1132,7 @@ 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; @@ -1194,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; @@ -1236,7 +1238,7 @@ 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; @@ -1272,7 +1274,7 @@ 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; @@ -1305,7 +1307,7 @@ 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) + 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; @@ -1932,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; @@ -2153,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); }