summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorMartynas Venckus <martynas@cvs.openbsd.org>2015-07-27 19:50:42 +0000
committerMartynas Venckus <martynas@cvs.openbsd.org>2015-07-27 19:50:42 +0000
commitbfc433f02dd6c3421516562c59fc3160f92f9db0 (patch)
treed5e83f1ee9e389e72c5e65f0bdf290c117dcd3c8 /gnu
parentac36018a8fbeb201bfa7cd3ead5e026fdc1f1ba2 (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.h2
-rw-r--r--gnu/gcc/gcc/c-parser.c40
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;