[llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c

Chris Lattner lattner at cs.uiuc.edu
Fri Feb 11 11:26:58 PST 2005



Changes in directory llvm-gcc/gcc:

llvm-expand.c updated: 1.77 -> 1.78
---
Log message:

Implement support for anonymous automatic unions, fixing PR501: http://llvm.cs.uiuc.edu/PR501  and
test/Regression/C++Frontend/2005-02-11-AnonymousUnion.cpp


---
Diffs of the changes:  (+50 -4)

 llvm-expand.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 50 insertions(+), 4 deletions(-)


Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.77 llvm-gcc/gcc/llvm-expand.c:1.78
--- llvm-gcc/gcc/llvm-expand.c:1.77	Thu Jan 13 11:16:36 2005
+++ llvm-gcc/gcc/llvm-expand.c	Fri Feb 11 13:26:43 2005
@@ -2616,6 +2616,52 @@
     }
 }
 
+/* llvm_expand_anon_union_decl - This function, which corresponds to
+ * expand_anon_union_decl, expands an anonymous union.  An anonymous union is
+ * where the user can refer to the elements as if they were defined in the same
+ * scope as the union itself.  These appear to always be automatic variables.
+ */
+static void llvm_expand_anon_union_decl(llvm_function *Fn, tree decl,
+                                        tree decl_elts) {
+  llvm_nesting *InnermostCleanupScope = Fn->ExpandInfo->InnermostBlockScope;
+  llvm_value *x;
+  tree t;
+
+  /* If any of the elements are addressable, so is the entire union.  */
+  for (t = decl_elts; t; t = TREE_CHAIN (t))
+    if (TREE_ADDRESSABLE (TREE_VALUE (t)))
+      {
+	TREE_ADDRESSABLE (decl) = 1;
+	break;
+      }
+
+  llvm_expand_decl(Fn, decl);
+  x = DECL_LLVM(decl);
+
+  /* Go through the elements, assigning the LLVM location to each.  */
+  for (t = decl_elts; t; t = TREE_CHAIN (t))
+    {
+      tree decl_elt = TREE_VALUE (t);
+      enum machine_mode mode = TYPE_MODE (TREE_TYPE (decl_elt));
+
+      /* If any of the elements are used, so is the entire union.  */
+      if (TREE_USED (decl_elt))
+	TREE_USED (decl) = 1;
+
+      /* Propagate the union's alignment to the elements.  */
+      DECL_ALIGN (decl_elt) = DECL_ALIGN (decl);
+      DECL_USER_ALIGN (decl_elt) = DECL_USER_ALIGN (decl);
+
+      /* If the element has BLKmode and the union doesn't, the union is
+         aligned such that the element doesn't need to have BLKmode, so
+         change the element's mode to the appropriate one for its size.  */
+      if (mode == BLKmode && DECL_MODE (decl) != BLKmode)
+	DECL_MODE (decl_elt) = mode
+	  = mode_for_size_tree (DECL_SIZE (decl_elt), MODE_INT, 1);
+      SET_DECL_LLVM(decl_elt, x);
+    }
+}
+
 
 /* Generate LLVM code for T, which is a DECL_STMT.  */
 static void genllvm_decl_stmt(llvm_function *F, tree t) {
@@ -2633,10 +2679,10 @@
       if (!anon_aggr_type_p (TREE_TYPE (decl))) {
         llvm_emit_local_var (F, decl);
       } else {
-        /* LLVM: See info about lhd_tree_inlining_anon_aggr_type_p */
-        LLVM_TODO_TREE(t);
-        expand_anon_union_decl (decl, NULL_TREE, 
-                                DECL_ANON_UNION_ELEMS (decl));
+        /* This is an anonymous aggregate object on the stack: the elements of
+         * this declaration are actually automatic objects themselves.
+         */
+        llvm_expand_anon_union_decl(F, decl, DECL_ANON_UNION_ELEMS(decl));
       }
     } else if (TREE_STATIC (decl)) {
       make_llvm_for_local_static(decl);






More information about the llvm-commits mailing list