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; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits