static unsigned get_expression_precedence(expression_kind_t kind)
{
static const unsigned prec[] = {
- [EXPR_UNKNOWN] = PREC_PRIMARY,
- [EXPR_INVALID] = PREC_PRIMARY,
- [EXPR_REFERENCE] = PREC_PRIMARY,
- [EXPR_REFERENCE_ENUM_VALUE] = PREC_PRIMARY,
- [EXPR_CHARACTER_CONSTANT] = PREC_PRIMARY,
- [EXPR_WIDE_CHARACTER_CONSTANT] = PREC_PRIMARY,
- [EXPR_CONST] = PREC_PRIMARY,
- [EXPR_STRING_LITERAL] = PREC_PRIMARY,
- [EXPR_WIDE_STRING_LITERAL] = PREC_PRIMARY,
- [EXPR_COMPOUND_LITERAL] = PREC_UNARY,
- [EXPR_CALL] = PREC_POSTFIX,
- [EXPR_CONDITIONAL] = PREC_CONDITIONAL,
- [EXPR_SELECT] = PREC_POSTFIX,
- [EXPR_ARRAY_ACCESS] = PREC_POSTFIX,
- [EXPR_SIZEOF] = PREC_UNARY,
- [EXPR_CLASSIFY_TYPE] = PREC_UNARY,
- [EXPR_ALIGNOF] = PREC_UNARY,
-
- [EXPR_FUNCNAME] = PREC_PRIMARY,
- [EXPR_BUILTIN_SYMBOL] = PREC_PRIMARY,
- [EXPR_BUILTIN_CONSTANT_P] = PREC_PRIMARY,
- [EXPR_BUILTIN_PREFETCH] = PREC_PRIMARY,
- [EXPR_OFFSETOF] = PREC_PRIMARY,
- [EXPR_VA_START] = PREC_PRIMARY,
- [EXPR_VA_ARG] = PREC_PRIMARY,
- [EXPR_STATEMENT] = PREC_PRIMARY,
- [EXPR_LABEL_ADDRESS] = PREC_PRIMARY,
-
- [EXPR_UNARY_NEGATE] = PREC_UNARY,
- [EXPR_UNARY_PLUS] = PREC_UNARY,
- [EXPR_UNARY_BITWISE_NEGATE] = PREC_UNARY,
- [EXPR_UNARY_NOT] = PREC_UNARY,
- [EXPR_UNARY_DEREFERENCE] = PREC_UNARY,
- [EXPR_UNARY_TAKE_ADDRESS] = PREC_UNARY,
- [EXPR_UNARY_POSTFIX_INCREMENT] = PREC_POSTFIX,
- [EXPR_UNARY_POSTFIX_DECREMENT] = PREC_POSTFIX,
- [EXPR_UNARY_PREFIX_INCREMENT] = PREC_UNARY,
- [EXPR_UNARY_PREFIX_DECREMENT] = PREC_UNARY,
- [EXPR_UNARY_CAST] = PREC_UNARY,
- [EXPR_UNARY_CAST_IMPLICIT] = PREC_UNARY,
- [EXPR_UNARY_ASSUME] = PREC_PRIMARY,
- [EXPR_UNARY_DELETE] = PREC_UNARY,
- [EXPR_UNARY_DELETE_ARRAY] = PREC_UNARY,
- [EXPR_UNARY_THROW] = PREC_ASSIGNMENT,
-
- [EXPR_BINARY_ADD] = PREC_ADDITIVE,
- [EXPR_BINARY_SUB] = PREC_ADDITIVE,
- [EXPR_BINARY_MUL] = PREC_MULTIPLICATIVE,
- [EXPR_BINARY_DIV] = PREC_MULTIPLICATIVE,
- [EXPR_BINARY_MOD] = PREC_MULTIPLICATIVE,
- [EXPR_BINARY_EQUAL] = PREC_EQUALITY,
- [EXPR_BINARY_NOTEQUAL] = PREC_EQUALITY,
- [EXPR_BINARY_LESS] = PREC_RELATIONAL,
- [EXPR_BINARY_LESSEQUAL] = PREC_RELATIONAL,
- [EXPR_BINARY_GREATER] = PREC_RELATIONAL,
- [EXPR_BINARY_GREATEREQUAL] = PREC_RELATIONAL,
- [EXPR_BINARY_BITWISE_AND] = PREC_AND,
- [EXPR_BINARY_BITWISE_OR] = PREC_OR,
- [EXPR_BINARY_BITWISE_XOR] = PREC_XOR,
- [EXPR_BINARY_LOGICAL_AND] = PREC_LOGICAL_AND,
- [EXPR_BINARY_LOGICAL_OR] = PREC_LOGICAL_OR,
- [EXPR_BINARY_SHIFTLEFT] = PREC_SHIFT,
- [EXPR_BINARY_SHIFTRIGHT] = PREC_SHIFT,
- [EXPR_BINARY_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_MUL_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_DIV_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_MOD_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_ADD_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_SUB_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_SHIFTLEFT_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_SHIFTRIGHT_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_BITWISE_AND_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_BITWISE_XOR_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_BITWISE_OR_ASSIGN] = PREC_ASSIGNMENT,
- [EXPR_BINARY_COMMA] = PREC_EXPRESSION,
-
- [EXPR_BINARY_ISGREATER] = PREC_PRIMARY,
- [EXPR_BINARY_ISGREATEREQUAL] = PREC_PRIMARY,
- [EXPR_BINARY_ISLESS] = PREC_PRIMARY,
- [EXPR_BINARY_ISLESSEQUAL] = PREC_PRIMARY,
- [EXPR_BINARY_ISLESSGREATER] = PREC_PRIMARY,
- [EXPR_BINARY_ISUNORDERED] = PREC_PRIMARY
+ [EXPR_UNKNOWN] = PREC_PRIMARY,
+ [EXPR_INVALID] = PREC_PRIMARY,
+ [EXPR_REFERENCE] = PREC_PRIMARY,
+ [EXPR_REFERENCE_ENUM_VALUE] = PREC_PRIMARY,
+ [EXPR_CHARACTER_CONSTANT] = PREC_PRIMARY,
+ [EXPR_WIDE_CHARACTER_CONSTANT] = PREC_PRIMARY,
+ [EXPR_CONST] = PREC_PRIMARY,
+ [EXPR_STRING_LITERAL] = PREC_PRIMARY,
+ [EXPR_WIDE_STRING_LITERAL] = PREC_PRIMARY,
+ [EXPR_COMPOUND_LITERAL] = PREC_UNARY,
+ [EXPR_CALL] = PREC_POSTFIX,
+ [EXPR_CONDITIONAL] = PREC_CONDITIONAL,
+ [EXPR_SELECT] = PREC_POSTFIX,
+ [EXPR_ARRAY_ACCESS] = PREC_POSTFIX,
+ [EXPR_SIZEOF] = PREC_UNARY,
+ [EXPR_CLASSIFY_TYPE] = PREC_UNARY,
+ [EXPR_ALIGNOF] = PREC_UNARY,
+
+ [EXPR_FUNCNAME] = PREC_PRIMARY,
+ [EXPR_BUILTIN_SYMBOL] = PREC_PRIMARY,
+ [EXPR_BUILTIN_CONSTANT_P] = PREC_PRIMARY,
+ [EXPR_BUILTIN_TYPES_COMPATIBLE_P] = PREC_PRIMARY,
+ [EXPR_BUILTIN_PREFETCH] = PREC_PRIMARY,
+ [EXPR_OFFSETOF] = PREC_PRIMARY,
+ [EXPR_VA_START] = PREC_PRIMARY,
+ [EXPR_VA_ARG] = PREC_PRIMARY,
+ [EXPR_STATEMENT] = PREC_PRIMARY,
+ [EXPR_LABEL_ADDRESS] = PREC_PRIMARY,
+
+ [EXPR_UNARY_NEGATE] = PREC_UNARY,
+ [EXPR_UNARY_PLUS] = PREC_UNARY,
+ [EXPR_UNARY_BITWISE_NEGATE] = PREC_UNARY,
+ [EXPR_UNARY_NOT] = PREC_UNARY,
+ [EXPR_UNARY_DEREFERENCE] = PREC_UNARY,
+ [EXPR_UNARY_TAKE_ADDRESS] = PREC_UNARY,
+ [EXPR_UNARY_POSTFIX_INCREMENT] = PREC_POSTFIX,
+ [EXPR_UNARY_POSTFIX_DECREMENT] = PREC_POSTFIX,
+ [EXPR_UNARY_PREFIX_INCREMENT] = PREC_UNARY,
+ [EXPR_UNARY_PREFIX_DECREMENT] = PREC_UNARY,
+ [EXPR_UNARY_CAST] = PREC_UNARY,
+ [EXPR_UNARY_CAST_IMPLICIT] = PREC_UNARY,
+ [EXPR_UNARY_ASSUME] = PREC_PRIMARY,
+ [EXPR_UNARY_DELETE] = PREC_UNARY,
+ [EXPR_UNARY_DELETE_ARRAY] = PREC_UNARY,
+ [EXPR_UNARY_THROW] = PREC_ASSIGNMENT,
+
+ [EXPR_BINARY_ADD] = PREC_ADDITIVE,
+ [EXPR_BINARY_SUB] = PREC_ADDITIVE,
+ [EXPR_BINARY_MUL] = PREC_MULTIPLICATIVE,
+ [EXPR_BINARY_DIV] = PREC_MULTIPLICATIVE,
+ [EXPR_BINARY_MOD] = PREC_MULTIPLICATIVE,
+ [EXPR_BINARY_EQUAL] = PREC_EQUALITY,
+ [EXPR_BINARY_NOTEQUAL] = PREC_EQUALITY,
+ [EXPR_BINARY_LESS] = PREC_RELATIONAL,
+ [EXPR_BINARY_LESSEQUAL] = PREC_RELATIONAL,
+ [EXPR_BINARY_GREATER] = PREC_RELATIONAL,
+ [EXPR_BINARY_GREATEREQUAL] = PREC_RELATIONAL,
+ [EXPR_BINARY_BITWISE_AND] = PREC_AND,
+ [EXPR_BINARY_BITWISE_OR] = PREC_OR,
+ [EXPR_BINARY_BITWISE_XOR] = PREC_XOR,
+ [EXPR_BINARY_LOGICAL_AND] = PREC_LOGICAL_AND,
+ [EXPR_BINARY_LOGICAL_OR] = PREC_LOGICAL_OR,
+ [EXPR_BINARY_SHIFTLEFT] = PREC_SHIFT,
+ [EXPR_BINARY_SHIFTRIGHT] = PREC_SHIFT,
+ [EXPR_BINARY_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_MUL_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_DIV_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_MOD_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_ADD_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_SUB_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_SHIFTLEFT_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_SHIFTRIGHT_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_BITWISE_AND_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_BITWISE_XOR_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_BITWISE_OR_ASSIGN] = PREC_ASSIGNMENT,
+ [EXPR_BINARY_COMMA] = PREC_EXPRESSION,
+
+ [EXPR_BINARY_ISGREATER] = PREC_PRIMARY,
+ [EXPR_BINARY_ISGREATEREQUAL] = PREC_PRIMARY,
+ [EXPR_BINARY_ISLESS] = PREC_PRIMARY,
+ [EXPR_BINARY_ISLESSEQUAL] = PREC_PRIMARY,
+ [EXPR_BINARY_ISLESSGREATER] = PREC_PRIMARY,
+ [EXPR_BINARY_ISUNORDERED] = PREC_PRIMARY
};
assert((size_t)kind < lengthof(prec));
unsigned res = prec[kind];
fputc(')', out);
}
+/**
+ * Prints a builtin types compatible expression.
+ *
+ * @param expression the builtin types compatible expression
+ */
+static void print_builtin_types_compatible(
+ const builtin_types_compatible_expression_t *expression)
+{
+ fputs("__builtin_types_compatible_p(", out);
+ print_type(expression->left);
+ fputs(", ", out);
+ print_type(expression->right);
+ fputc(')', out);
+}
+
/**
* Prints a builtin prefetch expression.
*
case EXPR_BUILTIN_CONSTANT_P:
print_builtin_constant(&expression->builtin_constant);
break;
+ case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
+ print_builtin_types_compatible(&expression->builtin_types_compatible);
+ break;
case EXPR_BUILTIN_PREFETCH:
print_builtin_prefetch(&expression->builtin_prefetch);
break;
case EXPR_OFFSETOF:
case EXPR_ALIGNOF:
case EXPR_BUILTIN_CONSTANT_P:
+ case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
case EXPR_LABEL_ADDRESS:
case EXPR_REFERENCE_ENUM_VALUE:
return true;
#include <stdbool.h>
#include "entity.h"
-typedef struct expression_base_t expression_base_t;
-typedef struct const_expression_t const_expression_t;
-typedef struct string_literal_expression_t string_literal_expression_t;
-typedef struct funcname_expression_t funcname_expression_t;
-typedef struct wide_string_literal_expression_t wide_string_literal_expression_t;
-typedef struct compound_literal_expression_t compound_literal_expression_t;
-typedef struct reference_expression_t reference_expression_t;
-typedef struct cast_expression_t cast_expression_t;
-typedef struct call_argument_t call_argument_t;
-typedef struct type_argument_t type_argument_t;
-typedef struct call_expression_t call_expression_t;
-typedef struct binary_expression_t binary_expression_t;
-typedef struct unary_expression_t unary_expression_t;
-typedef struct select_expression_t select_expression_t;
-typedef struct array_access_expression_t array_access_expression_t;
-typedef struct typeprop_expression_t typeprop_expression_t;
-typedef struct conditional_expression_t conditional_expression_t;
-typedef struct expression_list_element_t expression_list_element_t;
-typedef struct comma_expression_t comma_expression_t;
-typedef struct statement_expression_t statement_expression_t;
-typedef struct designator_t designator_t;
-typedef struct offsetof_expression_t offsetof_expression_t;
-typedef struct va_start_expression_t va_start_expression_t;
-typedef struct va_arg_expression_t va_arg_expression_t;
-typedef struct builtin_symbol_expression_t builtin_symbol_expression_t;
-typedef struct builtin_constant_expression_t builtin_constant_expression_t;
-typedef struct builtin_prefetch_expression_t builtin_prefetch_expression_t;
-typedef struct classify_type_expression_t classify_type_expression_t;
-typedef struct bitfield_extract_expression_t bitfield_extract_expression_t;
-typedef struct label_address_expression_t label_address_expression_t;
-typedef union expression_t expression_t;
+typedef struct expression_base_t expression_base_t;
+typedef struct const_expression_t const_expression_t;
+typedef struct string_literal_expression_t string_literal_expression_t;
+typedef struct funcname_expression_t funcname_expression_t;
+typedef struct wide_string_literal_expression_t wide_string_literal_expression_t;
+typedef struct compound_literal_expression_t compound_literal_expression_t;
+typedef struct reference_expression_t reference_expression_t;
+typedef struct cast_expression_t cast_expression_t;
+typedef struct call_argument_t call_argument_t;
+typedef struct type_argument_t type_argument_t;
+typedef struct call_expression_t call_expression_t;
+typedef struct binary_expression_t binary_expression_t;
+typedef struct unary_expression_t unary_expression_t;
+typedef struct select_expression_t select_expression_t;
+typedef struct array_access_expression_t array_access_expression_t;
+typedef struct typeprop_expression_t typeprop_expression_t;
+typedef struct conditional_expression_t conditional_expression_t;
+typedef struct expression_list_element_t expression_list_element_t;
+typedef struct comma_expression_t comma_expression_t;
+typedef struct statement_expression_t statement_expression_t;
+typedef struct designator_t designator_t;
+typedef struct offsetof_expression_t offsetof_expression_t;
+typedef struct va_start_expression_t va_start_expression_t;
+typedef struct va_arg_expression_t va_arg_expression_t;
+typedef struct builtin_symbol_expression_t builtin_symbol_expression_t;
+typedef struct builtin_constant_expression_t builtin_constant_expression_t;
+typedef struct builtin_types_compatible_expression_t builtin_types_compatible_expression_t;
+typedef struct builtin_prefetch_expression_t builtin_prefetch_expression_t;
+typedef struct classify_type_expression_t classify_type_expression_t;
+typedef struct bitfield_extract_expression_t bitfield_extract_expression_t;
+typedef struct label_address_expression_t label_address_expression_t;
+typedef union expression_t expression_t;
-typedef struct initializer_base_t initializer_base_t;
-typedef struct initializer_list_t initializer_list_t;
-typedef struct initializer_value_t initializer_value_t;
-typedef struct initializer_string_t initializer_string_t;
-typedef struct initializer_wide_string_t initializer_wide_string_t;
-typedef struct initializer_designator_t initializer_designator_t;
-typedef union initializer_t initializer_t;
+typedef struct initializer_base_t initializer_base_t;
+typedef struct initializer_list_t initializer_list_t;
+typedef struct initializer_value_t initializer_value_t;
+typedef struct initializer_string_t initializer_string_t;
+typedef struct initializer_wide_string_t initializer_wide_string_t;
+typedef struct initializer_designator_t initializer_designator_t;
+typedef union initializer_t initializer_t;
-typedef struct statement_base_t statement_base_t;
-typedef struct invalid_statement_t invalid_statement_t;
-typedef struct empty_statement_t empty_statement_t;
-typedef struct compound_statement_t compound_statement_t;
-typedef struct return_statement_t return_statement_t;
-typedef struct if_statement_t if_statement_t;
-typedef struct switch_statement_t switch_statement_t;
-typedef struct declaration_statement_t declaration_statement_t;
-typedef struct expression_statement_t expression_statement_t;
-typedef struct goto_statement_t goto_statement_t;
-typedef struct label_statement_t label_statement_t;
-typedef struct case_label_statement_t case_label_statement_t;
-typedef struct while_statement_t while_statement_t;
-typedef struct do_while_statement_t do_while_statement_t;
-typedef struct for_statement_t for_statement_t;
-typedef struct asm_argument_t asm_argument_t;
-typedef struct asm_clobber_t asm_clobber_t;
-typedef struct asm_statement_t asm_statement_t;
-typedef struct ms_try_statement_t ms_try_statement_t;
-typedef struct leave_statement_t leave_statement_t;
-typedef union statement_t statement_t;
+typedef struct statement_base_t statement_base_t;
+typedef struct invalid_statement_t invalid_statement_t;
+typedef struct empty_statement_t empty_statement_t;
+typedef struct compound_statement_t compound_statement_t;
+typedef struct return_statement_t return_statement_t;
+typedef struct if_statement_t if_statement_t;
+typedef struct switch_statement_t switch_statement_t;
+typedef struct declaration_statement_t declaration_statement_t;
+typedef struct expression_statement_t expression_statement_t;
+typedef struct goto_statement_t goto_statement_t;
+typedef struct label_statement_t label_statement_t;
+typedef struct case_label_statement_t case_label_statement_t;
+typedef struct while_statement_t while_statement_t;
+typedef struct do_while_statement_t do_while_statement_t;
+typedef struct for_statement_t for_statement_t;
+typedef struct asm_argument_t asm_argument_t;
+typedef struct asm_clobber_t asm_clobber_t;
+typedef struct asm_statement_t asm_statement_t;
+typedef struct ms_try_statement_t ms_try_statement_t;
+typedef struct leave_statement_t leave_statement_t;
+typedef union statement_t statement_t;
-typedef struct translation_unit_t translation_unit_t;
+typedef struct translation_unit_t translation_unit_t;
void init_ast(void);
void exit_ast(void);
return new_Const_long(mode, v);
}
+static ir_node *builtin_types_compatible_to_firm(
+ const builtin_types_compatible_expression_t *expression)
+{
+ type_t *const left = get_unqualified_type(skip_typeref(expression->left));
+ type_t *const right = get_unqualified_type(skip_typeref(expression->right));
+ long const value = types_compatible(left, right) ? 1 : 0;
+ ir_mode *const mode = get_ir_mode_arithmetic(expression->base.type);
+ return new_Const_long(mode, value);
+}
+
static ir_node *builtin_prefetch_to_firm(
const builtin_prefetch_expression_t *expression)
{
return builtin_symbol_to_firm(&expression->builtin_symbol);
case EXPR_BUILTIN_CONSTANT_P:
return builtin_constant_to_firm(&expression->builtin_constant);
+ case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
+ return builtin_types_compatible_to_firm(&expression->builtin_types_compatible);
case EXPR_BUILTIN_PREFETCH:
return builtin_prefetch_to_firm(&expression->builtin_prefetch);
case EXPR_OFFSETOF:
EXPR_FUNCNAME,
EXPR_BUILTIN_SYMBOL,
EXPR_BUILTIN_CONSTANT_P,
+ EXPR_BUILTIN_TYPES_COMPATIBLE_P,
EXPR_BUILTIN_PREFETCH,
EXPR_OFFSETOF,
EXPR_VA_START,
expression_t *value;
};
+struct builtin_types_compatible_expression_t {
+ expression_base_t base;
+ type_t *left;
+ type_t *right;
+};
+
struct builtin_prefetch_expression_t {
expression_base_t base;
expression_t *adr;
};
union expression_t {
- expression_kind_t kind;
- expression_base_t base;
- const_expression_t conste;
- funcname_expression_t funcname;
- string_literal_expression_t string;
- wide_string_literal_expression_t wide_string;
- compound_literal_expression_t compound_literal;
- builtin_symbol_expression_t builtin_symbol;
- builtin_constant_expression_t builtin_constant;
- builtin_prefetch_expression_t builtin_prefetch;
- reference_expression_t reference;
- call_expression_t call;
- unary_expression_t unary;
- binary_expression_t binary;
- select_expression_t select;
- array_access_expression_t array_access;
- typeprop_expression_t typeprop;
- offsetof_expression_t offsetofe;
- va_start_expression_t va_starte;
- va_arg_expression_t va_arge;
- conditional_expression_t conditional;
- statement_expression_t statement;
- classify_type_expression_t classify_type;
- label_address_expression_t label_address;
+ expression_kind_t kind;
+ expression_base_t base;
+ const_expression_t conste;
+ funcname_expression_t funcname;
+ string_literal_expression_t string;
+ wide_string_literal_expression_t wide_string;
+ compound_literal_expression_t compound_literal;
+ builtin_symbol_expression_t builtin_symbol;
+ builtin_constant_expression_t builtin_constant;
+ builtin_types_compatible_expression_t builtin_types_compatible;
+ builtin_prefetch_expression_t builtin_prefetch;
+ reference_expression_t reference;
+ call_expression_t call;
+ unary_expression_t unary;
+ binary_expression_t binary;
+ select_expression_t select;
+ array_access_expression_t array_access;
+ typeprop_expression_t typeprop;
+ offsetof_expression_t offsetofe;
+ va_start_expression_t va_starte;
+ va_arg_expression_t va_arge;
+ conditional_expression_t conditional;
+ statement_expression_t statement;
+ classify_type_expression_t classify_type;
+ label_address_expression_t label_address;
};
typedef enum initializer_kind_t {
static size_t get_expression_struct_size(expression_kind_t kind)
{
static const size_t sizes[] = {
- [EXPR_INVALID] = sizeof(expression_base_t),
- [EXPR_REFERENCE] = sizeof(reference_expression_t),
- [EXPR_REFERENCE_ENUM_VALUE] = sizeof(reference_expression_t),
- [EXPR_CONST] = sizeof(const_expression_t),
- [EXPR_CHARACTER_CONSTANT] = sizeof(const_expression_t),
- [EXPR_WIDE_CHARACTER_CONSTANT] = sizeof(const_expression_t),
- [EXPR_STRING_LITERAL] = sizeof(string_literal_expression_t),
- [EXPR_WIDE_STRING_LITERAL] = sizeof(wide_string_literal_expression_t),
- [EXPR_COMPOUND_LITERAL] = sizeof(compound_literal_expression_t),
- [EXPR_CALL] = sizeof(call_expression_t),
- [EXPR_UNARY_FIRST] = sizeof(unary_expression_t),
- [EXPR_BINARY_FIRST] = sizeof(binary_expression_t),
- [EXPR_CONDITIONAL] = sizeof(conditional_expression_t),
- [EXPR_SELECT] = sizeof(select_expression_t),
- [EXPR_ARRAY_ACCESS] = sizeof(array_access_expression_t),
- [EXPR_SIZEOF] = sizeof(typeprop_expression_t),
- [EXPR_ALIGNOF] = sizeof(typeprop_expression_t),
- [EXPR_CLASSIFY_TYPE] = sizeof(classify_type_expression_t),
- [EXPR_FUNCNAME] = sizeof(funcname_expression_t),
- [EXPR_BUILTIN_SYMBOL] = sizeof(builtin_symbol_expression_t),
- [EXPR_BUILTIN_CONSTANT_P] = sizeof(builtin_constant_expression_t),
- [EXPR_BUILTIN_PREFETCH] = sizeof(builtin_prefetch_expression_t),
- [EXPR_OFFSETOF] = sizeof(offsetof_expression_t),
- [EXPR_VA_START] = sizeof(va_start_expression_t),
- [EXPR_VA_ARG] = sizeof(va_arg_expression_t),
- [EXPR_STATEMENT] = sizeof(statement_expression_t),
- [EXPR_LABEL_ADDRESS] = sizeof(label_address_expression_t),
+ [EXPR_INVALID] = sizeof(expression_base_t),
+ [EXPR_REFERENCE] = sizeof(reference_expression_t),
+ [EXPR_REFERENCE_ENUM_VALUE] = sizeof(reference_expression_t),
+ [EXPR_CONST] = sizeof(const_expression_t),
+ [EXPR_CHARACTER_CONSTANT] = sizeof(const_expression_t),
+ [EXPR_WIDE_CHARACTER_CONSTANT] = sizeof(const_expression_t),
+ [EXPR_STRING_LITERAL] = sizeof(string_literal_expression_t),
+ [EXPR_WIDE_STRING_LITERAL] = sizeof(wide_string_literal_expression_t),
+ [EXPR_COMPOUND_LITERAL] = sizeof(compound_literal_expression_t),
+ [EXPR_CALL] = sizeof(call_expression_t),
+ [EXPR_UNARY_FIRST] = sizeof(unary_expression_t),
+ [EXPR_BINARY_FIRST] = sizeof(binary_expression_t),
+ [EXPR_CONDITIONAL] = sizeof(conditional_expression_t),
+ [EXPR_SELECT] = sizeof(select_expression_t),
+ [EXPR_ARRAY_ACCESS] = sizeof(array_access_expression_t),
+ [EXPR_SIZEOF] = sizeof(typeprop_expression_t),
+ [EXPR_ALIGNOF] = sizeof(typeprop_expression_t),
+ [EXPR_CLASSIFY_TYPE] = sizeof(classify_type_expression_t),
+ [EXPR_FUNCNAME] = sizeof(funcname_expression_t),
+ [EXPR_BUILTIN_SYMBOL] = sizeof(builtin_symbol_expression_t),
+ [EXPR_BUILTIN_CONSTANT_P] = sizeof(builtin_constant_expression_t),
+ [EXPR_BUILTIN_TYPES_COMPATIBLE_P] = sizeof(builtin_types_compatible_expression_t),
+ [EXPR_BUILTIN_PREFETCH] = sizeof(builtin_prefetch_expression_t),
+ [EXPR_OFFSETOF] = sizeof(offsetof_expression_t),
+ [EXPR_VA_START] = sizeof(va_start_expression_t),
+ [EXPR_VA_ARG] = sizeof(va_arg_expression_t),
+ [EXPR_STATEMENT] = sizeof(statement_expression_t),
+ [EXPR_LABEL_ADDRESS] = sizeof(label_address_expression_t),
};
if (kind >= EXPR_UNARY_FIRST && kind <= EXPR_UNARY_LAST) {
return sizes[EXPR_UNARY_FIRST];
case EXPR_FUNCNAME:
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_CONSTANT_P:
+ case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
case EXPR_BUILTIN_PREFETCH:
case EXPR_OFFSETOF:
case EXPR_STATEMENT: // TODO
case EXPR_FUNCNAME:
case EXPR_BUILTIN_SYMBOL:
case EXPR_BUILTIN_CONSTANT_P:
+ case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
case EXPR_BUILTIN_PREFETCH:
case EXPR_OFFSETOF:
case EXPR_INVALID:
}
/**
- * Parses a __builtin_constant() expression.
+ * Parses a __builtin_constant_p() expression.
*/
static expression_t *parse_builtin_constant(void)
{
return create_invalid_expression();
}
+/**
+ * Parses a __builtin_types_compatible_p() expression.
+ */
+static expression_t *parse_builtin_types_compatible(void)
+{
+ expression_t *expression = allocate_expression_zero(EXPR_BUILTIN_TYPES_COMPATIBLE_P);
+
+ eat(T___builtin_types_compatible_p);
+
+ expect('(', end_error);
+ add_anchor_token(')');
+ add_anchor_token(',');
+ expression->builtin_types_compatible.left = parse_typename();
+ rem_anchor_token(',');
+ expect(',', end_error);
+ expression->builtin_types_compatible.right = parse_typename();
+ rem_anchor_token(')');
+ expect(')', end_error);
+ expression->base.type = type_int;
+
+ return expression;
+end_error:
+ return create_invalid_expression();
+}
+
/**
* Parses a __builtin_prefetch() expression.
*/
static expression_t *parse_primary_expression(void)
{
switch (token.type) {
- case T_false: return parse_bool_const(false);
- case T_true: return parse_bool_const(true);
- case T_INTEGER: return parse_int_const();
- case T_CHARACTER_CONSTANT: return parse_character_constant();
- case T_WIDE_CHARACTER_CONSTANT: return parse_wide_character_constant();
- case T_FLOATINGPOINT: return parse_float_const();
+ case T_false: return parse_bool_const(false);
+ case T_true: return parse_bool_const(true);
+ case T_INTEGER: return parse_int_const();
+ case T_CHARACTER_CONSTANT: return parse_character_constant();
+ case T_WIDE_CHARACTER_CONSTANT: return parse_wide_character_constant();
+ case T_FLOATINGPOINT: return parse_float_const();
case T_STRING_LITERAL:
- case T_WIDE_STRING_LITERAL: return parse_string_const();
- case T_IDENTIFIER: return parse_reference();
+ case T_WIDE_STRING_LITERAL: return parse_string_const();
+ case T_IDENTIFIER: return parse_reference();
case T___FUNCTION__:
- case T___func__: return parse_function_keyword();
- case T___PRETTY_FUNCTION__: return parse_pretty_function_keyword();
- case T___FUNCSIG__: return parse_funcsig_keyword();
- case T___FUNCDNAME__: return parse_funcdname_keyword();
- case T___builtin_offsetof: return parse_offsetof();
- case T___builtin_va_start: return parse_va_start();
- case T___builtin_va_arg: return parse_va_arg();
+ case T___func__: return parse_function_keyword();
+ case T___PRETTY_FUNCTION__: return parse_pretty_function_keyword();
+ case T___FUNCSIG__: return parse_funcsig_keyword();
+ case T___FUNCDNAME__: return parse_funcdname_keyword();
+ case T___builtin_offsetof: return parse_offsetof();
+ case T___builtin_va_start: return parse_va_start();
+ case T___builtin_va_arg: return parse_va_arg();
case T___builtin_expect:
case T___builtin_alloca:
case T___builtin_inf:
case T___builtin_huge_val:
case T___builtin_va_end:
case T___builtin_return_address:
- case T___builtin_frame_address: return parse_builtin_symbol();
+ case T___builtin_frame_address: return parse_builtin_symbol();
case T___builtin_isgreater:
case T___builtin_isgreaterequal:
case T___builtin_isless:
case T___builtin_islessequal:
case T___builtin_islessgreater:
- case T___builtin_isunordered: return parse_compare_builtin();
- case T___builtin_constant_p: return parse_builtin_constant();
- case T___builtin_prefetch: return parse_builtin_prefetch();
- case T__assume: return parse_assume();
+ case T___builtin_isunordered: return parse_compare_builtin();
+ case T___builtin_constant_p: return parse_builtin_constant();
+ case T___builtin_prefetch: return parse_builtin_prefetch();
+ case T___builtin_types_compatible_p: return parse_builtin_types_compatible();
+ case T__assume: return parse_assume();
case T_ANDAND:
if (GNU_MODE)
return parse_label_address();
break;
- case '(': return parse_parenthesized_expression();
- case T___noop: return parse_noop_expression();
+ case '(': return parse_parenthesized_expression();
+ case T___noop: return parse_noop_expression();
}
errorf(HERE, "unexpected token %K, expected an expression", &token);
static bool expression_has_effect(const expression_t *const expr)
{
switch (expr->kind) {
- case EXPR_UNKNOWN: break;
- case EXPR_INVALID: return true; /* do NOT warn */
- case EXPR_REFERENCE: return false;
- case EXPR_REFERENCE_ENUM_VALUE: return false;
+ case EXPR_UNKNOWN: break;
+ case EXPR_INVALID: return true; /* do NOT warn */
+ case EXPR_REFERENCE: return false;
+ case EXPR_REFERENCE_ENUM_VALUE: return false;
/* suppress the warning for microsoft __noop operations */
- case EXPR_CONST: return expr->conste.is_ms_noop;
- case EXPR_CHARACTER_CONSTANT: return false;
- case EXPR_WIDE_CHARACTER_CONSTANT: return false;
- case EXPR_STRING_LITERAL: return false;
- case EXPR_WIDE_STRING_LITERAL: return false;
- case EXPR_LABEL_ADDRESS: return false;
+ case EXPR_CONST: return expr->conste.is_ms_noop;
+ case EXPR_CHARACTER_CONSTANT: return false;
+ case EXPR_WIDE_CHARACTER_CONSTANT: return false;
+ case EXPR_STRING_LITERAL: return false;
+ case EXPR_WIDE_STRING_LITERAL: return false;
+ case EXPR_LABEL_ADDRESS: return false;
case EXPR_CALL: {
const call_expression_t *const call = &expr->call;
expression_has_effect(cond->false_expression);
}
- case EXPR_SELECT: return false;
- case EXPR_ARRAY_ACCESS: return false;
- case EXPR_SIZEOF: return false;
- case EXPR_CLASSIFY_TYPE: return false;
- case EXPR_ALIGNOF: return false;
-
- case EXPR_FUNCNAME: return false;
- case EXPR_BUILTIN_SYMBOL: break; /* handled in EXPR_CALL */
- case EXPR_BUILTIN_CONSTANT_P: return false;
- case EXPR_BUILTIN_PREFETCH: return true;
- case EXPR_OFFSETOF: return false;
- case EXPR_VA_START: return true;
- case EXPR_VA_ARG: return true;
- case EXPR_STATEMENT: return true; // TODO
- case EXPR_COMPOUND_LITERAL: return false;
-
- case EXPR_UNARY_NEGATE: return false;
- case EXPR_UNARY_PLUS: return false;
- case EXPR_UNARY_BITWISE_NEGATE: return false;
- case EXPR_UNARY_NOT: return false;
- case EXPR_UNARY_DEREFERENCE: return false;
- case EXPR_UNARY_TAKE_ADDRESS: return false;
- case EXPR_UNARY_POSTFIX_INCREMENT: return true;
- case EXPR_UNARY_POSTFIX_DECREMENT: return true;
- case EXPR_UNARY_PREFIX_INCREMENT: return true;
- case EXPR_UNARY_PREFIX_DECREMENT: return true;
+ case EXPR_SELECT: return false;
+ case EXPR_ARRAY_ACCESS: return false;
+ case EXPR_SIZEOF: return false;
+ case EXPR_CLASSIFY_TYPE: return false;
+ case EXPR_ALIGNOF: return false;
+
+ case EXPR_FUNCNAME: return false;
+ case EXPR_BUILTIN_SYMBOL: break; /* handled in EXPR_CALL */
+ case EXPR_BUILTIN_CONSTANT_P: return false;
+ case EXPR_BUILTIN_TYPES_COMPATIBLE_P: return false;
+ case EXPR_BUILTIN_PREFETCH: return true;
+ case EXPR_OFFSETOF: return false;
+ case EXPR_VA_START: return true;
+ case EXPR_VA_ARG: return true;
+ case EXPR_STATEMENT: return true; // TODO
+ case EXPR_COMPOUND_LITERAL: return false;
+
+ case EXPR_UNARY_NEGATE: return false;
+ case EXPR_UNARY_PLUS: return false;
+ case EXPR_UNARY_BITWISE_NEGATE: return false;
+ case EXPR_UNARY_NOT: return false;
+ case EXPR_UNARY_DEREFERENCE: return false;
+ case EXPR_UNARY_TAKE_ADDRESS: return false;
+ case EXPR_UNARY_POSTFIX_INCREMENT: return true;
+ case EXPR_UNARY_POSTFIX_DECREMENT: return true;
+ case EXPR_UNARY_PREFIX_INCREMENT: return true;
+ case EXPR_UNARY_PREFIX_DECREMENT: return true;
/* Treat void casts as if they have an effect in order to being able to
* suppress the warning */
return is_type_atomic(type, ATOMIC_TYPE_VOID);
}
- case EXPR_UNARY_CAST_IMPLICIT: return true;
- case EXPR_UNARY_ASSUME: return true;
- case EXPR_UNARY_DELETE: return true;
- case EXPR_UNARY_DELETE_ARRAY: return true;
- case EXPR_UNARY_THROW: return true;
-
- case EXPR_BINARY_ADD: return false;
- case EXPR_BINARY_SUB: return false;
- case EXPR_BINARY_MUL: return false;
- case EXPR_BINARY_DIV: return false;
- case EXPR_BINARY_MOD: return false;
- case EXPR_BINARY_EQUAL: return false;
- case EXPR_BINARY_NOTEQUAL: return false;
- case EXPR_BINARY_LESS: return false;
- case EXPR_BINARY_LESSEQUAL: return false;
- case EXPR_BINARY_GREATER: return false;
- case EXPR_BINARY_GREATEREQUAL: return false;
- case EXPR_BINARY_BITWISE_AND: return false;
- case EXPR_BINARY_BITWISE_OR: return false;
- case EXPR_BINARY_BITWISE_XOR: return false;
- case EXPR_BINARY_SHIFTLEFT: return false;
- case EXPR_BINARY_SHIFTRIGHT: return false;
- case EXPR_BINARY_ASSIGN: return true;
- case EXPR_BINARY_MUL_ASSIGN: return true;
- case EXPR_BINARY_DIV_ASSIGN: return true;
- case EXPR_BINARY_MOD_ASSIGN: return true;
- case EXPR_BINARY_ADD_ASSIGN: return true;
- case EXPR_BINARY_SUB_ASSIGN: return true;
- case EXPR_BINARY_SHIFTLEFT_ASSIGN: return true;
- case EXPR_BINARY_SHIFTRIGHT_ASSIGN: return true;
- case EXPR_BINARY_BITWISE_AND_ASSIGN: return true;
- case EXPR_BINARY_BITWISE_XOR_ASSIGN: return true;
- case EXPR_BINARY_BITWISE_OR_ASSIGN: return true;
+ case EXPR_UNARY_CAST_IMPLICIT: return true;
+ case EXPR_UNARY_ASSUME: return true;
+ case EXPR_UNARY_DELETE: return true;
+ case EXPR_UNARY_DELETE_ARRAY: return true;
+ case EXPR_UNARY_THROW: return true;
+
+ case EXPR_BINARY_ADD: return false;
+ case EXPR_BINARY_SUB: return false;
+ case EXPR_BINARY_MUL: return false;
+ case EXPR_BINARY_DIV: return false;
+ case EXPR_BINARY_MOD: return false;
+ case EXPR_BINARY_EQUAL: return false;
+ case EXPR_BINARY_NOTEQUAL: return false;
+ case EXPR_BINARY_LESS: return false;
+ case EXPR_BINARY_LESSEQUAL: return false;
+ case EXPR_BINARY_GREATER: return false;
+ case EXPR_BINARY_GREATEREQUAL: return false;
+ case EXPR_BINARY_BITWISE_AND: return false;
+ case EXPR_BINARY_BITWISE_OR: return false;
+ case EXPR_BINARY_BITWISE_XOR: return false;
+ case EXPR_BINARY_SHIFTLEFT: return false;
+ case EXPR_BINARY_SHIFTRIGHT: return false;
+ case EXPR_BINARY_ASSIGN: return true;
+ case EXPR_BINARY_MUL_ASSIGN: return true;
+ case EXPR_BINARY_DIV_ASSIGN: return true;
+ case EXPR_BINARY_MOD_ASSIGN: return true;
+ case EXPR_BINARY_ADD_ASSIGN: return true;
+ case EXPR_BINARY_SUB_ASSIGN: return true;
+ case EXPR_BINARY_SHIFTLEFT_ASSIGN: return true;
+ case EXPR_BINARY_SHIFTRIGHT_ASSIGN: return true;
+ case EXPR_BINARY_BITWISE_AND_ASSIGN: return true;
+ case EXPR_BINARY_BITWISE_XOR_ASSIGN: return true;
+ case EXPR_BINARY_BITWISE_OR_ASSIGN: return true;
/* Only examine the right hand side of && and ||, because the left hand
* side already has the effect of controlling the execution of the right
case EXPR_BINARY_COMMA:
return expression_has_effect(expr->binary.right);
- case EXPR_BINARY_ISGREATER: return false;
- case EXPR_BINARY_ISGREATEREQUAL: return false;
- case EXPR_BINARY_ISLESS: return false;
- case EXPR_BINARY_ISLESSEQUAL: return false;
- case EXPR_BINARY_ISLESSGREATER: return false;
- case EXPR_BINARY_ISUNORDERED: return false;
+ case EXPR_BINARY_ISGREATER: return false;
+ case EXPR_BINARY_ISGREATEREQUAL: return false;
+ case EXPR_BINARY_ISLESS: return false;
+ case EXPR_BINARY_ISLESSEQUAL: return false;
+ case EXPR_BINARY_ISLESSGREATER: return false;
+ case EXPR_BINARY_ISUNORDERED: return false;
}
internal_errorf(HERE, "unexpected expression");
S(_ALL, __builtin_huge_val)
S(_ALL, __builtin_return_address)
S(_ALL, __builtin_frame_address)
+S(_ALL, __builtin_types_compatible_p)
S(_ALL, __PRETTY_FUNCTION__)
S(_ALL, __FUNCTION__)
S(_ALL, __label__)
case EXPR_VA_START:
case EXPR_VA_ARG:
case EXPR_LABEL_ADDRESS:
+ case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
break;
}