diff --git a/include/gcc-c-fe.def b/include/gcc-c-fe.def index 36a765484a7..cb7cf197525 100644 --- a/include/gcc-c-fe.def +++ b/include/gcc-c-fe.def @@ -89,7 +89,10 @@ GCC_METHOD5 (int /* bool */, build_add_field, /* After all the fields have been added to a struct or union, the struct or union type must be "finished". This does some final - cleanups in GCC. */ + cleanups in GCC. + + Note that when using GCC_C_FE_VERSION_2, it is preferable to call + finish_record_with_alignment instead. */ GCC_METHOD2 (int /* bool */, finish_record_or_union, gcc_type, /* Argument RECORD_OR_UNION_TYPE. */ @@ -220,3 +223,11 @@ GCC_METHOD2 (gcc_type, float_type, unsigned long, /* Argument SIZE_IN_BYTES. */ const char *) /* Argument BUILTIN_NAME. */ +/* New in GCC_FE_VERSION_2. Like finish_record_or_union but the caller also + supplies the alignment. If the alignment is 0, this acts identically to + finish_record_or_union. */ + +GCC_METHOD3 (int /* bool */, finish_record_with_alignment, + gcc_type, /* Argument RECORD_OR_UNION_TYPE. */ + unsigned long, /* Argument SIZE_IN_BYTES. */ + unsigned long) /* Argument ALIGNMENT. */ diff --git a/include/gcc-c-interface.h b/include/gcc-c-interface.h index feece1e38a2..700d7483a4a 100644 --- a/include/gcc-c-interface.h +++ b/include/gcc-c-interface.h @@ -45,7 +45,10 @@ enum gcc_c_api_version /* Added char_type. Added new version of int_type and float_type, deprecated int_type_v0 and float_type_v0. */ - GCC_C_FE_VERSION_1 = 1 + GCC_C_FE_VERSION_1 = 1, + + /* Added finish_record_with_alignment method. */ + GCC_C_FE_VERSION_2 = 2, }; /* Qualifiers. */ @@ -198,7 +201,11 @@ struct gcc_c_context /* The type of the initialization function. The caller passes in the desired base version and desired C-specific version. If the request can be satisfied, a compatible gcc_context object will be - returned. Otherwise, the function returns NULL. */ + returned. In particular, this may return a context object with a higher + actual version number than was requested, provided the higher version is + fully compatible. (As of GCC_C_FE_VERSION_2, this is always true.) + + Otherwise, the function returns NULL. */ typedef struct gcc_c_context *gcc_c_fe_context_function (enum gcc_base_api_version, diff --git a/include/gcc-cp-interface.h b/include/gcc-cp-interface.h index 2f950729b9b..15b911cb216 100644 --- a/include/gcc-cp-interface.h +++ b/include/gcc-cp-interface.h @@ -483,7 +483,11 @@ struct gcc_cp_context /* The type of the initialization function. The caller passes in the desired base version and desired C-specific version. If the request can be satisfied, a compatible gcc_context object will be - returned. Otherwise, the function returns NULL. */ + returned. In particular, this may return a context object with a higher + actual version number than was requested, provided the higher version is + fully compatible. + + Otherwise, the function returns NULL. */ typedef struct gcc_cp_context *gcc_cp_fe_context_function (enum gcc_base_api_version, diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc index 992181e8fdc..1c570f3054d 100644 --- a/libcc1/libcc1.cc +++ b/libcc1/libcc1.cc @@ -108,7 +108,7 @@ set_callbacks (struct gcc_c_context *s, static const struct gcc_c_fe_vtable c_vtable = { - GCC_C_FE_VERSION_1, + GCC_C_FE_VERSION_2, set_callbacks, #define GCC_METHOD0(R, N) \ @@ -165,7 +165,8 @@ gcc_c_fe_context (enum gcc_base_api_version base_version, enum gcc_c_api_version c_version) { if ((base_version != GCC_FE_VERSION_0 && base_version != GCC_FE_VERSION_1) - || (c_version != GCC_C_FE_VERSION_0 && c_version != GCC_C_FE_VERSION_1)) + || (c_version != GCC_C_FE_VERSION_0 && c_version != GCC_C_FE_VERSION_1 + && c_version != GCC_C_FE_VERSION_2)) return NULL; return new libcc1 (&c_vtable); diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc index f1082d8e9d3..72d17c3b81c 100644 --- a/libcc1/libcc1plugin.cc +++ b/libcc1/libcc1plugin.cc @@ -387,9 +387,10 @@ plugin_build_add_field (cc1_plugin::connection *, } int -plugin_finish_record_or_union (cc1_plugin::connection *, - gcc_type record_or_union_type_in, - unsigned long size_in_bytes) +plugin_finish_record_with_alignment (cc1_plugin::connection *, + gcc_type record_or_union_type_in, + unsigned long size_in_bytes, + unsigned long align) { tree record_or_union_type = convert_in (record_or_union_type_in); @@ -407,10 +408,10 @@ plugin_finish_record_or_union (cc1_plugin::connection *, } else { - // FIXME there's no way to get this from DWARF, - // or even, it seems, a particularly good way to deduce it. - SET_TYPE_ALIGN (record_or_union_type, - TYPE_PRECISION (pointer_sized_int_node)); + if (align == 0) + align = TYPE_PRECISION (pointer_sized_int_node); + + SET_TYPE_ALIGN (record_or_union_type, align); TYPE_SIZE (record_or_union_type) = bitsize_int (size_in_bytes * BITS_PER_UNIT); @@ -441,6 +442,15 @@ plugin_finish_record_or_union (cc1_plugin::connection *, return 1; } +int +plugin_finish_record_or_union (cc1_plugin::connection *conn, + gcc_type record_or_union_type_in, + unsigned long size_in_bytes) +{ + return plugin_finish_record_with_alignment (conn, record_or_union_type_in, + size_in_bytes, 0); +} + gcc_type plugin_build_enum_type (cc1_plugin::connection *self, gcc_type underlying_int_type_in) @@ -755,7 +765,7 @@ int plugin_init (struct plugin_name_args *plugin_info, struct plugin_gcc_version *) { - generic_plugin_init (plugin_info, GCC_C_FE_VERSION_1); + generic_plugin_init (plugin_info, GCC_C_FE_VERSION_2); register_callback (plugin_info->base_name, PLUGIN_PRAGMAS, plugin_init_extra_pragmas, NULL);