Module Name:    src
Committed By:   rillig
Date:           Sat Mar  9 13:54:47 UTC 2024

Modified Files:
        src/usr.bin/xlint/lint1: README.md cgram.y ckbool.c ckctype.c
            ckgetopt.c cksnprintb.c debug.c emit1.c func.c init.c lint1.h
            tree.c

Log Message:
lint: inline accessor macros for tnode_t


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/usr.bin/xlint/lint1/README.md
cvs rdiff -u -r1.490 -r1.491 src/usr.bin/xlint/lint1/cgram.y
cvs rdiff -u -r1.29 -r1.30 src/usr.bin/xlint/lint1/ckbool.c
cvs rdiff -u -r1.10 -r1.11 src/usr.bin/xlint/lint1/ckctype.c
cvs rdiff -u -r1.25 -r1.26 src/usr.bin/xlint/lint1/ckgetopt.c
cvs rdiff -u -r1.8 -r1.9 src/usr.bin/xlint/lint1/cksnprintb.c
cvs rdiff -u -r1.72 -r1.73 src/usr.bin/xlint/lint1/debug.c
cvs rdiff -u -r1.91 -r1.92 src/usr.bin/xlint/lint1/emit1.c
cvs rdiff -u -r1.183 -r1.184 src/usr.bin/xlint/lint1/func.c
cvs rdiff -u -r1.262 -r1.263 src/usr.bin/xlint/lint1/init.c
cvs rdiff -u -r1.220 -r1.221 src/usr.bin/xlint/lint1/lint1.h
cvs rdiff -u -r1.611 -r1.612 src/usr.bin/xlint/lint1/tree.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/xlint/lint1/README.md
diff -u src/usr.bin/xlint/lint1/README.md:1.15 src/usr.bin/xlint/lint1/README.md:1.16
--- src/usr.bin/xlint/lint1/README.md:1.15	Mon Feb  5 23:11:22 2024
+++ src/usr.bin/xlint/lint1/README.md	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-[//]: # ($NetBSD: README.md,v 1.15 2024/02/05 23:11:22 rillig Exp $)
+[//]: # ($NetBSD: README.md,v 1.16 2024/03/09 13:54:47 rillig Exp $)
 
 # Introduction
 
@@ -108,15 +108,15 @@ Each node has an operator that defines w
 The operators and their properties are defined in `oper.c`.
 Some examples for operators:
 
-| Operator | Meaning                                    |
-|----------|--------------------------------------------|
-| CON      | compile-time constant in `tn_val`          |
-| NAME     | references the identifier in `tn_sym`      |
-| UPLUS    | the unary operator `+tn_left`              |
-| PLUS     | the binary operator `tn_left + tn_right`   |
-| CALL     | a direct function call                     |
-| ICALL    | an indirect function call                  |
-| CVT      | an implicit conversion or an explicit cast |
+| Operator | Meaning                                        |
+|----------|------------------------------------------------|
+| CON      | compile-time constant in `u.value`             |
+| NAME     | references the identifier in `u.sym`           |
+| UPLUS    | the unary operator `+u.ops.left`               |
+| PLUS     | the binary operator `u.ops.left + u.ops.right` |
+| CALL     | a direct function call                         |
+| ICALL    | an indirect function call                      |
+| CVT      | an implicit conversion or an explicit cast     |
 
 As an example, the expression `strcmp(names[i], "name")` has this internal
 structure:

Index: src/usr.bin/xlint/lint1/cgram.y
diff -u src/usr.bin/xlint/lint1/cgram.y:1.490 src/usr.bin/xlint/lint1/cgram.y:1.491
--- src/usr.bin/xlint/lint1/cgram.y:1.490	Sat Mar  9 10:41:11 2024
+++ src/usr.bin/xlint/lint1/cgram.y	Sat Mar  9 13:54:47 2024
@@ -1,5 +1,5 @@
 %{
-/* $NetBSD: cgram.y,v 1.490 2024/03/09 10:41:11 rillig Exp $ */
+/* $NetBSD: cgram.y,v 1.491 2024/03/09 13:54:47 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: cgram.y,v 1.490 2024/03/09 10:41:11 rillig Exp $");
+__RCSID("$NetBSD: cgram.y,v 1.491 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <limits.h>
@@ -625,7 +625,7 @@ gcc_statement_expr_item:
 		} else {
 			/* XXX: do that only on the last name */
 			if ($1->tn_op == NAME)
-				$1->tn_sym->s_used = true;
+				$1->u.sym->s_used = true;
 			expr($1, false, false, false, false);
 			suppress_fallthrough = false;
 			$$ = $1;

Index: src/usr.bin/xlint/lint1/ckbool.c
diff -u src/usr.bin/xlint/lint1/ckbool.c:1.29 src/usr.bin/xlint/lint1/ckbool.c:1.30
--- src/usr.bin/xlint/lint1/ckbool.c:1.29	Sat Feb  3 12:57:12 2024
+++ src/usr.bin/xlint/lint1/ckbool.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ckbool.c,v 1.29 2024/02/03 12:57:12 rillig Exp $ */
+/* $NetBSD: ckbool.c,v 1.30 2024/03/09 13:54:47 rillig Exp $ */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #include <sys/cdefs.h>
 
 #if defined(__RCSID)
-__RCSID("$NetBSD: ckbool.c,v 1.29 2024/02/03 12:57:12 rillig Exp $");
+__RCSID("$NetBSD: ckbool.c,v 1.30 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <string.h>
@@ -73,7 +73,7 @@ is_symmetric_bool_or_other(op_t op)
 static bool
 is_int_constant_zero(const tnode_t *tn, tspec_t t)
 {
-	return t == INT && tn->tn_op == CON && tn->tn_val.u.integer == 0;
+	return t == INT && tn->tn_op == CON && tn->u.value.u.integer == 0;
 }
 
 static bool
@@ -201,7 +201,7 @@ bool
 is_typeok_bool_compares_with_zero(const tnode_t *tn)
 {
 	while (tn->tn_op == COMMA)
-		tn = tn->tn_right;
+		tn = tn->u.ops.right;
 	tn = before_conversion(tn);
 
 	return tn->tn_type->t_tspec == BOOL

Index: src/usr.bin/xlint/lint1/ckctype.c
diff -u src/usr.bin/xlint/lint1/ckctype.c:1.10 src/usr.bin/xlint/lint1/ckctype.c:1.11
--- src/usr.bin/xlint/lint1/ckctype.c:1.10	Mon Feb  5 23:11:22 2024
+++ src/usr.bin/xlint/lint1/ckctype.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ckctype.c,v 1.10 2024/02/05 23:11:22 rillig Exp $ */
+/* $NetBSD: ckctype.c,v 1.11 2024/03/09 13:54:47 rillig Exp $ */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #include <sys/cdefs.h>
 
 #if defined(__RCSID)
-__RCSID("$NetBSD: ckctype.c,v 1.10 2024/02/05 23:11:22 rillig Exp $");
+__RCSID("$NetBSD: ckctype.c,v 1.11 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <string.h>
@@ -99,7 +99,7 @@ check_ctype_arg(const char *func, const 
 {
 	const tnode_t *on, *cn;
 
-	for (on = arg; on->tn_op == CVT; on = on->tn_left)
+	for (on = arg; on->tn_op == CVT; on = on->u.ops.left)
 		if (on->tn_type->t_tspec == UCHAR)
 			return;
 	if (on->tn_type->t_tspec == UCHAR)
@@ -125,8 +125,8 @@ check_ctype_function_call(const function
 
 	if (call->args_len == 1 && call->args != NULL &&
 	    call->func->tn_op == NAME &&
-	    is_ctype_function(call->func->tn_sym->s_name))
-		check_ctype_arg(call->func->tn_sym->s_name, call->args[0]);
+	    is_ctype_function(call->func->u.sym->s_name))
+		check_ctype_arg(call->func->u.sym->s_name, call->args[0]);
 }
 
 void
@@ -134,10 +134,10 @@ check_ctype_macro_invocation(const tnode
 {
 
 	if (ln->tn_op == PLUS &&
-	    ln->tn_left != NULL &&
-	    ln->tn_left->tn_op == LOAD &&
-	    ln->tn_left->tn_left != NULL &&
-	    ln->tn_left->tn_left->tn_op == NAME &&
-	    is_ctype_table(ln->tn_left->tn_left->tn_sym->s_name))
+	    ln->u.ops.left != NULL &&
+	    ln->u.ops.left->tn_op == LOAD &&
+	    ln->u.ops.left->u.ops.left != NULL &&
+	    ln->u.ops.left->u.ops.left->tn_op == NAME &&
+	    is_ctype_table(ln->u.ops.left->u.ops.left->u.sym->s_name))
 		check_ctype_arg("function from <ctype.h>", rn);
 }

Index: src/usr.bin/xlint/lint1/ckgetopt.c
diff -u src/usr.bin/xlint/lint1/ckgetopt.c:1.25 src/usr.bin/xlint/lint1/ckgetopt.c:1.26
--- src/usr.bin/xlint/lint1/ckgetopt.c:1.25	Sun Mar  3 16:09:01 2024
+++ src/usr.bin/xlint/lint1/ckgetopt.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ckgetopt.c,v 1.25 2024/03/03 16:09:01 rillig Exp $ */
+/* $NetBSD: ckgetopt.c,v 1.26 2024/03/09 13:54:47 rillig Exp $ */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: ckgetopt.c,v 1.25 2024/03/03 16:09:01 rillig Exp $");
+__RCSID("$NetBSD: ckgetopt.c,v 1.26 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <stdbool.h>
@@ -86,23 +86,23 @@ is_getopt_condition(const tnode_t *tn, c
 	if (tn != NULL
 	    && tn->tn_op == NE
 
-	    && tn->tn_right->tn_op == CON
-	    && tn->tn_right->tn_u._tn_val.v_tspec == INT
-	    && tn->tn_right->tn_u._tn_val.u.integer == -1
-
-	    && tn->tn_left->tn_op == ASSIGN
-	    && tn->tn_left->tn_right->tn_op == CALL
-	    && (call = tn->tn_left->tn_right->tn_call)->func->tn_op == ADDR
-	    && call->func->tn_left->tn_op == NAME
-	    && strcmp(call->func->tn_left->tn_sym->s_name, "getopt") == 0
+	    && tn->u.ops.right->tn_op == CON
+	    && tn->u.ops.right->u.value.v_tspec == INT
+	    && tn->u.ops.right->u.value.u.integer == -1
+
+	    && tn->u.ops.left->tn_op == ASSIGN
+	    && tn->u.ops.left->u.ops.right->tn_op == CALL
+	    && (call = tn->u.ops.left->u.ops.right->u.call)->func->tn_op == ADDR
+	    && call->func->u.ops.left->tn_op == NAME
+	    && strcmp(call->func->u.ops.left->u.sym->s_name, "getopt") == 0
 	    && call->args_len == 3
 	    && call->args != NULL
 
 	    && (last_arg = call->args[2]) != NULL
 	    && last_arg->tn_op == CVT
-	    && last_arg->tn_left->tn_op == ADDR
-	    && last_arg->tn_left->tn_left->tn_op == STRING
-	    && (str = last_arg->tn_left->tn_left->tn_string)->data != NULL) {
+	    && last_arg->u.ops.left->tn_op == ADDR
+	    && last_arg->u.ops.left->u.ops.left->tn_op == STRING
+	    && (str = last_arg->u.ops.left->u.ops.left->u.str_literals)->data != NULL) {
 		buffer buf;
 		buf_init(&buf);
 		quoted_iterator it = { .end = 0 };

Index: src/usr.bin/xlint/lint1/cksnprintb.c
diff -u src/usr.bin/xlint/lint1/cksnprintb.c:1.8 src/usr.bin/xlint/lint1/cksnprintb.c:1.9
--- src/usr.bin/xlint/lint1/cksnprintb.c:1.8	Sat Mar  9 10:47:16 2024
+++ src/usr.bin/xlint/lint1/cksnprintb.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: cksnprintb.c,v 1.8 2024/03/09 10:47:16 rillig Exp $	*/
+/*	$NetBSD: cksnprintb.c,v 1.9 2024/03/09 13:54:47 rillig Exp $	*/
 
 /*-
  * Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: cksnprintb.c,v 1.8 2024/03/09 10:47:16 rillig Exp $");
+__RCSID("$NetBSD: cksnprintb.c,v 1.9 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <stdbool.h>
@@ -59,10 +59,10 @@ static bool
 match_string_literal(const tnode_t *tn, const buffer **str)
 {
 	while (tn->tn_op == CVT)
-		tn = tn->tn_left;
+		tn = tn->u.ops.left;
 	return tn->tn_op == ADDR
-	    && tn->tn_left->tn_op == STRING
-	    && (*str = tn->tn_left->tn_string, (*str)->data != NULL);
+	    && tn->u.ops.left->tn_op == STRING
+	    && (*str = tn->u.ops.left->u.str_literals, (*str)->data != NULL);
 }
 
 static bool
@@ -74,8 +74,8 @@ match_snprintb_call(const function_call 
 	const buffer *str;
 
 	if (call->func->tn_op == ADDR
-	    && call->func->tn_left->tn_op == NAME
-	    && (func = call->func->tn_left->tn_sym->s_name, true)
+	    && call->func->u.ops.left->tn_op == NAME
+	    && (func = call->func->u.ops.left->u.sym->s_name, true)
 	    && ((strcmp(func, "snprintb") == 0 && call->args_len == 4)
 		|| (strcmp(func, "snprintb_m") == 0 && call->args_len == 5))
 	    && match_string_literal(call->args[2], &str)
@@ -329,7 +329,7 @@ check_snprintb(const tnode_t *expr)
 {
 	const buffer *fmt;
 	const tnode_t *value;
-	if (!match_snprintb_call(expr->tn_call, &fmt, &value))
+	if (!match_snprintb_call(expr->u.call, &fmt, &value))
 		return;
 
 	checker ck = {

Index: src/usr.bin/xlint/lint1/debug.c
diff -u src/usr.bin/xlint/lint1/debug.c:1.72 src/usr.bin/xlint/lint1/debug.c:1.73
--- src/usr.bin/xlint/lint1/debug.c:1.72	Sat Mar  9 13:20:55 2024
+++ src/usr.bin/xlint/lint1/debug.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: debug.c,v 1.72 2024/03/09 13:20:55 rillig Exp $ */
+/* $NetBSD: debug.c,v 1.73 2024/03/09 13:54:47 rillig Exp $ */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: debug.c,v 1.72 2024/03/09 13:20:55 rillig Exp $");
+__RCSID("$NetBSD: debug.c,v 1.73 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -198,8 +198,8 @@ debug_node(const tnode_t *tn) // NOLINT(
 	    op == CVT && tn->tn_cast ? "cast" : op_name(op));
 	if (op == NAME)
 		debug_printf(" '%s' with %s",
-		    tn->tn_sym->s_name,
-		    scl_name(tn->tn_sym->s_scl));
+		    tn->u.sym->s_name,
+		    scl_name(tn->u.sym->s_scl));
 	else
 		debug_printf(" type");
 	debug_printf(" '%s'", type_name(tn->tn_type));
@@ -216,36 +216,36 @@ debug_node(const tnode_t *tn) // NOLINT(
 		break;
 	case CON:
 		if (is_floating(tn->tn_type->t_tspec))
-			debug_printf(", value %Lg", tn->tn_val.u.floating);
+			debug_printf(", value %Lg", tn->u.value.u.floating);
 		else if (is_uinteger(tn->tn_type->t_tspec))
 			debug_printf(", value %llu",
-			    (unsigned long long)tn->tn_val.u.integer);
+			    (unsigned long long)tn->u.value.u.integer);
 		else if (is_integer(tn->tn_type->t_tspec))
 			debug_printf(", value %lld",
-			    (long long)tn->tn_val.u.integer);
+			    (long long)tn->u.value.u.integer);
 		else {
 			lint_assert(tn->tn_type->t_tspec == BOOL);
 			debug_printf(", value %s",
-			    tn->tn_val.u.integer != 0 ? "true" : "false");
+			    tn->u.value.u.integer != 0 ? "true" : "false");
 		}
-		if (tn->tn_val.v_unsigned_since_c90)
+		if (tn->u.value.v_unsigned_since_c90)
 			debug_printf(", unsigned_since_c90");
-		if (tn->tn_val.v_char_constant)
+		if (tn->u.value.v_char_constant)
 			debug_printf(", char_constant");
 		debug_printf("\n");
 		break;
 	case STRING:
-		if (tn->tn_string->data != NULL)
-			debug_printf(", %s\n", tn->tn_string->data);
+		if (tn->u.str_literals->data != NULL)
+			debug_printf(", %s\n", tn->u.str_literals->data);
 		else
-			debug_printf(", length %zu\n", tn->tn_string->len);
+			debug_printf(", length %zu\n", tn->u.str_literals->len);
 		break;
 	case CALL:
 	case ICALL:
 		debug_printf("\n");
 
 		debug_indent_inc();
-		const function_call *call = tn->tn_call;
+		const function_call *call = tn->u.call;
 		debug_node(call->func);
 		if (call->args != NULL) {
 			for (size_t i = 0; i < call->args_len; i++)
@@ -259,14 +259,14 @@ debug_node(const tnode_t *tn) // NOLINT(
 
 		debug_indent_inc();
 		lint_assert(has_operands(tn));
-		lint_assert(tn->tn_left != NULL);
-		debug_node(tn->tn_left);
+		lint_assert(tn->u.ops.left != NULL);
+		debug_node(tn->u.ops.left);
 		if (op != INCBEF && op != INCAFT
 		    && op != DECBEF && op != DECAFT
 		    && op != CALL && op != ICALL)
-			lint_assert(is_binary(tn) == (tn->tn_right != NULL));
-		if (tn->tn_right != NULL)
-			debug_node(tn->tn_right);
+			lint_assert(is_binary(tn) == (tn->u.ops.right != NULL));
+		if (tn->u.ops.right != NULL)
+			debug_node(tn->u.ops.right);
 		debug_indent_dec();
 	}
 }

Index: src/usr.bin/xlint/lint1/emit1.c
diff -u src/usr.bin/xlint/lint1/emit1.c:1.91 src/usr.bin/xlint/lint1/emit1.c:1.92
--- src/usr.bin/xlint/lint1/emit1.c:1.91	Sat Mar  9 13:20:55 2024
+++ src/usr.bin/xlint/lint1/emit1.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: emit1.c,v 1.91 2024/03/09 13:20:55 rillig Exp $ */
+/* $NetBSD: emit1.c,v 1.92 2024/03/09 13:54:47 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: emit1.c,v 1.91 2024/03/09 13:20:55 rillig Exp $");
+__RCSID("$NetBSD: emit1.c,v 1.92 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -335,7 +335,7 @@ outcall(const tnode_t *tn, bool retval_u
 	 * flags; 'u' and 'i' must be last to make sure a letter is between the
 	 * numeric argument of a flag and the name of the function
 	 */
-	const function_call *call = tn->tn_call;
+	const function_call *call = tn->u.call;
 
 	/* information about arguments */
 	for (size_t n = 1; call->args != NULL && n <= call->args_len; n++) {
@@ -347,7 +347,7 @@ outcall(const tnode_t *tn, bool retval_u
 				 * XXX it would probably be better to
 				 * explicitly test the sign
 				 */
-				int64_t si = arg->tn_val.u.integer;
+				int64_t si = arg->u.value.u.integer;
 				if (si == 0)
 					/* zero constant */
 					outchar('z');
@@ -360,12 +360,12 @@ outcall(const tnode_t *tn, bool retval_u
 				outint((int)n);
 			}
 		} else if (arg->tn_op == ADDR &&
-		    arg->tn_left->tn_op == STRING &&
-		    arg->tn_left->tn_string->data != NULL) {
+		    arg->u.ops.left->tn_op == STRING &&
+		    arg->u.ops.left->u.str_literals->data != NULL) {
 			buffer buf;
 			buf_init(&buf);
 			quoted_iterator it = { .end = 0 };
-			while (quoted_next(arg->tn_left->tn_string, &it))
+			while (quoted_next(arg->u.ops.left->u.str_literals, &it))
 				buf_add_char(&buf, (char)it.value);
 
 			/* string literal, write all format specifiers */
@@ -377,7 +377,7 @@ outcall(const tnode_t *tn, bool retval_u
 	}
 	outchar((char)(retval_discarded ? 'd' : retval_used ? 'u' : 'i'));
 
-	outname(call->func->tn_left->tn_sym->s_name);
+	outname(call->func->u.ops.left->u.sym->s_name);
 
 	/* types of arguments */
 	outchar('f');

Index: src/usr.bin/xlint/lint1/func.c
diff -u src/usr.bin/xlint/lint1/func.c:1.183 src/usr.bin/xlint/lint1/func.c:1.184
--- src/usr.bin/xlint/lint1/func.c:1.183	Sat Mar  9 13:20:55 2024
+++ src/usr.bin/xlint/lint1/func.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: func.c,v 1.183 2024/03/09 13:20:55 rillig Exp $	*/
+/*	$NetBSD: func.c,v 1.184 2024/03/09 13:54:47 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: func.c,v 1.183 2024/03/09 13:20:55 rillig Exp $");
+__RCSID("$NetBSD: func.c,v 1.184 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -401,12 +401,12 @@ static void
 check_case_label_bitand(const tnode_t *case_expr, const tnode_t *switch_expr)
 {
 	if (switch_expr->tn_op != BITAND ||
-	    switch_expr->tn_right->tn_op != CON)
+	    switch_expr->u.ops.right->tn_op != CON)
 		return;
 
 	lint_assert(case_expr->tn_op == CON);
-	uint64_t case_value = (uint64_t)case_expr->tn_val.u.integer;
-	uint64_t mask = (uint64_t)switch_expr->tn_right->tn_val.u.integer;
+	uint64_t case_value = (uint64_t)case_expr->u.value.u.integer;
+	uint64_t mask = (uint64_t)switch_expr->u.ops.right->u.value.u.integer;
 
 	if ((case_value & ~mask) != 0)
 		/* statement not reached */
@@ -908,7 +908,7 @@ static bool
 is_parenthesized(const tnode_t *tn)
 {
 	while (!tn->tn_parenthesized && tn->tn_op == COMMA)
-		tn = tn->tn_right;
+		tn = tn->u.ops.right;
 	return tn->tn_parenthesized && !tn->tn_sys;
 }
 
@@ -925,16 +925,16 @@ check_return_value(bool sys, tnode_t *tn
 	ln->tn_op = NAME;
 	ln->tn_type = expr_unqualified_type(funcsym->s_type->t_subt);
 	ln->tn_lvalue = true;
-	ln->tn_sym = funcsym;	/* better than nothing */
+	ln->u.sym = funcsym;	/* better than nothing */
 
 	tnode_t *retn = build_binary(ln, RETURN, sys, tn);
 
 	if (retn != NULL) {
-		const tnode_t *rn = retn->tn_right;
+		const tnode_t *rn = retn->u.ops.right;
 		while (rn->tn_op == CVT || rn->tn_op == PLUS)
-			rn = rn->tn_left;
-		if (rn->tn_op == ADDR && rn->tn_left->tn_op == NAME &&
-		    rn->tn_left->tn_sym->s_scl == AUTO)
+			rn = rn->u.ops.left;
+		if (rn->tn_op == ADDR && rn->u.ops.left->tn_op == NAME &&
+		    rn->u.ops.left->u.sym->s_scl == AUTO)
 			/* '%s' returns pointer to automatic object */
 			warning(302, funcsym->s_name);
 	}

Index: src/usr.bin/xlint/lint1/init.c
diff -u src/usr.bin/xlint/lint1/init.c:1.262 src/usr.bin/xlint/lint1/init.c:1.263
--- src/usr.bin/xlint/lint1/init.c:1.262	Sat Mar  9 13:20:55 2024
+++ src/usr.bin/xlint/lint1/init.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: init.c,v 1.262 2024/03/09 13:20:55 rillig Exp $	*/
+/*	$NetBSD: init.c,v 1.263 2024/03/09 13:54:47 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: init.c,v 1.262 2024/03/09 13:20:55 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.263 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -272,7 +272,7 @@ check_init_expr(const type_t *ltp, sym_t
 	ln->tn_op = NAME;
 	ln->tn_type = lutp;
 	ln->tn_lvalue = true;
-	ln->tn_sym = lsym;
+	ln->u.sym = lsym;
 
 	rn = cconv(rn);
 
@@ -885,10 +885,10 @@ initialization_init_array_from_string(in
 	if (!can_init_character_array(tp, tn))
 		return false;
 
-	size_t len = tn->tn_string->len;
-	if (tn->tn_string->data != NULL) {
+	size_t len = tn->u.str_literals->len;
+	if (tn->u.str_literals->data != NULL) {
 		quoted_iterator it = { .end = 0 };
-		for (len = 0; quoted_next(tn->tn_string, &it); len++)
+		for (len = 0; quoted_next(tn->u.str_literals, &it); len++)
 			continue;
 	}
 

Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.220 src/usr.bin/xlint/lint1/lint1.h:1.221
--- src/usr.bin/xlint/lint1/lint1.h:1.220	Sat Mar  9 13:20:55 2024
+++ src/usr.bin/xlint/lint1/lint1.h	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.220 2024/03/09 13:20:55 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.221 2024/03/09 13:54:47 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -277,12 +277,12 @@ struct tnode {
 	bool	tn_system_dependent:1; /* depends on sizeof or offsetof */
 	union {
 		struct {
-			tnode_t *_tn_left;	/* (left) operand */
-			tnode_t *_tn_right;	/* right operand */
-		} tn_s;
-		sym_t	*_tn_sym;	/* symbol if op == NAME */
-		val_t	_tn_val;	/* value if op == CON */
-		buffer	*_tn_string;	/* string if op == STRING; for
+			tnode_t *left;	/* (left) operand */
+			tnode_t *right;	/* right operand */
+		} ops;
+		sym_t	*sym;		/* if NAME */
+		val_t	value;		/* if CON */
+		buffer	*str_literals;	/* if STRING; for
 					 * character strings, 'data' points to
 					 * the concatenated string literals in
 					 * source form, and 'len' is the
@@ -290,17 +290,10 @@ struct tnode {
 					 * wide strings, 'data' is NULL and
 					 * 'len' is the number of resulting
 					 * characters */
-		function_call *_tn_call;
-	} tn_u;
+		function_call *call;	/* if CALL or ICALL */
+	} u;
 };
 
-#define	tn_left		tn_u.tn_s._tn_left
-#define tn_right	tn_u.tn_s._tn_right
-#define tn_sym		tn_u._tn_sym
-#define	tn_val		tn_u._tn_val
-#define	tn_string	tn_u._tn_string
-#define tn_call		tn_u._tn_call
-
 struct generic_association {
 	type_t *ga_arg;		/* NULL means default or error */
 	tnode_t *ga_result;	/* NULL means error */
@@ -605,20 +598,20 @@ static inline bool
 constant_is_nonzero(const tnode_t *tn)
 {
 	lint_assert(tn->tn_op == CON);
-	lint_assert(tn->tn_type->t_tspec == tn->tn_val.v_tspec);
-	return is_nonzero_val(&tn->tn_val);
+	lint_assert(tn->tn_type->t_tspec == tn->u.value.v_tspec);
+	return is_nonzero_val(&tn->u.value);
 }
 
 static inline bool
 is_zero(const tnode_t *tn)
 {
-	return tn != NULL && tn->tn_op == CON && !is_nonzero_val(&tn->tn_val);
+	return tn != NULL && tn->tn_op == CON && !is_nonzero_val(&tn->u.value);
 }
 
 static inline bool
 is_nonzero(const tnode_t *tn)
 {
-	return tn != NULL && tn->tn_op == CON && is_nonzero_val(&tn->tn_val);
+	return tn != NULL && tn->tn_op == CON && is_nonzero_val(&tn->u.value);
 }
 
 static inline const char *

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.611 src/usr.bin/xlint/lint1/tree.c:1.612
--- src/usr.bin/xlint/lint1/tree.c:1.611	Sat Mar  9 13:20:55 2024
+++ src/usr.bin/xlint/lint1/tree.c	Sat Mar  9 13:54:47 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.611 2024/03/09 13:20:55 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.612 2024/03/09 13:54:47 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.611 2024/03/09 13:20:55 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.612 2024/03/09 13:54:47 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -282,35 +282,35 @@ ic_expr(const tnode_t *tn)
 
 	switch (tn->tn_op) {
 	case CON:
-		return ic_con(tn->tn_type, &tn->tn_val);
+		return ic_con(tn->tn_type, &tn->u.value);
 	case CVT:
-		if (!is_integer(tn->tn_left->tn_type->t_tspec))
+		if (!is_integer(tn->u.ops.left->tn_type->t_tspec))
 			return ic_any(tn->tn_type);
-		lc = ic_expr(tn->tn_left);
-		return ic_cvt(tn->tn_type, tn->tn_left->tn_type, lc);
+		lc = ic_expr(tn->u.ops.left);
+		return ic_cvt(tn->tn_type, tn->u.ops.left->tn_type, lc);
 	case MOD:
-		lc = ic_expr(before_conversion(tn->tn_left));
-		rc = ic_expr(before_conversion(tn->tn_right));
+		lc = ic_expr(before_conversion(tn->u.ops.left));
+		rc = ic_expr(before_conversion(tn->u.ops.right));
 		return ic_mod(tn->tn_type, lc, rc);
 	case SHL:
-		lc = ic_expr(tn->tn_left);
-		rc = ic_expr(tn->tn_right);
+		lc = ic_expr(tn->u.ops.left);
+		rc = ic_expr(tn->u.ops.right);
 		return ic_shl(tn->tn_type, lc, rc);
 	case SHR:
-		lc = ic_expr(tn->tn_left);
-		rc = ic_expr(tn->tn_right);
+		lc = ic_expr(tn->u.ops.left);
+		rc = ic_expr(tn->u.ops.right);
 		return ic_shr(tn->tn_type, lc, rc);
 	case BITAND:
-		lc = ic_expr(tn->tn_left);
-		rc = ic_expr(tn->tn_right);
+		lc = ic_expr(tn->u.ops.left);
+		rc = ic_expr(tn->u.ops.right);
 		return ic_bitand(lc, rc);
 	case BITOR:
-		lc = ic_expr(tn->tn_left);
-		rc = ic_expr(tn->tn_right);
+		lc = ic_expr(tn->u.ops.left);
+		rc = ic_expr(tn->u.ops.right);
 		return ic_bitor(lc, rc);
 	case QUEST:
-		lc = ic_expr(tn->tn_right->tn_left);
-		rc = ic_expr(tn->tn_right->tn_right);
+		lc = ic_expr(tn->u.ops.right->u.ops.left);
+		rc = ic_expr(tn->u.ops.right->u.ops.right);
 		return ic_cond(lc, rc);
 	default:
 		return ic_any(tn->tn_type);
@@ -357,8 +357,8 @@ build_op(op_t op, bool sys, type_t *type
 	ntn->tn_op = op;
 	ntn->tn_type = type;
 	ntn->tn_sys = sys;
-	ntn->tn_left = ln;
-	ntn->tn_right = rn;
+	ntn->u.ops.left = ln;
+	ntn->u.ops.right = rn;
 
 	if (op == INDIR || op == FSEL) {
 		lint_assert(ln->tn_type->t_tspec == PTR);
@@ -376,8 +376,8 @@ build_constant(type_t *tp, val_t *v)
 	tnode_t *n = expr_alloc_tnode();
 	n->tn_op = CON;
 	n->tn_type = tp;
-	n->tn_val = *v;
-	n->tn_val.v_tspec = tp->t_tspec;
+	n->u.value = *v;
+	n->u.value.v_tspec = tp->t_tspec;
 	free(v);
 	return n;
 }
@@ -389,10 +389,10 @@ build_integer_constant(tspec_t t, int64_
 	tnode_t *n = expr_alloc_tnode();
 	n->tn_op = CON;
 	n->tn_type = gettyp(t);
-	n->tn_val.v_tspec = t;
-	n->tn_val.v_unsigned_since_c90 = false;
-	n->tn_val.v_char_constant = false;
-	n->tn_val.u.integer = si;
+	n->u.value.v_tspec = t;
+	n->u.value.v_unsigned_since_c90 = false;
+	n->u.value.v_char_constant = false;
+	n->u.value.u.integer = si;
 	return n;
 }
 
@@ -504,19 +504,19 @@ build_name(sym_t *sym, bool is_funcname)
 	n->tn_type = sym->s_type;
 	if (sym->s_scl == BOOL_CONST) {
 		n->tn_op = CON;
-		n->tn_val.v_tspec = BOOL;
-		n->tn_val.v_unsigned_since_c90 = false;
-		n->tn_val.v_char_constant = false;
-		n->tn_val.u.integer = sym->u.s_bool_constant ? 1 : 0;
+		n->u.value.v_tspec = BOOL;
+		n->u.value.v_unsigned_since_c90 = false;
+		n->u.value.v_char_constant = false;
+		n->u.value.u.integer = sym->u.s_bool_constant ? 1 : 0;
 	} else if (sym->s_scl == ENUM_CONST) {
 		n->tn_op = CON;
-		n->tn_val.v_tspec = INT;	/* ENUM is in n->tn_type */
-		n->tn_val.v_unsigned_since_c90 = false;
-		n->tn_val.v_char_constant = false;
-		n->tn_val.u.integer = sym->u.s_enum_constant;
+		n->u.value.v_tspec = INT;	/* ENUM is in n->tn_type */
+		n->u.value.v_unsigned_since_c90 = false;
+		n->u.value.v_char_constant = false;
+		n->u.value.u.integer = sym->u.s_enum_constant;
 	} else {
 		n->tn_op = NAME;
-		n->tn_sym = sym;
+		n->u.sym = sym;
 		if (sym->s_kind == SK_VCFT && sym->s_type->t_tspec != FUNC)
 			n->tn_lvalue = true;
 	}
@@ -544,13 +544,13 @@ build_string(buffer *lit)
 	n->tn_type = tp;
 	n->tn_lvalue = true;
 
-	n->tn_string = expr_zero_alloc(sizeof(*n->tn_string), "tnode.string");
-	n->tn_string->len = lit->len;
+	n->u.str_literals = expr_zero_alloc(sizeof(*n->u.str_literals), "tnode.string");
+	n->u.str_literals->len = lit->len;
 
 	if (lit->data != NULL) {
-		n->tn_string->data = expr_zero_alloc(lit->len + 1,
+		n->u.str_literals->data = expr_zero_alloc(lit->len + 1,
 		    "tnode.string.data");
-		(void)memcpy(n->tn_string->data, lit->data, lit->len + 1);
+		(void)memcpy(n->u.str_literals->data, lit->data, lit->len + 1);
 		free(lit->data);
 	}
 	free(lit);
@@ -579,9 +579,9 @@ static bool
 is_out_of_char_range(const tnode_t *tn)
 {
 	return tn->tn_op == CON &&
-	    !tn->tn_val.v_char_constant &&
-	    !(0 <= tn->tn_val.u.integer &&
-		tn->tn_val.u.integer < 1 << (CHAR_SIZE - 1));
+	    !tn->u.value.v_char_constant &&
+	    !(0 <= tn->u.value.u.integer &&
+		tn->u.value.u.integer < 1 << (CHAR_SIZE - 1));
 }
 
 static bool
@@ -595,7 +595,7 @@ check_nonportable_char_comparison(op_t o
 	if (lt == CHAR && is_out_of_char_range(rn)) {
 		char buf[128];
 		(void)snprintf(buf, sizeof(buf), "%s %d",
-		    op_name(op), (int)rn->tn_val.u.integer);
+		    op_name(op), (int)rn->u.value.u.integer);
 		/* nonportable character comparison '%s' */
 		warning(230, buf);
 		return false;
@@ -603,7 +603,7 @@ check_nonportable_char_comparison(op_t o
 	if (rt == CHAR && is_out_of_char_range(ln)) {
 		char buf[128];
 		(void)snprintf(buf, sizeof(buf), "%d %s ?",
-		    (int)ln->tn_val.u.integer, op_name(op));
+		    (int)ln->u.value.u.integer, op_name(op));
 		/* nonportable character comparison '%s' */
 		warning(230, buf);
 		return false;
@@ -626,16 +626,16 @@ check_integer_comparison(op_t op, tnode_
 
 	if (any_query_enabled && !in_system_header) {
 		if (lt == CHAR && rn->tn_op == CON &&
-		    !rn->tn_val.v_char_constant) {
+		    !rn->u.value.v_char_constant) {
 			/* comparison '%s' of 'char' with plain integer %d */
 			query_message(14,
-			    op_name(op), (int)rn->tn_val.u.integer);
+			    op_name(op), (int)rn->u.value.u.integer);
 		}
 		if (rt == CHAR && ln->tn_op == CON &&
-		    !ln->tn_val.v_char_constant) {
+		    !ln->u.value.v_char_constant) {
 			/* comparison '%s' of 'char' with plain integer %d */
 			query_message(14,
-			    op_name(op), (int)ln->tn_val.u.integer);
+			    op_name(op), (int)ln->u.value.u.integer);
 		}
 	}
 
@@ -643,8 +643,8 @@ check_integer_comparison(op_t op, tnode_
 		return;
 
 	if (is_uinteger(lt) && !is_uinteger(rt) &&
-	    rn->tn_op == CON && rn->tn_val.u.integer <= 0) {
-		if (rn->tn_val.u.integer < 0) {
+	    rn->tn_op == CON && rn->u.value.u.integer <= 0) {
+		if (rn->u.value.u.integer < 0) {
 			/* operator '%s' compares '%s' with '%s' */
 			warning(162, op_name(op),
 			    type_name(ln->tn_type), "negative constant");
@@ -654,8 +654,8 @@ check_integer_comparison(op_t op, tnode_
 		return;
 	}
 	if (is_uinteger(rt) && !is_uinteger(lt) &&
-	    ln->tn_op == CON && ln->tn_val.u.integer <= 0) {
-		if (ln->tn_val.u.integer < 0) {
+	    ln->tn_op == CON && ln->u.value.u.integer <= 0) {
+		if (ln->u.value.u.integer < 0) {
 			/* operator '%s' compares '%s' with '%s' */
 			warning(162, op_name(op),
 			    "negative constant", type_name(rn->tn_type));
@@ -778,9 +778,9 @@ build_address(bool sys, tnode_t *tn, boo
 
 	/* eliminate '&*' */
 	if (tn->tn_op == INDIR &&
-	    tn->tn_left->tn_type->t_tspec == PTR &&
-	    tn->tn_left->tn_type->t_subt == tn->tn_type) {
-		return tn->tn_left;
+	    tn->u.ops.left->tn_type->t_tspec == PTR &&
+	    tn->u.ops.left->tn_type->t_subt == tn->tn_type) {
+		return tn->u.ops.left;
 	}
 
 	return build_op(ADDR, sys, expr_derive_type(tn->tn_type, PTR),
@@ -801,12 +801,12 @@ fold_constant_integer(tnode_t *tn)
 	v->v_tspec = tn->tn_type->t_tspec;
 
 	lint_assert(has_operands(tn));
-	tspec_t t = tn->tn_left->tn_type->t_tspec;
+	tspec_t t = tn->u.ops.left->tn_type->t_tspec;
 	bool utyp = !is_integer(t) || is_uinteger(t);
-	int64_t sl = tn->tn_left->tn_val.u.integer, sr = 0;
+	int64_t sl = tn->u.ops.left->u.value.u.integer, sr = 0;
 	uint64_t ul = sl, ur = 0;
 	if (is_binary(tn))
-		ur = sr = tn->tn_right->tn_val.u.integer;
+		ur = sr = tn->u.ops.right->u.value.u.integer;
 
 	uint64_t mask = value_bits(size_in_bits(t));
 	bool ovfl = false;
@@ -928,9 +928,9 @@ fold_constant_integer(tnode_t *tn)
 	v->u.integer = convert_integer(si, t, 0);
 
 	tnode_t *cn = build_constant(tn->tn_type, v);
-	if (tn->tn_left->tn_system_dependent)
+	if (tn->u.ops.left->tn_system_dependent)
 		cn->tn_system_dependent = true;
-	if (is_binary(tn) && tn->tn_right->tn_system_dependent)
+	if (is_binary(tn) && tn->u.ops.right->tn_system_dependent)
 		cn->tn_system_dependent = true;
 
 	return cn;
@@ -941,7 +941,7 @@ build_struct_access(op_t op, bool sys, t
 {
 
 	lint_assert(rn->tn_op == NAME);
-	lint_assert(is_member(rn->tn_sym));
+	lint_assert(is_member(rn->u.sym));
 
 	bool lvalue = op == ARROW || ln->tn_lvalue;
 
@@ -954,7 +954,7 @@ build_struct_access(op_t op, bool sys, t
 	}
 
 	tnode_t *ctn = build_integer_constant(PTRDIFF_TSPEC,
-	    rn->tn_sym->u.s_member.sm_offset_in_bits / CHAR_SIZE);
+	    rn->u.sym->u.s_member.sm_offset_in_bits / CHAR_SIZE);
 
 	type_t *ptr_tp = expr_derive_type(rn->tn_type, PTR);
 	tnode_t *ntn = build_op(PLUS, sys, ptr_tp, ln, ctn);
@@ -1042,19 +1042,19 @@ static void
 check_enum_array_index(const tnode_t *ln, const tnode_t *rn)
 {
 
-	if (ln->tn_op != ADDR || ln->tn_left->tn_op != NAME)
+	if (ln->tn_op != ADDR || ln->u.ops.left->tn_op != NAME)
 		return;
 
-	const type_t *ltp = ln->tn_left->tn_type;
+	const type_t *ltp = ln->u.ops.left->tn_type;
 	if (ltp->t_tspec != ARRAY || ltp->t_incomplete_array)
 		return;
 
 	if (rn->tn_op != CVT || !rn->tn_type->t_is_enum)
 		return;
-	if (rn->tn_left->tn_op != LOAD)
+	if (rn->u.ops.left->tn_op != LOAD)
 		return;
 
-	const type_t *rtp = rn->tn_left->tn_type;
+	const type_t *rtp = rn->u.ops.left->tn_type;
 	const sym_t *ec = rtp->u.enumer->en_first_enumerator;
 	const sym_t *max_ec = ec;
 	lint_assert(ec != NULL);
@@ -1152,7 +1152,7 @@ is_null_pointer(const tnode_t *tn)
 	// If not, simplify the code below.
 	return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID)
 		|| is_integer(t))
-	    && (tn->tn_op == CON && tn->tn_val.u.integer == 0);
+	    && (tn->tn_op == CON && tn->u.value.u.integer == 0);
 }
 
 /* Return a type based on tp1, with added qualifiers from tp2. */
@@ -1236,7 +1236,7 @@ build_colon(bool sys, tnode_t *ln, tnode
 static bool
 is_cast_redundant(const tnode_t *tn)
 {
-	const type_t *ntp = tn->tn_type, *otp = tn->tn_left->tn_type;
+	const type_t *ntp = tn->tn_type, *otp = tn->u.ops.left->tn_type;
 	tspec_t nt = ntp->t_tspec, ot = otp->t_tspec;
 
 	if (nt == BOOL || ot == BOOL)
@@ -1309,7 +1309,7 @@ build_assignment(op_t op, bool sys, tnod
 		if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
 			rn = convert(NOOP, 0, ctn->tn_type, rn);
 		rn = build_op(MULT, sys, rn->tn_type, rn, ctn);
-		if (rn->tn_left->tn_op == CON)
+		if (rn->u.ops.left->tn_op == CON)
 			rn = fold_constant_integer(rn);
 	}
 
@@ -1344,8 +1344,8 @@ build_assignment(op_t op, bool sys, tnod
 	    types_compatible(ln->tn_type, rn->tn_type, false, false, NULL) &&
 	    is_cast_redundant(rn)) {
 		/* redundant cast from '%s' to '%s' before assignment */
-		query_message(7,
-		    type_name(rn->tn_left->tn_type), type_name(rn->tn_type));
+		query_message(7, type_name(rn->u.ops.left->tn_type),
+		    type_name(rn->tn_type));
 	}
 
 	return build_op(op, sys, ln->tn_type, ln, rn);
@@ -1361,8 +1361,8 @@ build_real_imag(op_t op, bool sys, tnode
 		 * This may be too much, but it avoids wrong warnings. See
 		 * d_c99_complex_split.c.
 		 */
-		mark_as_used(ln->tn_sym, false, false);
-		mark_as_set(ln->tn_sym);
+		mark_as_used(ln->u.sym, false, false);
+		mark_as_set(ln->u.sym);
 	}
 
 	tspec_t t;
@@ -1442,9 +1442,9 @@ check_precedence_confusion(tnode_t *tn)
 	debug_node(tn);
 
 	lint_assert(is_binary(tn));
-	for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left)
+	for (ln = tn->u.ops.left; ln->tn_op == CVT; ln = ln->u.ops.left)
 		continue;
-	for (rn = tn->tn_right; rn->tn_op == CVT; rn = rn->tn_left)
+	for (rn = tn->u.ops.right; rn->tn_op == CVT; rn = rn->u.ops.left)
 		continue;
 
 	if (is_confusing_precedence(tn->tn_op,
@@ -1464,8 +1464,8 @@ fold_constant_compare_zero(tnode_t *tn)
 	lint_assert(v->v_tspec == INT || (Tflag && v->v_tspec == BOOL));
 
 	lint_assert(has_operands(tn));
-	bool l = constant_is_nonzero(tn->tn_left);
-	bool r = is_binary(tn) && constant_is_nonzero(tn->tn_right);
+	bool l = constant_is_nonzero(tn->u.ops.left);
+	bool r = is_binary(tn) && constant_is_nonzero(tn->u.ops.right);
 
 	switch (tn->tn_op) {
 	case NOT:
@@ -1541,11 +1541,12 @@ fold_constant_floating(tnode_t *tn)
 
 	lint_assert(is_floating(t));
 	lint_assert(has_operands(tn));
-	lint_assert(t == tn->tn_left->tn_type->t_tspec);
-	lint_assert(!is_binary(tn) || t == tn->tn_right->tn_type->t_tspec);
+	lint_assert(t == tn->u.ops.left->tn_type->t_tspec);
+	lint_assert(!is_binary(tn) || t == tn->u.ops.right->tn_type->t_tspec);
 
-	long double lv = tn->tn_left->tn_val.u.floating;
-	long double rv = is_binary(tn) ? tn->tn_right->tn_val.u.floating : 0.0;
+	long double lv = tn->u.ops.left->u.value.u.floating;
+	long double rv = is_binary(tn) ? tn->u.ops.right->u.value.u.floating
+	    : 0.0;
 
 	switch (tn->tn_op) {
 	case UPLUS:
@@ -1619,23 +1620,23 @@ use(const tnode_t *tn)
 		return;
 	switch (tn->tn_op) {
 	case NAME:
-		mark_as_used(tn->tn_sym, false /* XXX */, false /* XXX */);
+		mark_as_used(tn->u.sym, false /* XXX */, false /* XXX */);
 		break;
 	case CON:
 	case STRING:
 		break;
 	case CALL:
 	case ICALL:;
-		const function_call *call = tn->tn_call;
+		const function_call *call = tn->u.call;
 		if (call->args != NULL)
 			for (size_t i = 0, n = call->args_len; i < n; i++)
 				use(call->args[i]);
 		break;
 	default:
 		lint_assert(has_operands(tn));
-		use(tn->tn_left);
+		use(tn->u.ops.left);
 		if (is_binary(tn))
-			use(tn->tn_right);
+			use(tn->u.ops.right);
 	}
 }
 
@@ -1669,16 +1670,16 @@ build_binary(tnode_t *ln, op_t op, bool 
 		rn = promote(op, false, rn);
 
 	if (mp->m_warn_if_left_unsigned_in_c90 &&
-	    ln->tn_op == CON && ln->tn_val.v_unsigned_since_c90) {
+	    ln->tn_op == CON && ln->u.value.v_unsigned_since_c90) {
 		/* C90 treats constant as unsigned, op '%s' */
 		warning(218, op_name(op));
-		ln->tn_val.v_unsigned_since_c90 = false;
+		ln->u.value.v_unsigned_since_c90 = false;
 	}
 	if (mp->m_warn_if_right_unsigned_in_c90 &&
-	    rn->tn_op == CON && rn->tn_val.v_unsigned_since_c90) {
+	    rn->tn_op == CON && rn->u.value.v_unsigned_since_c90) {
 		/* C90 treats constant as unsigned, op '%s' */
 		warning(218, op_name(op));
-		rn->tn_val.v_unsigned_since_c90 = false;
+		rn->u.value.v_unsigned_since_c90 = false;
 	}
 
 	if (mp->m_balance_operands || (!allow_c90 && (op == SHL || op == SHR)))
@@ -1778,10 +1779,10 @@ build_binary(tnode_t *ln, op_t op, bool 
 				ntn = fold_constant_integer(ntn);
 		} else if (op == QUEST) {
 			lint_assert(has_operands(rn));
-			use(ln->tn_val.u.integer != 0
-			    ? rn->tn_right : rn->tn_left);
-			ntn = ln->tn_val.u.integer != 0
-			    ? rn->tn_left : rn->tn_right;
+			use(ln->u.value.u.integer != 0
+			    ? rn->u.ops.right : rn->u.ops.left);
+			ntn = ln->u.value.u.integer != 0
+			    ? rn->u.ops.left : rn->u.ops.right;
 		}
 	}
 
@@ -2018,7 +2019,7 @@ const tnode_t *
 before_conversion(const tnode_t *tn)
 {
 	while (tn->tn_op == CVT && !tn->tn_cast)
-		tn = tn->tn_left;
+		tn = tn->u.ops.left;
 	return tn;
 }
 
@@ -2078,7 +2079,7 @@ typeok_incdec(op_t op, const tnode_t *tn
 	/* operand has scalar type (checked in typeok) */
 	if (!tn->tn_lvalue) {
 		if (tn->tn_op == CVT && tn->tn_cast &&
-		    tn->tn_left->tn_op == LOAD)
+		    tn->u.ops.left->tn_op == LOAD)
 			/* a cast does not yield an lvalue */
 			error(163);
 		/* %soperand of '%s' must be lvalue */
@@ -2098,7 +2099,7 @@ typeok_address(op_t op, const tnode_t *t
 		/* ok, a warning comes later (in build_address()) */
 	} else if (!tn->tn_lvalue) {
 		if (tn->tn_op == CVT && tn->tn_cast &&
-		    tn->tn_left->tn_op == LOAD)
+		    tn->u.ops.left->tn_op == LOAD)
 			/* a cast does not yield an lvalue */
 			error(163);
 		/* %soperand of '%s' must be lvalue */
@@ -2115,9 +2116,9 @@ typeok_address(op_t op, const tnode_t *t
 		error(111, op_name(op));
 		return false;
 	}
-	if (tn->tn_op == NAME && tn->tn_sym->s_register) {
+	if (tn->tn_op == NAME && tn->u.sym->s_register) {
 		/* cannot take address of register '%s' */
-		error(113, tn->tn_sym->s_name);
+		error(113, tn->u.sym->s_name);
 		return false;
 	}
 	return true;
@@ -2207,13 +2208,13 @@ typeok_shr(op_t op,
 		if (ln->tn_op != CON)
 			/* bitwise '%s' on signed value possibly nonportable */
 			warning(117, op_name(op));
-		else if (ln->tn_val.u.integer < 0)
+		else if (ln->u.value.u.integer < 0)
 			/* bitwise '%s' on signed value nonportable */
 			warning(120, op_name(op));
 	} else if (allow_trad && allow_c90 &&
 	    !is_uinteger(olt) && is_uinteger(ort)) {
 		/* The left operand would become unsigned in traditional C. */
-		if (hflag && (ln->tn_op != CON || ln->tn_val.u.integer < 0)) {
+		if (hflag && (ln->tn_op != CON || ln->u.value.u.integer < 0)) {
 			/* semantics of '%s' change in C90; use ... */
 			warning(118, op_name(op));
 		}
@@ -2224,7 +2225,7 @@ typeok_shr(op_t op,
 		 * In traditional C, the left operand would be extended
 		 * (possibly sign-extended) and then shifted.
 		 */
-		if (hflag && (ln->tn_op != CON || ln->tn_val.u.integer < 0)) {
+		if (hflag && (ln->tn_op != CON || ln->u.value.u.integer < 0)) {
 			/* semantics of '%s' change in C90; use ... */
 			warning(118, op_name(op));
 		}
@@ -2258,15 +2259,15 @@ typeok_shift(const type_t *ltp, tspec_t 
 	if (rn->tn_op != CON)
 		return;
 
-	if (!is_uinteger(rt) && rn->tn_val.u.integer < 0)
+	if (!is_uinteger(rt) && rn->u.value.u.integer < 0)
 		/* negative shift */
 		warning(121);
-	else if ((uint64_t)rn->tn_val.u.integer == size_in_bits(lt))
+	else if ((uint64_t)rn->u.value.u.integer == size_in_bits(lt))
 		/* shift amount %u equals bit-size of '%s' */
-		warning(267, (unsigned)rn->tn_val.u.integer, type_name(ltp));
-	else if ((uint64_t)rn->tn_val.u.integer > size_in_bits(lt)) {
+		warning(267, (unsigned)rn->u.value.u.integer, type_name(ltp));
+	else if ((uint64_t)rn->u.value.u.integer > size_in_bits(lt)) {
 		/* shift amount %llu is greater than bit-size %llu of '%s' */
-		warning(122, (unsigned long long)rn->tn_val.u.integer,
+		warning(122, (unsigned long long)rn->u.value.u.integer,
 		    (unsigned long long)size_in_bits(lt),
 		    tspec_name(lt));
 	}
@@ -2477,7 +2478,7 @@ typeok_assign(op_t op, const tnode_t *ln
 
 	if (!ln->tn_lvalue) {
 		if (ln->tn_op == CVT && ln->tn_cast &&
-		    ln->tn_left->tn_op == LOAD)
+		    ln->u.ops.left->tn_op == LOAD)
 			/* a cast does not yield an lvalue */
 			error(163);
 		/* %soperand of '%s' must be lvalue */
@@ -2566,9 +2567,9 @@ is_direct_function_call(const tnode_t *t
 {
 
 	if (tn->tn_op == CALL
-	    && tn->tn_call->func->tn_op == ADDR
-	    && tn->tn_call->func->tn_left->tn_op == NAME) {
-		*out_name = tn->tn_call->func->tn_left->tn_sym->s_name;
+	    && tn->u.call->func->tn_op == ADDR
+	    && tn->u.call->func->u.ops.left->tn_op == NAME) {
+		*out_name = tn->u.call->func->u.ops.left->u.sym->s_name;
 		return true;
 	}
 	return false;
@@ -2600,8 +2601,8 @@ is_const_char_pointer(const tnode_t *tn)
 	 * const' here.
 	 */
 	if (tn->tn_op == CVT &&
-	    tn->tn_left->tn_op == ADDR &&
-	    tn->tn_left->tn_left->tn_op == STRING)
+	    tn->u.ops.left->tn_op == ADDR &&
+	    tn->u.ops.left->u.ops.left->tn_op == STRING)
 		return true;
 
 	const type_t *tp = before_conversion(tn)->tn_type;
@@ -2613,9 +2614,9 @@ is_const_char_pointer(const tnode_t *tn)
 static bool
 is_first_arg_const_char_pointer(const tnode_t *tn)
 {
-	return tn->tn_call->args != NULL
-	    && tn->tn_call->args_len >= 1
-	    && is_const_char_pointer(tn->tn_call->args[0]);
+	return tn->u.call->args != NULL
+	    && tn->u.call->args_len >= 1
+	    && is_const_char_pointer(tn->u.call->args[0]);
 }
 
 static bool
@@ -2628,9 +2629,9 @@ is_const_pointer(const tnode_t *tn)
 static bool
 is_second_arg_const_pointer(const tnode_t *tn)
 {
-	return tn->tn_call->args_len >= 2
-	    && tn->tn_call->args != NULL
-	    && is_const_pointer(tn->tn_call->args[1]);
+	return tn->u.call->args_len >= 2
+	    && tn->u.call->args != NULL
+	    && is_const_pointer(tn->u.call->args[1]);
 }
 
 static void
@@ -2828,19 +2829,19 @@ has_side_effect(const tnode_t *tn) /* NO
 		return true;
 
 	if (op == CVT && tn->tn_type->t_tspec == VOID)
-		return has_side_effect(tn->tn_left);
+		return has_side_effect(tn->u.ops.left);
 
-	/* XXX: Why not has_side_effect(tn->tn_left) as well? */
+	/* XXX: Why not has_side_effect(tn->u.ops.left) as well? */
 	if (op == LOGAND || op == LOGOR)
-		return has_side_effect(tn->tn_right);
+		return has_side_effect(tn->u.ops.right);
 
-	/* XXX: Why not has_side_effect(tn->tn_left) as well? */
+	/* XXX: Why not has_side_effect(tn->u.ops.left) as well? */
 	if (op == QUEST)
-		return has_side_effect(tn->tn_right);
+		return has_side_effect(tn->u.ops.right);
 
 	if (op == COLON || op == COMMA) {
-		return has_side_effect(tn->tn_left) ||
-		    has_side_effect(tn->tn_right);
+		return has_side_effect(tn->u.ops.left) ||
+		    has_side_effect(tn->u.ops.right);
 	}
 
 	return false;
@@ -2859,8 +2860,8 @@ is_local_symbol(const tnode_t *tn)
 {
 
 	return tn->tn_op == LOAD &&
-	    tn->tn_left->tn_op == NAME &&
-	    tn->tn_left->tn_sym->s_scl == AUTO;
+	    tn->u.ops.left->tn_op == NAME &&
+	    tn->u.ops.left->u.sym->s_scl == AUTO;
 }
 
 static bool
@@ -2869,7 +2870,7 @@ is_int_constant_zero(const tnode_t *tn)
 
 	return tn->tn_op == CON &&
 	    tn->tn_type->t_tspec == INT &&
-	    tn->tn_val.u.integer == 0;
+	    tn->u.value.u.integer == 0;
 }
 
 static void
@@ -2878,8 +2879,8 @@ check_null_effect(const tnode_t *tn)
 
 	if (hflag &&
 	    !has_side_effect(tn) &&
-	    !(is_void_cast(tn) && is_local_symbol(tn->tn_left)) &&
-	    !(is_void_cast(tn) && is_int_constant_zero(tn->tn_left))) {
+	    !(is_void_cast(tn) && is_local_symbol(tn->u.ops.left)) &&
+	    !(is_void_cast(tn) && is_int_constant_zero(tn->u.ops.left))) {
 		/* expression has null effect */
 		warning(129);
 	}
@@ -3046,7 +3047,7 @@ check_enum_int_mismatch(op_t op, int arg
 		 */
 		if (!rn->tn_type->t_is_enum && rn->tn_op == CON &&
 		    is_integer(rn->tn_type->t_tspec) &&
-		    rn->tn_val.u.integer == 0) {
+		    rn->u.value.u.integer == 0) {
 			return;
 		}
 		/* initialization of '%s' with '%s' */
@@ -3234,7 +3235,7 @@ should_warn_about_prototype_conversion(t
 	 */
 	if (ptn->tn_op == CON && is_integer(nt) &&
 	    signed_type(nt) == signed_type(ot) &&
-	    !msb(ptn->tn_val.u.integer, ot))
+	    !msb(ptn->u.value.u.integer, ot))
 		return false;
 
 	return true;
@@ -3571,13 +3572,13 @@ convert(op_t op, int arg, type_t *tp, tn
 	ntn->tn_type = tp;
 	ntn->tn_cast = op == CVT;
 	ntn->tn_sys |= tn->tn_sys;
-	ntn->tn_right = NULL;
+	ntn->u.ops.right = NULL;
 	if (tn->tn_op != CON || nt == VOID) {
-		ntn->tn_left = tn;
+		ntn->u.ops.left = tn;
 	} else {
 		ntn->tn_op = CON;
-		convert_constant(op, arg, ntn->tn_type, &ntn->tn_val,
-		    &tn->tn_val);
+		convert_constant(op, arg, ntn->tn_type, &ntn->u.value,
+		    &tn->u.value);
 	}
 
 	return ntn;
@@ -4217,7 +4218,7 @@ build_function_call(tnode_t *func, bool 
 	ntn->tn_op = fcop;
 	ntn->tn_type = func->tn_type->t_subt->t_subt;
 	ntn->tn_sys = sys;
-	ntn->tn_call = call;
+	ntn->u.call = call;
 	return ntn;
 }
 
@@ -4248,14 +4249,14 @@ integer_constant(tnode_t *tn, bool requi
 	v->v_tspec = tn->tn_type->t_tspec;
 
 	if (tn->tn_op == CON) {
-		lint_assert(tn->tn_type->t_tspec == tn->tn_val.v_tspec);
-		if (is_integer(tn->tn_val.v_tspec)) {
+		lint_assert(tn->tn_type->t_tspec == tn->u.value.v_tspec);
+		if (is_integer(tn->u.value.v_tspec)) {
 			v->v_unsigned_since_c90 =
-			    tn->tn_val.v_unsigned_since_c90;
-			v->u.integer = tn->tn_val.u.integer;
+			    tn->u.value.v_unsigned_since_c90;
+			v->u.integer = tn->u.value.u.integer;
 			return v;
 		}
-		v->u.integer = (int64_t)tn->tn_val.u.floating;
+		v->u.integer = (int64_t)tn->u.value.u.floating;
 	} else
 		v->u.integer = 1;
 
@@ -4276,7 +4277,7 @@ static bool
 is_constcond_false(const tnode_t *tn, tspec_t t)
 {
 	return (t == BOOL || t == INT) &&
-	    tn->tn_op == CON && tn->tn_val.u.integer == 0;
+	    tn->tn_op == CON && tn->u.value.u.integer == 0;
 }
 
 /*
@@ -4336,8 +4337,8 @@ static void
 check_array_index(tnode_t *tn, bool amper)
 {
 	lint_assert(has_operands(tn));
-	const tnode_t *ln = tn->tn_left;
-	const tnode_t *rn = tn->tn_right;
+	const tnode_t *ln = tn->u.ops.left;
+	const tnode_t *rn = tn->u.ops.right;
 
 	/* We can only check constant indices. */
 	if (rn->tn_op != CON)
@@ -4346,16 +4347,17 @@ check_array_index(tnode_t *tn, bool ampe
 	/* Return if the left node does not stem from an array. */
 	if (ln->tn_op != ADDR)
 		return;
-	if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME)
+	if (ln->u.ops.left->tn_op != STRING && ln->u.ops.left->tn_op != NAME)
 		return;
-	if (ln->tn_left->tn_type->t_tspec != ARRAY)
+	if (ln->u.ops.left->tn_type->t_tspec != ARRAY)
 		return;
 
 	/*
 	 * For incomplete array types, we can print a warning only if the index
 	 * is negative.
 	 */
-	if (is_incomplete(ln->tn_left->tn_type) && rn->tn_val.u.integer >= 0)
+	if (is_incomplete(ln->u.ops.left->tn_type)
+	    && rn->u.value.u.integer >= 0)
 		return;
 
 	int elsz = length_in_bits(ln->tn_type->t_subt, NULL);
@@ -4365,10 +4367,10 @@ check_array_index(tnode_t *tn, bool ampe
 
 	/* Change the unit of the index from bytes to element size. */
 	int64_t con = is_uinteger(rn->tn_type->t_tspec)
-	    ? (int64_t)((uint64_t)rn->tn_val.u.integer / elsz)
-	    : rn->tn_val.u.integer / elsz;
+	    ? (int64_t)((uint64_t)rn->u.value.u.integer / elsz)
+	    : rn->u.value.u.integer / elsz;
 
-	int dim = ln->tn_left->tn_type->u.dimension + (amper ? 1 : 0);
+	int dim = ln->u.ops.left->tn_type->u.dimension + (amper ? 1 : 0);
 
 	if (!is_uinteger(rn->tn_type->t_tspec) && con < 0)
 		/* array subscript cannot be negative: %ld */
@@ -4384,18 +4386,18 @@ check_expr_addr(const tnode_t *ln, bool 
 	/* XXX: Taking warn_about_unreachable into account here feels wrong. */
 	if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
 		if (!szof)
-			mark_as_set(ln->tn_sym);
-		mark_as_used(ln->tn_sym, fcall, szof);
+			mark_as_set(ln->u.sym);
+		mark_as_used(ln->u.sym, fcall, szof);
 	}
-	if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS)
-		check_array_index(ln->tn_left, true);
+	if (ln->tn_op == INDIR && ln->u.ops.left->tn_op == PLUS)
+		check_array_index(ln->u.ops.left, true);
 }
 
 static void
 check_expr_load(const tnode_t *ln)
 {
-	if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS)
-		check_array_index(ln->tn_left, false);
+	if (ln->tn_op == INDIR && ln->u.ops.left->tn_op == PLUS)
+		check_array_index(ln->u.ops.left, false);
 }
 
 /*
@@ -4417,14 +4419,14 @@ check_expr_side_effect(const tnode_t *ln
 
 	/* XXX: Taking warn_about_unreachable into account here feels wrong. */
 	if (ln->tn_op == NAME && (reached || !warn_about_unreachable)) {
-		scl_t sc = ln->tn_sym->s_scl;
+		scl_t sc = ln->u.sym->s_scl;
 		if (sc != EXTERN && sc != STATIC &&
-		    !ln->tn_sym->s_set && !szof && !is_asm_around()) {
+		    !ln->u.sym->s_set && !szof && !is_asm_around()) {
 			/* '%s' may be used before set */
-			warning(158, ln->tn_sym->s_name);
-			mark_as_set(ln->tn_sym);
+			warning(158, ln->u.sym->s_name);
+			mark_as_set(ln->u.sym);
 		}
-		mark_as_used(ln->tn_sym, false, false);
+		mark_as_used(ln->u.sym, false, false);
 	}
 }
 
@@ -4433,13 +4435,13 @@ check_expr_assign(const tnode_t *ln, boo
 {
 	/* XXX: Taking warn_about_unreachable into account here feels wrong. */
 	if (ln->tn_op == NAME && !szof && (reached || !warn_about_unreachable)) {
-		mark_as_set(ln->tn_sym);
-		if (ln->tn_sym->s_scl == EXTERN)
-			outusg(ln->tn_sym);
+		mark_as_set(ln->u.sym);
+		if (ln->u.sym->s_scl == EXTERN)
+			outusg(ln->u.sym);
 	}
-	if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS)
+	if (ln->tn_op == INDIR && ln->u.ops.left->tn_op == PLUS)
 		/* check the range of array indices */
-		check_array_index(ln->tn_left, false);
+		check_array_index(ln->u.ops.left, false);
 }
 
 static void
@@ -4447,8 +4449,8 @@ check_expr_call(const tnode_t *tn, const
 		bool szof, bool vctx, bool cond, bool retval_discarded)
 {
 	lint_assert(ln->tn_op == ADDR);
-	lint_assert(ln->tn_left->tn_op == NAME);
-	if (!szof && !is_compiler_builtin(ln->tn_left->tn_sym->s_name))
+	lint_assert(ln->u.ops.left->tn_op == NAME);
+	if (!szof && !is_compiler_builtin(ln->u.ops.left->u.sym->s_name))
 		outcall(tn, vctx || cond, retval_discarded);
 	check_snprintb(tn);
 }
@@ -4519,7 +4521,7 @@ check_expr_misc(const tnode_t *tn, bool 
 	if (op == NAME || op == CON || op == STRING)
 		return;
 	if (op == CALL || op == ICALL) {
-		const function_call *call = tn->tn_call;
+		const function_call *call = tn->u.call;
 		if (op == CALL)
 			check_expr_call(tn, call->func,
 			    szof, vctx, cond, retval_discarded);
@@ -4535,8 +4537,8 @@ check_expr_misc(const tnode_t *tn, bool 
 	}
 
 	lint_assert(has_operands(tn));
-	tnode_t *ln = tn->tn_left;
-	tnode_t *rn = tn->tn_right;
+	tnode_t *ln = tn->u.ops.left;
+	tnode_t *rn = tn->u.ops.right;
 	check_expr_op(op, ln, szof, fcall, eqwarn);
 
 	const mod_t *mp = &modtab[op];
@@ -4601,22 +4603,22 @@ constant_addr(const tnode_t *tn, const s
 
 	switch (tn->tn_op) {
 	case MINUS:
-		if (tn->tn_right->tn_op == CVT)
-			return constant_addr(tn->tn_right, symp, offsp);
-		else if (tn->tn_right->tn_op != CON)
+		if (tn->u.ops.right->tn_op == CVT)
+			return constant_addr(tn->u.ops.right, symp, offsp);
+		else if (tn->u.ops.right->tn_op != CON)
 			return false;
 		/* FALLTHROUGH */
 	case PLUS:
 		offs1 = offs2 = 0;
-		if (tn->tn_left->tn_op == CON) {
-			offs1 = (ptrdiff_t)tn->tn_left->tn_val.u.integer;
-			if (!constant_addr(tn->tn_right, &sym, &offs2))
+		if (tn->u.ops.left->tn_op == CON) {
+			offs1 = (ptrdiff_t)tn->u.ops.left->u.value.u.integer;
+			if (!constant_addr(tn->u.ops.right, &sym, &offs2))
 				return false;
-		} else if (tn->tn_right->tn_op == CON) {
-			offs2 = (ptrdiff_t)tn->tn_right->tn_val.u.integer;
+		} else if (tn->u.ops.right->tn_op == CON) {
+			offs2 = (ptrdiff_t)tn->u.ops.right->u.value.u.integer;
 			if (tn->tn_op == MINUS)
 				offs2 = -offs2;
-			if (!constant_addr(tn->tn_left, &sym, &offs1))
+			if (!constant_addr(tn->u.ops.left, &sym, &offs1))
 				return false;
 		} else {
 			return false;
@@ -4625,15 +4627,15 @@ constant_addr(const tnode_t *tn, const s
 		*offsp = offs1 + offs2;
 		return true;
 	case ADDR:
-		if (tn->tn_left->tn_op == NAME) {
-			*symp = tn->tn_left->tn_sym;
+		if (tn->u.ops.left->tn_op == NAME) {
+			*symp = tn->u.ops.left->u.sym;
 			*offsp = 0;
 			return true;
 		} else {
 			/*
 			 * If this were the front end of a compiler, we would
 			 * return a label instead of 0, at least if
-			 * 'tn->tn_left->tn_op == STRING'.
+			 * 'tn->u.ops.left->tn_op == STRING'.
 			 */
 			*symp = NULL;
 			*offsp = 0;
@@ -4641,7 +4643,7 @@ constant_addr(const tnode_t *tn, const s
 		}
 	case CVT:
 		t = tn->tn_type->t_tspec;
-		ot = tn->tn_left->tn_type->t_tspec;
+		ot = tn->u.ops.left->tn_type->t_tspec;
 		if ((!is_integer(t) && t != PTR) ||
 		    (!is_integer(ot) && ot != PTR)) {
 			return false;
@@ -4661,7 +4663,7 @@ constant_addr(const tnode_t *tn, const s
 		else if (psize(t) != psize(ot))
 			return -1;
 #endif
-		return constant_addr(tn->tn_left, symp, offsp);
+		return constant_addr(tn->u.ops.left, symp, offsp);
 	default:
 		return false;
 	}

Reply via email to