/* Encoding of types for Objective C.
- Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004
+ Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2009
Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
Bitfield support by Ovidiu Predescu
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
-/* As a special exception, if you link this library with files
- compiled with GCC to produce an executable, this does not cause
- the resulting executable to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License. */
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
/* FIXME: This file has no business including tm.h. */
+/* FIXME: This file contains functions that will abort the entire
+ program if they fail. Is that really needed ?
+*/
+
+#include "objc-private/common.h"
+#include "objc-private/error.h"
#include "tconfig.h"
#include "coretypes.h"
#include "tm.h"
#define VECTOR_TYPE _C_VECTOR
-#define TYPE_FIELDS(TYPE) objc_skip_typespec (TYPE)
+#define TYPE_FIELDS(TYPE) ({const char *_field = (TYPE)+1; \
+ while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \
+ && *_field != _C_UNION_B && *_field++ != '=') \
+ /* do nothing */; \
+ _field;})
#define DECL_MODE(TYPE) *(TYPE)
#define TYPE_MODE(TYPE) *(TYPE)
#define DFmode _C_DBL
-#define get_inner_array_type(TYPE) ((TYPE) + 1)
+#define strip_array_types(TYPE) ({const char *_field = (TYPE); \
+ while (*_field == _C_ARY_B)\
+ {\
+ while (isdigit ((unsigned char)*++_field))\
+ ;\
+ }\
+ _field;})
/* Some ports (eg ARM) allow the structure size boundary to be
selected at compile-time. We override the normal definition with
#undef ALTIVEC_VECTOR_MODE
#define ALTIVEC_VECTOR_MODE(MODE) (0)
+/* Furthermore, some (powerpc) targets also use TARGET_ALIGN_NATURAL
+ in their alignment macros. Currently[4.5/6], rs6000.h points this
+ to a static variable, initialized by target overrides. This is reset
+ in linux64.h but not in darwin64.h. The macro is not used by *86*. */
+
+#if __MACH__ && __LP64__
+# undef TARGET_ALIGN_NATURAL
+# define TARGET_ALIGN_NATURAL 1
+#endif
/* FIXME: while this file has no business including tm.h, this
definitely has no business defining this macro but it
is only way around without really rewritting this file,
- should look after the branch of 3.4 to fix this. */
+ should look after the branch of 3.4 to fix this.
+ FIXME1: It's also out of date, darwin no longer has the same alignment
+ 'special' as aix - this is probably the origin of the m32 breakage. */
#define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED) \
- ((TYPE_FIELDS (STRUCT) != 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode) \
+ ({ const char *_fields = TYPE_FIELDS (STRUCT); \
+ ((_fields != 0 \
+ && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode) \
? MAX (MAX (COMPUTED, SPECIFIED), 64) \
- : MAX (COMPUTED, SPECIFIED))
+ : MAX (COMPUTED, SPECIFIED));})
+/* FIXME: The word 'fixme' is insufficient to explain the wrong-ness
+ of this next macro definition. */
+#define darwin_rs6000_special_round_type_align(S,C,S2) \
+ rs6000_special_round_type_align(S,C,S2)
/*
return the size of an object specified by type
return size;
}
+
+ case _C_COMPLEX:
+ {
+ type++; /* Skip after the 'j'. */
+ switch (*type)
+ {
+ case _C_CHR:
+ return sizeof (_Complex char);
+ break;
+
+ case _C_UCHR:
+ return sizeof (_Complex unsigned char);
+ break;
+
+ case _C_SHT:
+ return sizeof (_Complex short);
+ break;
+
+ case _C_USHT:
+ return sizeof (_Complex unsigned short);
+ break;
+
+ case _C_INT:
+ return sizeof (_Complex int);
+ break;
+
+ case _C_UINT:
+ return sizeof (_Complex unsigned int);
+ break;
+
+ case _C_LNG:
+ return sizeof (_Complex long);
+ break;
+
+ case _C_ULNG:
+ return sizeof (_Complex unsigned long);
+ break;
+
+ case _C_LNG_LNG:
+ return sizeof (_Complex long long);
+ break;
+
+ case _C_ULNG_LNG:
+ return sizeof (_Complex unsigned long long);
+ break;
+
+ case _C_FLT:
+ return sizeof (_Complex float);
+ break;
+
+ case _C_DBL:
+ return sizeof (_Complex double);
+ break;
+
+ default:
+ {
+ /* FIXME: Is this so bad that we have to abort the
+ entire program ? (it applies to all the other
+ _objc_abort calls in this file).
+ */
+ _objc_abort ("unknown complex type %s\n", type);
+ return 0;
+ }
+ }
+ }
default:
{
- objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
+ _objc_abort ("unknown type %s\n", type);
return 0;
}
}
return align;
}
+
+
+ case _C_COMPLEX:
+ {
+ type++; /* Skip after the 'j'. */
+ switch (*type)
+ {
+ case _C_CHR:
+ return __alignof__ (_Complex char);
+ break;
+
+ case _C_UCHR:
+ return __alignof__ (_Complex unsigned char);
+ break;
+
+ case _C_SHT:
+ return __alignof__ (_Complex short);
+ break;
+
+ case _C_USHT:
+ return __alignof__ (_Complex unsigned short);
+ break;
+
+ case _C_INT:
+ return __alignof__ (_Complex int);
+ break;
+
+ case _C_UINT:
+ return __alignof__ (_Complex unsigned int);
+ break;
+
+ case _C_LNG:
+ return __alignof__ (_Complex long);
+ break;
+
+ case _C_ULNG:
+ return __alignof__ (_Complex unsigned long);
+ break;
+
+ case _C_LNG_LNG:
+ return __alignof__ (_Complex long long);
+ break;
+
+ case _C_ULNG_LNG:
+ return __alignof__ (_Complex unsigned long long);
+ break;
+
+ case _C_FLT:
+ return __alignof__ (_Complex float);
+ break;
+
+ case _C_DBL:
+ return __alignof__ (_Complex double);
+ break;
+
+ default:
+ {
+ _objc_abort ("unknown complex type %s\n", type);
+ return 0;
+ }
+ }
+ }
default:
{
- objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
+ _objc_abort ("unknown type %s\n", type);
return 0;
}
}
case _C_UNDEF:
return ++type;
break;
+
+ case _C_COMPLEX:
+ return type + 2;
+ break;
case _C_ARY_B:
/* skip digits, typespec and closing ']' */
return ++type;
else
{
- objc_error (nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type);
+ _objc_abort ("bad array type %s\n", type);
return 0;
}
default:
{
- objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
+ _objc_abort ("unknown type %s\n", type);
return 0;
}
}
if (*type != _C_UNION_B && *type != _C_STRUCT_B)
{
- objc_error (nil, OBJC_ERR_BAD_TYPE,
- "record (or union) type expected in objc_layout_structure, got %s\n",
- type);
+ _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
+ type);
}
type ++;
/* The following are used only if the field is a bitfield */
register const char *bfld_type = 0;
- register int bfld_type_size, bfld_type_align = 0, bfld_field_size = 0;
+ register int bfld_type_align = 0, bfld_field_size = 0;
/* The current type without the type qualifiers */
const char *type;
bfld_type++)
/* do nothing */;
- bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT;
bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
bfld_field_size = atoi (objc_skip_typespec (bfld_type));
layout->record_size += bfld_field_size;
bfld_type++)
/* do nothing */;
- bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT;
bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
bfld_field_size = atoi (objc_skip_typespec (bfld_type));
}
/* Work out the alignment of the record as one expression and store
in the record type. Round it up to a multiple of the record's
alignment. */
-
#if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
- layout->record_align = ROUND_TYPE_ALIGN (layout->original_type,
+ layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1,
layout->record_align);
#else