Index: src/OFMethodSignature.m ================================================================== --- src/OFMethodSignature.m +++ src/OFMethodSignature.m @@ -27,11 +27,11 @@ #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "macros.h" -size_t alignofEncoding(const char **type, size_t *length); +size_t alignofEncoding(const char **type, size_t *length, bool inStruct); size_t sizeofEncoding(const char **type, size_t *length); size_t alignofArray(const char **type, size_t *length) { @@ -45,11 +45,11 @@ while (*length > 0 && isdigit(**type)) { (*type)++; (*length)--; } - align = alignofEncoding(type, length); + align = alignofEncoding(type, length, true); if (*length == 0 || **type != ']') @throw [OFInvalidFormatException exception]; (*type)++; @@ -83,11 +83,11 @@ /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != '}') { - size_t fieldAlign = alignofEncoding(type, length); + size_t fieldAlign = alignofEncoding(type, length, true); #if defined(OF_POWERPC) && defined(OF_MACOS) if (!first && fieldAlign > 4) fieldAlign = 4; @@ -129,11 +129,11 @@ /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != ')') { - size_t fieldAlign = alignofEncoding(type, length); + size_t fieldAlign = alignofEncoding(type, length, true); if (fieldAlign > align) align = fieldAlign; } @@ -145,11 +145,11 @@ return align; } size_t -alignofEncoding(const char **type, size_t *length) +alignofEncoding(const char **type, size_t *length, bool inStruct) { size_t align; if (*length == 0) @throw [OFInvalidFormatException exception]; @@ -179,11 +179,16 @@ case 'L': align = OF_ALIGNOF(long); break; case 'q': case 'Q': - align = OF_ALIGNOF(long long); +#ifdef OF_X86 + if (inStruct) + align = 4; + else +#endif + align = OF_ALIGNOF(long long); break; #ifdef __SIZEOF_INT128__ case 't': case 'T': align = __extension__ OF_ALIGNOF(__int128); @@ -191,14 +196,24 @@ #endif case 'f': align = OF_ALIGNOF(float); break; case 'd': - align = OF_ALIGNOF(double); +#ifdef OF_X86 + if (inStruct) + align = 4; + else +#endif + align = OF_ALIGNOF(double); break; case 'D': - align = OF_ALIGNOF(long double); +#ifdef OF_X86 + if (inStruct) + align = 4; + else +#endif + align = OF_ALIGNOF(long double); break; case 'B': align = OF_ALIGNOF(_Bool); break; case 'v': @@ -224,11 +239,11 @@ return alignofUnion(type, length); case '^': /* Just to skip over the rest */ (*type)++; (*length)--; - alignofEncoding(type, length); + alignofEncoding(type, length, false); return OF_ALIGNOF(void *); #ifndef __STDC_NO_COMPLEX__ case 'j': (*type)++; @@ -240,11 +255,16 @@ switch (**type) { case 'f': align = OF_ALIGNOF(float _Complex); break; case 'd': - align = OF_ALIGNOF(double _Complex); +# ifdef OF_X86 + if (inStruct) + align = 4; + else +#endif + align = OF_ALIGNOF(double _Complex); break; case 'D': align = OF_ALIGNOF(long double _Complex); break; default: @@ -331,11 +351,11 @@ size_t fieldSize, fieldAlign; typeCopy = *type; lengthCopy = *length; fieldSize = sizeofEncoding(type, length); - fieldAlign = alignofEncoding(&typeCopy, &lengthCopy); + fieldAlign = alignofEncoding(&typeCopy, &lengthCopy, true); #if defined(OF_POWERPC) && defined(OF_MACOS) if (!first && fieldAlign > 4) fieldAlign = 4; @@ -545,11 +565,11 @@ size_t of_alignof_type_encoding(const char *type) { size_t length = strlen(type); - size_t ret = alignofEncoding(&type, &length); + size_t ret = alignofEncoding(&type, &length, false); if (length > 0) @throw [OFInvalidFormatException exception]; return ret; Index: tests/OFMethodSignatureTests.m ================================================================== --- tests/OFMethodSignatureTests.m +++ tests/OFMethodSignatureTests.m @@ -16,10 +16,14 @@ */ #include "config.h" #include + +#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) +# include +#endif #import "OFMethodSignature.h" #import "OFAutoreleasePool.h" #import "OFInvalidFormatException.h" @@ -44,10 +48,17 @@ char c; int i; } u; double d; }; + +#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) +struct test3_struct { + char c; + complex double cd; +}; +#endif union test3_union { char c; int i; double d; @@ -121,19 +132,25 @@ TEST(@"of_sizeof_type_encoding() #2", of_sizeof_type_encoding(@encode(struct test2_struct)) == sizeof(struct test2_struct)) +#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) TEST(@"of_sizeof_type_encoding() #3", + of_sizeof_type_encoding(@encode(struct test3_struct)) == + sizeof(struct test3_struct)) +#endif + + TEST(@"of_sizeof_type_encoding() #4", of_sizeof_type_encoding(@encode(union test3_union)) == sizeof(union test3_union)) - TEST(@"of_sizeof_type_encoding() #4", + TEST(@"of_sizeof_type_encoding() #5", of_sizeof_type_encoding(@encode(union test4_union)) == sizeof(union test4_union)) - TEST(@"of_sizeof_type_encoding() #5", + TEST(@"of_sizeof_type_encoding() #6", of_sizeof_type_encoding(@encode(struct test1_struct [5])) == sizeof(struct test1_struct [5])) TEST(@"of_alignof_type_encoding() #1", of_alignof_type_encoding(@encode(struct test1_struct)) == @@ -141,20 +158,26 @@ TEST(@"of_alignof_type_encoding() #2", of_alignof_type_encoding(@encode(struct test2_struct)) == OF_ALIGNOF(struct test2_struct)) +#if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) TEST(@"of_alignof_type_encoding() #3", + of_alignof_type_encoding(@encode(struct test3_struct)) == + OF_ALIGNOF(struct test3_struct)) +#endif + + TEST(@"of_alignof_type_encoding() #4", of_alignof_type_encoding(@encode(union test3_union)) == OF_ALIGNOF(union test3_union)) - TEST(@"of_alignof_type_encoding() #4", + TEST(@"of_alignof_type_encoding() #5", of_alignof_type_encoding(@encode(union test4_union)) == OF_ALIGNOF(union test4_union)) - TEST(@"of_alignof_type_encoding() #5", + TEST(@"of_alignof_type_encoding() #6", of_alignof_type_encoding(@encode(struct test1_struct [5])) == OF_ALIGNOF(struct test1_struct [5])) [pool drain]; } @end