diff options
author | Martynas Venckus <martynas@cvs.openbsd.org> | 2015-07-27 19:50:42 +0000 |
---|---|---|
committer | Martynas Venckus <martynas@cvs.openbsd.org> | 2015-07-27 19:50:42 +0000 |
commit | bfc433f02dd6c3421516562c59fc3160f92f9db0 (patch) | |
tree | d5e83f1ee9e389e72c5e65f0bdf290c117dcd3c8 /gnu | |
parent | ac36018a8fbeb201bfa7cd3ead5e026fdc1f1ba2 (diff) |
Implement support for __builtin_complex() to construct complex values,
required by the upcoming libm work.
OK miod@.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/gcc/gcc/c-common.h | 2 | ||||
-rw-r--r-- | gnu/gcc/gcc/c-parser.c | 40 |
2 files changed, 41 insertions, 1 deletions
diff --git a/gnu/gcc/gcc/c-common.h b/gnu/gcc/gcc/c-common.h index 60b8a82f339..80311e62137 100644 --- a/gnu/gcc/gcc/c-common.h +++ b/gnu/gcc/gcc/c-common.h @@ -71,7 +71,7 @@ enum rid /* C extensions */ RID_ASM, RID_TYPEOF, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG, RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, - RID_TYPES_COMPATIBLE_P, + RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, /* Too many ways of getting the name of a function as a string */ diff --git a/gnu/gcc/gcc/c-parser.c b/gnu/gcc/gcc/c-parser.c index c6be63918f6..e8dabcea47a 100644 --- a/gnu/gcc/gcc/c-parser.c +++ b/gnu/gcc/gcc/c-parser.c @@ -109,6 +109,7 @@ static const struct resword reswords[] = { "__attribute", RID_ATTRIBUTE, 0 }, { "__attribute__", RID_ATTRIBUTE, 0 }, { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 }, + { "__builtin_complex", RID_BUILTIN_COMPLEX, 0 }, { "__builtin_offsetof", RID_OFFSETOF, 0 }, { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 }, { "__builtin_va_arg", RID_VA_ARG, 0 }, @@ -5017,6 +5018,7 @@ c_parser_alignof_expression (c_parser *parser) assignment-expression , assignment-expression ) __builtin_types_compatible_p ( type-name , type-name ) + __builtin_complex ( assignment-expression , assignment-expression ) offsetof-member-designator: identifier @@ -5403,6 +5405,44 @@ c_parser_postfix_expression (c_parser *parser) expr.original_code = ERROR_MARK; } break; + case RID_BUILTIN_COMPLEX: + c_parser_consume_token (parser); + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + { + expr.value = error_mark_node; + break; + } + e1 = c_parser_expr_no_commas (parser, NULL); + if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) + { + expr.value = error_mark_node; + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + break; + } + e2 = c_parser_expr_no_commas (parser, NULL); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1.value)) + || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2.value)) + || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1.value)) + || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2.value))) + { + error ("%<__builtin_complex%> operand not of real binary " + "floating-point type"); + expr.value = error_mark_node; + break; + } + if (TYPE_MAIN_VARIANT (TREE_TYPE (e1.value)) != + TYPE_MAIN_VARIANT (TREE_TYPE (e2.value))) + { + error ("%<__builtin_complex%> operands of different types"); + expr.value = error_mark_node; + break; + } + expr.value = build2 (COMPLEX_EXPR, build_complex_type ( + TYPE_MAIN_VARIANT (TREE_TYPE (e1.value))), + e1.value, e2.value); + break; default: c_parser_error (parser, "expected expression"); expr.value = error_mark_node; |