[llvm-commits] [llvm-gcc-4.2] r44214 - in /llvm-gcc-4.2/trunk/gcc: llvm-abi.h llvm-convert.cpp llvm-debug.cpp llvm-types.cpp

Duncan Sands baldrick at free.fr
Sun Nov 18 05:15:23 PST 2007


Author: baldrick
Date: Sun Nov 18 07:15:23 2007
New Revision: 44214

URL: http://llvm.org/viewvc/llvm-project?rev=44214&view=rev
Log:
Basic support for qualified unions (QUAL_UNION_TYPE).
This doesn't handle all cases, but it does handle most
cases.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-abi.h
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=44214&r1=44213&r2=44214&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Sun Nov 18 07:15:23 2007
@@ -80,7 +80,8 @@
 /// that cannot live in an LLVM register.
 static bool isAggregateTreeType(tree type) {
   return TREE_CODE(type) == RECORD_TYPE || TREE_CODE(type) == ARRAY_TYPE ||
-         TREE_CODE(type) == UNION_TYPE  || TREE_CODE(type) == COMPLEX_TYPE;
+         TREE_CODE(type) == UNION_TYPE  || TREE_CODE(type) == QUAL_UNION_TYPE ||
+         TREE_CODE(type) == COMPLEX_TYPE;
 }
 
 /// isSingleElementStructOrArray - If this is (recursively) a structure with one
@@ -92,6 +93,7 @@
   
   tree FoundField = 0;
   switch (TREE_CODE(type)) {
+  case QUAL_UNION_TYPE:
   case UNION_TYPE:     // Single element unions don't count.
   case COMPLEX_TYPE:   // Complex values are like 2-element records.
   default:
@@ -216,7 +218,8 @@
       C.EnterField(1, Ty);
       HandleArgument(TREE_TYPE(type));
       C.ExitField();
-    } else if (TREE_CODE(type) == UNION_TYPE) {
+    } else if ((TREE_CODE(type) == UNION_TYPE) ||
+               (TREE_CODE(type) == QUAL_UNION_TYPE)) {
       HandleUnion(type);
     } else if (TREE_CODE(type) == ARRAY_TYPE) {
       const ArrayType *ATy = cast<ArrayType>(Ty);
@@ -231,7 +234,7 @@
     }
   }
 
-  /// HandleUnion - Handle a UNION_TYPE tree.
+  /// HandleUnion - Handle a UNION_TYPE or QUAL_UNION_TYPE tree.
   ///
   void HandleUnion(tree type) {
     if (TYPE_TRANSPARENT_UNION(type)) {
@@ -249,12 +252,22 @@
       tree MaxElt = 0;
       for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
         if (TREE_CODE(Field) == FIELD_DECL) {
+          // Skip fields that are known not to be present.
+          if (TREE_CODE(type) == QUAL_UNION_TYPE &&
+              integer_zerop(DECL_QUALIFIER(Field)))
+              continue;
+
           tree SizeTree = TYPE_SIZE(TREE_TYPE(Field));
           unsigned Size = ((unsigned)TREE_INT_CST_LOW(SizeTree)+7)/8;
           if (Size > MaxSize) {
             MaxSize = Size;
             MaxElt = Field;
           }
+
+          // Skip remaining fields if this one is known to be present.
+          if (TREE_CODE(type) == QUAL_UNION_TYPE &&
+              integer_onep(DECL_QUALIFIER(Field)))
+              break;
         }
       }
       

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=44214&r1=44213&r2=44214&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sun Nov 18 07:15:23 2007
@@ -4931,7 +4931,8 @@
   tree FieldDecl = TREE_OPERAND(exp, 1);
 
   assert((TREE_CODE(DECL_CONTEXT(FieldDecl)) == RECORD_TYPE ||
-          TREE_CODE(DECL_CONTEXT(FieldDecl)) == UNION_TYPE));
+          TREE_CODE(DECL_CONTEXT(FieldDecl)) == UNION_TYPE  ||
+          TREE_CODE(DECL_CONTEXT(FieldDecl)) == QUAL_UNION_TYPE));
    
   // Ensure that the struct type has been converted, so that the fielddecls
   // are laid out.  Note that we convert to the context of the Field, not to the
@@ -5192,6 +5193,7 @@
       TODO(exp);
     }
     return 0;
+  case QUAL_UNION_TYPE:
   case UNION_TYPE:
     // Store each element of the constructor into the corresponding field of
     // DEST.
