I rather create a new tree for template usage really, so you don't create an extra tree and save a little amount of memory.
This, however, would consume another scarce resource, i.e. tree codes. The attached patch, in the meanwhile, has been bootstrapped and regtested i686-pc-linux-gnu, C/C++ only, with no regression. Note that this is *not* the patch I sent yesterday, which did not work.
Ok for mainline? Paolo
2007-01-30 Paolo Bonzini <[EMAIL PROTECTED]> * cp/cp-tree.h (OMP_ATOMIC_CODE): Delete. (OMP_ATOMIC_DEPENDENT_P): Rewrite. * cp/pt.c (tsubst_expr): Adjust for new format of dependent OMP_ATOMIC expressions. * cp/semantics.c (finish_omp_atomic): Store a whole expression node in operand 1, and integer_zero_node in operand 0, for dependent OMP_ATOMIC. Rewrite to make flow easier to understand. Index: cp-tree.h =================================================================== *** cp-tree.h (revision 121287) --- cp-tree.h (working copy) *************** extern void decl_shadowed_for_var_insert *** 3040,3052 **** (TREE_LANG_FLAG_0 (SCOPE_REF_CHECK (NODE))) /* True for an OMP_ATOMIC that has dependent parameters. These are stored ! as bare LHS/RHS, and not as ADDR/RHS, as in the generic statement. */ #define OMP_ATOMIC_DEPENDENT_P(NODE) \ ! (TREE_LANG_FLAG_0 (OMP_ATOMIC_CHECK (NODE))) ! ! /* Used to store the operation code when OMP_ATOMIC_DEPENDENT_P is set. */ ! #define OMP_ATOMIC_CODE(NODE) \ ! (OMP_ATOMIC_CHECK (NODE)->exp.complexity) /* Used while gimplifying continue statements bound to OMP_FOR nodes. */ #define OMP_FOR_GIMPLIFYING_P(NODE) \ --- 3040,3048 ---- (TREE_LANG_FLAG_0 (SCOPE_REF_CHECK (NODE))) /* True for an OMP_ATOMIC that has dependent parameters. These are stored ! as an expr in operand 1, and integer_zero_node in operand 0. */ #define OMP_ATOMIC_DEPENDENT_P(NODE) \ ! (TREE_CODE (TREE_OPERAND (OMP_ATOMIC_CHECK (NODE), 0)) == INTEGER_CST) /* Used while gimplifying continue statements bound to OMP_FOR nodes. */ #define OMP_FOR_GIMPLIFYING_P(NODE) \ Index: pt.c =================================================================== *** pt.c (revision 121287) --- pt.c (working copy) *************** tsubst_expr (tree t, tree args, tsubst_f *** 8917,8928 **** break; case OMP_ATOMIC: ! { ! tree op0, op1; ! op0 = RECUR (TREE_OPERAND (t, 0)); ! op1 = RECUR (TREE_OPERAND (t, 1)); ! finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1); ! } break; default: --- 8917,8929 ---- break; case OMP_ATOMIC: ! if (OMP_ATOMIC_DEPENDENT_P (t)) ! { ! tree op1 = TREE_OPERAND (t, 1); ! tree lhs = RECUR (TREE_OPERAND (op1, 0)); ! tree rhs = RECUR (TREE_OPERAND (op1, 1)); ! finish_omp_atomic (TREE_CODE (op1), lhs, rhs); ! } break; default: Index: semantics.c =================================================================== *** semantics.c (revision 121287) --- semantics.c (working copy) *************** finish_omp_for (location_t locus, tree d *** 3867,3907 **** void finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) { - tree orig_lhs; - tree orig_rhs; - bool dependent_p; tree stmt; ! orig_lhs = lhs; ! orig_rhs = rhs; ! dependent_p = false; ! stmt = NULL_TREE; ! ! /* Even in a template, we can detect invalid uses of the atomic ! pragma if neither LHS nor RHS is type-dependent. */ ! if (processing_template_decl) ! { ! dependent_p = (type_dependent_expression_p (lhs) ! || type_dependent_expression_p (rhs)); ! if (!dependent_p) { lhs = build_non_dependent_expr (lhs); rhs = build_non_dependent_expr (rhs); } ! } ! if (!dependent_p) ! { stmt = c_finish_omp_atomic (code, lhs, rhs); - if (stmt == error_mark_node) - return; - } - if (processing_template_decl) - { - stmt = build2 (OMP_ATOMIC, void_type_node, orig_lhs, orig_rhs); - OMP_ATOMIC_DEPENDENT_P (stmt) = 1; - OMP_ATOMIC_CODE (stmt) = code; } ! add_stmt (stmt); } void --- 3867,3894 ---- void finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) { tree stmt; ! if (processing_template_decl ! && (type_dependent_expression_p (lhs) ! || type_dependent_expression_p (rhs))) ! stmt = build2 (OMP_ATOMIC, void_type_node, integer_zero_node, ! build2 (code, void_type_node, lhs, rhs)); ! else ! { ! /* Even in a template, we can detect invalid uses of the atomic ! pragma if neither LHS nor RHS is type-dependent. */ ! if (processing_template_decl) { lhs = build_non_dependent_expr (lhs); rhs = build_non_dependent_expr (rhs); } ! stmt = c_finish_omp_atomic (code, lhs, rhs); } ! ! if (stmt != error_mark_node) ! add_stmt (stmt); } void