id = mangle(id_underscore, get_entity_ident(ent));
}
- decl_modifiers_t decl_modifiers = declaration->decl_modifiers;
+ decl_modifiers_t decl_modifiers = declaration->modifiers;
if (decl_modifiers & DM_DLLIMPORT) {
/* add prefix for imported symbols */
id = mangle(id_imp, id);
}
}
+static void add_function_pointer(ir_type *segment, ir_entity *method,
+ const char *unique_template)
+{
+ ir_type *method_type = get_entity_type(method);
+ ident *id = id_unique(unique_template);
+ ir_type *ptr_type = new_type_pointer(id, method_type, mode_P_code);
+
+ ident *ide = id_unique(unique_template);
+ ir_entity *ptr = new_entity(segment, ide, ptr_type);
+ ir_graph *irg = get_const_code_irg();
+ ir_node *val = new_rd_SymConst_addr_ent(NULL, irg, mode_P_code,
+ method, NULL);
+
+ set_entity_compiler_generated(ptr, 1);
+ set_entity_variability(ptr, variability_constant);
+ set_atomic_ent_value(ptr, val);
+}
+
/**
* Create code for a function.
*/
if (declaration->init.statement == NULL)
return;
+ if (declaration->modifiers & DM_CONSTRUCTOR) {
+ ir_type *segment = get_segment_type(IR_SEGMENT_CONSTRUCTORS);
+ add_function_pointer(segment, function_entity, "constructor_ptr.%u");
+ }
+ if (declaration->modifiers & DM_DESTRUCTOR) {
+ ir_type *segment = get_segment_type(IR_SEGMENT_DESTRUCTORS);
+ add_function_pointer(segment, function_entity, "destructor_ptr.%u");
+ }
+
current_function_decl = declaration;
current_function_name = NULL;
current_funcsig = NULL;
/* set inline flags */
if (declaration->is_inline)
set_irg_inline_property(irg, irg_inline_recomended);
- handle_decl_modifier_irg(irg, declaration->decl_modifiers);
+ handle_decl_modifier_irg(irg, declaration->modifiers);
next_value_number_function = 0;
initialize_function_parameters(declaration);
* Extended microsoft modifier.
*/
typedef enum {
- DM_DLLIMPORT = (1 << 0),
- DM_DLLEXPORT = (1 << 1),
- DM_THREAD = (1 << 2),
- DM_NAKED = (1 << 3),
- DM_MICROSOFT_INLINE = (1 << 4),
- DM_FORCEINLINE = (1 << 5),
- DM_SELECTANY = (1 << 6),
- DM_NOTHROW = (1 << 7),
- DM_NOVTABLE = (1 << 8),
- DM_NORETURN = (1 << 9),
- DM_NOINLINE = (1 << 10),
- DM_RESTRICT = (1 << 11),
- DM_NOALIAS = (1 << 12)
+ DM_DLLIMPORT = (1 << 0),
+ DM_DLLEXPORT = (1 << 1),
+ DM_THREAD = (1 << 2),
+ DM_NAKED = (1 << 3),
+ DM_MICROSOFT_INLINE = (1 << 4),
+ DM_FORCEINLINE = (1 << 5),
+ DM_SELECTANY = (1 << 6),
+ DM_NOTHROW = (1 << 7),
+ DM_NOVTABLE = (1 << 8),
+ DM_NORETURN = (1 << 9),
+ DM_NOINLINE = (1 << 10),
+ DM_RESTRICT = (1 << 11),
+ DM_NOALIAS = (1 << 12),
+ DM_PACKED = (1 << 13),
+ DM_TRANSPARENT_UNION = (1 << 14),
+ DM_PURE = (1 << 15),
+ DM_CONSTRUCTOR = (1 << 16),
+ DM_DESTRUCTOR = (1 << 17)
} decl_modifier_t;
-typedef unsigned short decl_modifiers_t;
+typedef unsigned decl_modifiers_t;
struct declaration_t {
unsigned char namespc;
unsigned char declared_storage_class;
unsigned char storage_class;
unsigned char alignment; /**< Alignment of the declaration, 0 for default. */
- decl_modifiers_t decl_modifiers; /**< MS __declspec modifiers. */
+ decl_modifiers_t modifiers; /**< modifiers. */
const char *deprecated_string; /**< MS deprecated string if any. */
symbol_t *get_property_sym; /**< MS get property. */
symbol_t *put_property_sym; /**< MS put property. */
unsigned char alignment; /**< Alignment, 0 if not set. */
unsigned int is_inline : 1;
unsigned int deprecated : 1;
- decl_modifiers_t decl_modifiers; /**< MS __declspec extended modifier mask */
+ decl_modifiers_t modifiers; /**< declaration modifiers */
gnu_attribute_t *gnu_attributes; /**< list of GNU attributes */
const char *deprecated_string; /**< can be set if declaration was marked deprecated. */
symbol_t *get_property_sym; /**< the name of the get property if set. */
attribute->u.value = true;
}
+static void check_no_argument(gnu_attribute_t *attribute, const char *name)
+{
+ if(!attribute->have_arguments)
+ return;
+
+ /* should have no arguments */
+ errorf(HERE, "wrong number of arguments specified for '%s' attribute", name);
+ eat_until_matching_token('(');
+ /* we have already consumed '(', so we stop before ')', eat it */
+ eat(')');
+ attribute->invalid = true;
+}
+
/**
* Parse one GNU attribute.
*
* interrupt( string literal )
* sentinel( constant expression )
*/
-static void parse_gnu_attribute(gnu_attribute_t **attributes)
+static decl_modifiers_t parse_gnu_attribute(gnu_attribute_t **attributes)
{
- gnu_attribute_t *head = *attributes;
- gnu_attribute_t *last = *attributes;
+ gnu_attribute_t *head = *attributes;
+ gnu_attribute_t *last = *attributes;
+ decl_modifiers_t modifiers = 0;
gnu_attribute_t *attribute;
eat(T___attribute__);
case GNU_AK_STDCALL:
case GNU_AK_FASTCALL:
case GNU_AK_DEPRECATED:
- case GNU_AK_NOINLINE:
- case GNU_AK_NORETURN:
case GNU_AK_NAKED:
- case GNU_AK_PURE:
- case GNU_AK_ALWAYS_INLINE:
case GNU_AK_MALLOC:
case GNU_AK_WEAK:
- case GNU_AK_CONSTRUCTOR:
- case GNU_AK_DESTRUCTOR:
- case GNU_AK_NOTHROW:
- case GNU_AK_TRANSPARENT_UNION:
case GNU_AK_COMMON:
case GNU_AK_NOCOMMON:
- case GNU_AK_PACKED:
case GNU_AK_SHARED:
case GNU_AK_NOTSHARED:
case GNU_AK_USED:
case GNU_AK_MAY_ALIAS:
case GNU_AK_MS_STRUCT:
case GNU_AK_GCC_STRUCT:
+ check_no_argument(attribute, name);
+ break;
+
+ case GNU_AK_PURE:
+ check_no_argument(attribute, name);
+ modifiers |= DM_PURE;
+ break;
+
+ case GNU_AK_ALWAYS_INLINE:
+ check_no_argument(attribute, name);
+ modifiers |= DM_FORCEINLINE;
+ break;
+
case GNU_AK_DLLIMPORT:
+ check_no_argument(attribute, name);
+ modifiers |= DM_DLLIMPORT;
+ break;
+
case GNU_AK_DLLEXPORT:
- if(attribute->have_arguments) {
- /* should have no arguments */
- errorf(HERE, "wrong number of arguments specified for '%s' attribute", name);
- eat_until_matching_token('(');
- /* we have already consumed '(', so we stop before ')', eat it */
- eat(')');
- attribute->invalid = true;
- }
+ check_no_argument(attribute, name);
+ modifiers |= DM_DLLEXPORT;
+ break;
+
+ case GNU_AK_PACKED:
+ check_no_argument(attribute, name);
+ modifiers |= DM_PACKED;
+ break;
+
+ case GNU_AK_NOINLINE:
+ check_no_argument(attribute, name);
+ modifiers |= DM_NOINLINE;
+ break;
+
+ case GNU_AK_NORETURN:
+ check_no_argument(attribute, name);
+ modifiers |= DM_NORETURN;
+ break;
+
+ case GNU_AK_NOTHROW:
+ check_no_argument(attribute, name);
+ modifiers |= DM_NOTHROW;
+ break;
+
+ case GNU_AK_TRANSPARENT_UNION:
+ check_no_argument(attribute, name);
+ modifiers |= DM_TRANSPARENT_UNION;
+ break;
+
+ case GNU_AK_CONSTRUCTOR:
+ check_no_argument(attribute, name);
+ modifiers |= DM_CONSTRUCTOR;
+ break;
+
+ case GNU_AK_DESTRUCTOR:
+ check_no_argument(attribute, name);
+ modifiers |= DM_DESTRUCTOR;
break;
case GNU_AK_ALIGNED:
expect(')');
end_error:
*attributes = head;
+
+ return modifiers;
}
/**
* Parse GNU attributes.
*/
-static void parse_attributes(gnu_attribute_t **attributes)
+static decl_modifiers_t parse_attributes(gnu_attribute_t **attributes)
{
+ decl_modifiers_t modifiers = 0;
+
while(true) {
switch(token.type) {
case T___attribute__: {
- parse_gnu_attribute(attributes);
+ modifiers |= parse_gnu_attribute(attributes);
break;
}
case T_asm:
attributes_finished:
end_error:
- return;
+ return modifiers;
}
static designator_t *parse_designation(void)
static void parse_microsoft_extended_decl_modifier(declaration_specifiers_t *specifiers)
{
- decl_modifiers_t *modifiers = &specifiers->decl_modifiers;
+ decl_modifiers_t *modifiers = &specifiers->modifiers;
while(true) {
if(token.type == T_restrict) {
case T__forceinline:
/* only in microsoft mode */
- specifiers->decl_modifiers |= DM_FORCEINLINE;
+ specifiers->modifiers |= DM_FORCEINLINE;
case T_inline:
next_token();
break;
case T___attribute__:
- parse_attributes(&specifiers->gnu_attributes);
+ specifiers->modifiers
+ |= parse_attributes(&specifiers->gnu_attributes);
break;
case T_IDENTIFIER: {
}
/* TODO: find out if this is correct */
- parse_attributes(&attributes);
+ declaration->modifiers |= parse_attributes(&attributes);
construct_type_t *inner_types = NULL;
}
declarator_finished:
- parse_attributes(&attributes);
+ declaration->modifiers |= parse_attributes(&attributes);
/* append inner_types at the end of the list, we don't to set last anymore
* as it's not needed anymore */
{
declaration_t *const declaration = allocate_declaration_zero();
declaration->declared_storage_class = specifiers->declared_storage_class;
- declaration->decl_modifiers = specifiers->decl_modifiers;
+ declaration->modifiers = specifiers->modifiers;
declaration->deprecated = specifiers->deprecated;
declaration->deprecated_string = specifiers->deprecated_string;
declaration->get_property_sym = specifiers->get_property_sym;
declaration->type = specifiers->type;
declaration->declared_storage_class = specifiers->declared_storage_class;
declaration->source_position = specifiers->source_position;
- declaration->decl_modifiers = specifiers->decl_modifiers;
+ declaration->modifiers = specifiers->modifiers;
if (declaration->declared_storage_class != STORAGE_CLASS_NONE) {
warningf(&declaration->source_position,
declaration->declared_storage_class = STORAGE_CLASS_NONE;
declaration->storage_class = STORAGE_CLASS_NONE;
declaration->source_position = source_position;
- declaration->decl_modifiers = specifiers->decl_modifiers;
+ declaration->modifiers = specifiers->modifiers;
declaration->type = type;
} else {
declaration = parse_declarator(specifiers,/*may_be_abstract=*/true);