Author: Petr Machata <pmachata@apm-mustang-ev2-02.ml3.eng.bos.redhat.com>
Description: Move get_hfa_type from IA64 backend to type.c, name it type_get_hfa_type
Applied-Upstream: http://anonscm.debian.org/gitweb/?p=collab-maint/ltrace.git;a=commit;h=982cbca34b2b49a158086ff5f43eb9bba89edead
Last-Update: 2014-03-13

Index: ltrace/sysdeps/linux-gnu/ia64/fetch.c
===================================================================
--- ltrace.orig/sysdeps/linux-gnu/ia64/fetch.c	2014-03-12 16:13:44.075726000 -0600
+++ ltrace/sysdeps/linux-gnu/ia64/fetch.c	2014-03-13 09:32:30.504762084 -0600
@@ -1,6 +1,6 @@
 /*
  * This file is part of ltrace.
- * Copyright (C) 2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc.
  * Copyright (C) 2008,2009 Juan Cespedes
  * Copyright (C) 2006 Steve Fink
  * Copyright (C) 2006 Ian Wienand
@@ -249,37 +249,6 @@
 	return 0;
 }
 
-static enum arg_type
-get_hfa_type(struct arg_type_info *info, size_t *countp)
-{
-	size_t n = type_aggregate_size(info);
-	if (n == (size_t)-1)
-		return ARGTYPE_VOID;
-
-	enum arg_type type = ARGTYPE_VOID;
-	*countp = 0;
-
-	while (n-- > 0) {
-		struct arg_type_info *emt = type_element(info, n);
-
-		enum arg_type emt_type = emt->type;
-		size_t emt_count = 1;
-		if (emt_type == ARGTYPE_STRUCT || emt_type == ARGTYPE_ARRAY)
-			emt_type = get_hfa_type(emt, &emt_count);
-
-		if (type == ARGTYPE_VOID) {
-			if (emt_type != ARGTYPE_FLOAT
-			    && emt_type != ARGTYPE_DOUBLE)
-				return ARGTYPE_VOID;
-			type = emt_type;
-		}
-		if (emt_type != type)
-			return ARGTYPE_VOID;
-		*countp += emt_count;
-	}
-	return type;
-}
-
 static int
 allocate_hfa(struct fetch_context *ctx, struct Process *proc,
 	     struct arg_type_info *info, struct value *valuep,
@@ -380,10 +349,11 @@
 	 * floating-point registers, beginning with f8.  */
 	if (info->type == ARGTYPE_STRUCT || info->type == ARGTYPE_ARRAY) {
 		size_t hfa_size;
-		enum arg_type hfa_type = get_hfa_type(info, &hfa_size);
-		if (hfa_type != ARGTYPE_VOID && hfa_size <= 8)
+		struct arg_type_info *hfa_info
+			= type_get_hfa_type(info, &hfa_size);
+		if (hfa_info != NULL && hfa_size <= 8)
 			return allocate_hfa(ctx, proc, info, valuep,
-					    hfa_type, hfa_size);
+					    hfa_info->type, hfa_size);
 	}
 
 	/* Integers and pointers are passed in r8.  128-bit integers
@@ -409,7 +379,7 @@
 		    struct arg_type_info *info, struct value *valuep)
 {
 	switch (info->type) {
-		enum arg_type hfa_type;
+		struct arg_type_info *hfa_info;
 		size_t hfa_size;
 
 	case ARGTYPE_VOID:
@@ -421,10 +391,10 @@
 		return allocate_float(ctx, proc, info, valuep, 1);
 
 	case ARGTYPE_STRUCT:
-		hfa_type = get_hfa_type(info, &hfa_size);
-		if (hfa_type != ARGTYPE_VOID)
+		hfa_info = type_get_hfa_type(info, &hfa_size);
+		if (hfa_info != NULL)
 			return allocate_hfa(ctx, proc, info, valuep,
-					    hfa_type, hfa_size);
+					    hfa_info->type, hfa_size);
 		/* Fall through.  */
 	case ARGTYPE_CHAR:
 	case ARGTYPE_SHORT:
Index: ltrace/type.c
===================================================================
--- ltrace.orig/type.c	2014-03-12 16:13:44.075726000 -0600
+++ ltrace/type.c	2014-03-13 09:32:30.504762084 -0600
@@ -568,3 +568,39 @@
 	}
 	abort();
 }
+
+struct arg_type_info *
+type_get_hfa_type(struct arg_type_info *info, size_t *countp)
+{
+	assert(info != NULL);
+	if (info->type != ARGTYPE_STRUCT
+	    && info->type != ARGTYPE_ARRAY)
+		return NULL;
+
+	size_t n = type_aggregate_size(info);
+	if (n == (size_t)-1)
+		return NULL;
+
+	struct arg_type_info *ret = NULL;
+	*countp = 0;
+
+	while (n-- > 0) {
+		struct arg_type_info *emt = type_element(info, n);
+
+		size_t emt_count = 1;
+		if (emt->type == ARGTYPE_STRUCT || emt->type == ARGTYPE_ARRAY)
+			emt = type_get_hfa_type(emt, &emt_count);
+		if (emt == NULL)
+			return NULL;
+		if (ret == NULL) {
+			if (emt->type != ARGTYPE_FLOAT
+			    && emt->type != ARGTYPE_DOUBLE)
+				return NULL;
+			ret = emt;
+		}
+		if (emt->type != ret->type)
+			return NULL;
+		*countp += emt_count;
+	}
+	return ret;
+}
Index: ltrace/type.h
===================================================================
--- ltrace.orig/type.h	2014-03-12 16:13:44.075726000 -0600
+++ ltrace/type.h	2014-03-13 09:32:30.504762084 -0600
@@ -1,6 +1,6 @@
 /*
  * This file is part of ltrace.
- * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
  * Copyright (C) 1997-2009 Juan Cespedes
  *
  * This program is free software; you can redistribute it and/or
@@ -142,4 +142,13 @@
  * type.  */
 struct arg_type_info *type_get_fp_equivalent(struct arg_type_info *info);
 
+/* If INFO is homogeneous floating-point aggregate, return the
+ * corresponding floating point type, and set *COUNTP to number of
+ * fields of the structure.  Otherwise return NULL.  INFO is a HFA if
+ * it's an aggregate whose each field is either a HFA, or a
+ * floating-point type.  */
+struct arg_type_info *type_get_hfa_type(struct arg_type_info *info,
+					size_t *countp);
+
+
 #endif /* TYPE_H */