+#endif
+/*-----------------------------------------------------------------*/
+/* replaceAstWithTemporary: Replace the AST pointed to by the arg */
+/* with a reference to a new temporary variable. Returns*/
+/* an AST which assigns the original value to the */
+/* temporary. */
+/*-----------------------------------------------------------------*/
+static ast *replaceAstWithTemporary(ast **treeptr)
+{
+ symbol *sym = newSymbol (genSymName(NestLevel), NestLevel );
+ ast *tempvar;
+
+ /* Tell gatherImplicitVariables() to automatically give the
+ symbol the correct type */
+ sym->infertype = 1;
+ sym->type = NULL;
+ sym->etype = NULL;
+
+ tempvar = newNode('=', newAst_VALUE(symbolVal(sym)), *treeptr);
+ *treeptr = newAst_VALUE(symbolVal(sym));
+
+ addSymChain(&sym);
+
+ return tempvar;
+}
+
+/*-----------------------------------------------------------------*/
+/* createRMW: Create a read-modify-write expression, using a */
+/* temporary variable if necessary to avoid duplicating */
+/* any side effects, for use in e.g. */
+/* foo()->count += 5; becomes */
+/* tmp = foo(); tmp->count = tmp->count + 5; */
+/*-----------------------------------------------------------------*/
+ast * createRMW (ast *target, unsigned op, ast *operand)
+{
+ ast *readval, *writeval;
+ ast *tempvar1 = NULL;
+ ast *tempvar2 = NULL;
+ ast *result;
+
+ if (!target || !operand) {
+ return NULL;
+ }
+
+ /* we need to create two copies of target: one to read from and
+ one to write to. but we need to do this without duplicating
+ any side effects that may be contained in the tree. */
+
+ if (IS_AST_OP(target)) {
+ /* if this is a dereference, put the referenced item in the temporary */
+ if (IS_DEREF_OP(target) || target->opval.op == PTR_OP) {
+ /* create a new temporary containing the item being dereferenced */
+ if (hasSEFcalls(target->left))
+ tempvar1 = replaceAstWithTemporary(&(target->left));
+ } else if (target->opval.op == '[') {
+ /* Array access is similar, but we have to avoid side effects in
+ both values [WIML: Why not transform a[b] to *(a+b) in parser?] */
+ if (hasSEFcalls(target->left))
+ tempvar1 = replaceAstWithTemporary(&(target->left));
+ if (hasSEFcalls(target->right))
+ tempvar2 = replaceAstWithTemporary(&(target->right));
+ } else {
+ /* we would have to handle '.', but it is not generated any more */
+ wassertl(target->opval.op != '.', "obsolete opcode in tree");
+
+ /* no other kinds of ASTs are lvalues and can contain side effects */
+ }
+ }
+
+ readval = target;
+ writeval = copyAst(target);
+
+ result = newNode('=', writeval, newNode(op, readval, operand));
+ if (tempvar2)
+ result = newNode(',', tempvar2, result);
+ if (tempvar1)
+ result = newNode(',', tempvar1, result);
+
+ return result;
+
+}