[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