@@ -5457,6 +5459,7 @@
   case VECTOR_TYPE:
   case ARRAY_TYPE:  return ConvertArrayCONSTRUCTOR(exp);
   case RECORD_TYPE: return ConvertRecordCONSTRUCTOR(exp);
+  case QUAL_UNION_TYPE:
   case UNION_TYPE:  return ConvertUnionCONSTRUCTOR(exp);
   }
 }

Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=44214&r1=44213&r2=44214&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Sun Nov 18 07:15:23 2007
@@ -628,8 +628,8 @@
     }
     
     case RECORD_TYPE:
-    case UNION_TYPE:
-    case QUAL_UNION_TYPE: {
+    case QUAL_UNION_TYPE:
+    case UNION_TYPE: {
       // struct { a; b; ... z; }; | union { a; b; ... z; };
       unsigned Tag = TREE_CODE(type) == RECORD_TYPE ? DW_TAG_structure_type :
                                                       DW_TAG_union_type;

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=44214&r1=44213&r2=44214&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Sun Nov 18 07:15:23 2007
@@ -573,6 +573,7 @@
         return true;
     return false;
   }
+  case QUAL_UNION_TYPE:
   case UNION_TYPE: {
     // If this is a union with the transparent_union attribute set, it is
     // treated as if it were just the same as its first type.
@@ -591,10 +592,19 @@
     for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
       if (TREE_CODE(Field) != FIELD_DECL) continue;
       assert(getFieldOffsetInBits(Field) == 0 && "Union with non-zero offset?");
+      // Skip fields that are known not to be present.
+      if (TREE_CODE(type) == QUAL_UNION_TYPE &&
+          integer_zerop(DECL_QUALIFIER(Field)))
+        continue;
 
       if (GCCTypeOverlapsWithPadding(TREE_TYPE(Field),
                                      PadStartBits, PadSizeBits))
         return true;
+
+      // Skip remaining fields if this one is known to be present.
+      if (TREE_CODE(type) == QUAL_UNION_TYPE &&
+          integer_onep(DECL_QUALIFIER(Field)))
+        break;
     }
 
     return false;
@@ -669,6 +679,7 @@
     abort();
   case VOID_TYPE:   return SET_TYPE_LLVM(type, Type::VoidTy);
   case RECORD_TYPE: return ConvertRECORD(type, orig_type);
+  case QUAL_UNION_TYPE:
   case UNION_TYPE:  return ConvertUNION(type, orig_type);
   case BOOLEAN_TYPE: {
     if (const Type *Ty = GET_TYPE_LLVM(type))
@@ -1834,8 +1845,8 @@
 }
 
 
-/// ConvertUNION - We know that 'type' is a UNION_TYPE: convert it to an LLVM
-/// type.
+/// ConvertUNION - We know that 'type' is a UNION_TYPE or a QUAL_UNION_TYPE:
+/// convert it to an LLVM type.
 const Type *TypeConverter::ConvertUNION(tree type, tree orig_type) {
   if (const Type *Ty = GET_TYPE_LLVM(type)) {
     // If we already compiled this type, and if it was not a forward
@@ -1853,7 +1864,7 @@
   // Note that we are compiling a struct now.
   bool OldConvertingStruct = ConvertingStruct;
   ConvertingStruct = true;
-  
+
   // Find the type with the largest aligment, and if we have multiple types with
   // the same alignment, select one with largest size. If type with max. align
   // is smaller then other types then we will add padding later on anyway to 
@@ -1868,6 +1879,11 @@
     // Set the field idx to zero for all fields.
     SetFieldIndex(Field, 0);
 
+    // Skip fields that are known not to be present.
+    if (TREE_CODE(type) == QUAL_UNION_TYPE &&
+        integer_zerop(DECL_QUALIFIER(Field)))
+      continue;
+
     const Type *TheTy = ConvertType(TREE_TYPE(Field));
     bool isPacked = false;
     unsigned Size  = TD.getABITypeSize(TheTy);
@@ -1898,6 +1914,11 @@
       MaxSize = MAX(MaxSize, Size);
       MaxAlign = Align;
     }
+
+    // Skip remaining fields if this one is known to be present.
+    if (TREE_CODE(type) == QUAL_UNION_TYPE &&
+        integer_onep(DECL_QUALIFIER(Field)))
+      break;
   }
 
   std::vector<const Type*> UnionElts;





More information about the llvm-commits mailing list