This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Thanks in advance for your (constructive ;) comments, Paolo.
Index: cp/cp-tree.def =================================================================== --- cp/cp-tree.def (revision 122814) +++ cp/cp-tree.def (working copy) @@ -422,6 +422,12 @@ index is a machine integer. */ DEFTREECODE (ARGUMENT_PACK_SELECT, "argument_pack_select", tcc_exceptional, 0) +/** C++ extensions. */ + +/* Represents a trait expression during template expansion. Operand 0 + is the kind of trait. Operand 1 the queried type. */ +DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_expression, 2) + /* Local variables: mode:c Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 122814) +++ cp/cp-tree.h (working copy) @@ -481,6 +481,20 @@ int index; }; +/* The different kinds of traits that we encounter. */ + +typedef enum cp_trait_kind +{ + CP_HAS_TRIVIAL_DESTRUCTOR, + CP_IS_CLASS, + CP_IS_EMPTY, + CP_IS_POD, + CP_IS_UNION +} cp_trait_kind; + +#define TRAIT_EXPR_KIND(NODE) \ + ((cp_trait_kind)TREE_INT_CST_LOW (TREE_OPERAND (TRAIT_EXPR_CHECK (NODE), 0))) + enum cp_tree_node_structure_enum { TS_CP_GENERIC, TS_CP_IDENTIFIER, @@ -4553,6 +4567,7 @@ extern tree baselink_for_fns (tree); extern void finish_static_assert (tree, tree, location_t, bool); +extern tree finish_trait_expr (enum cp_trait_kind, tree); /* in tree.c */ extern void lang_check_failed (const char *, int, Index: cp/pt.c =================================================================== --- cp/pt.c (revision 122814) +++ cp/pt.c (working copy) @@ -10667,6 +10667,10 @@ case OFFSETOF_EXPR: return finish_offsetof (RECUR (TREE_OPERAND (t, 0))); + case TRAIT_EXPR: + return finish_trait_expr (TRAIT_EXPR_KIND (t), + RECUR (TREE_OPERAND (t, 1))); + case STMT_EXPR: { tree old_stmt_expr = cur_stmt_expr; @@ -14852,6 +14856,9 @@ return false; } + case TRAIT_EXPR: + return dependent_type_p (TREE_OPERAND (expression, 1)); + default: /* A constant expression is value-dependent if any subexpression is value-dependent. */ @@ -14915,6 +14922,7 @@ if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR || TREE_CODE (expression) == SIZEOF_EXPR || TREE_CODE (expression) == ALIGNOF_EXPR + || TREE_CODE (expression) == TRAIT_EXPR || TREE_CODE (expression) == TYPEID_EXPR || TREE_CODE (expression) == DELETE_EXPR || TREE_CODE (expression) == VEC_DELETE_EXPR Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 122814) +++ cp/semantics.c (working copy) @@ -4000,4 +4000,56 @@ } } +/* Process a trait expression. */ + +tree +finish_trait_expr (cp_trait_kind kind, tree type) +{ + bool value = false; + enum tree_code type_code; + + gcc_assert (kind == CP_HAS_TRIVIAL_DESTRUCTOR + || kind == CP_IS_CLASS + || kind == CP_IS_EMPTY + || kind == CP_IS_POD + || kind == CP_IS_UNION); + + if (type == error_mark_node) + return error_mark_node; + + if (processing_template_decl) + return build2 (TRAIT_EXPR, boolean_type_node, + build_int_cst (NULL_TREE, kind), type); + + type_code = TREE_CODE (type); + + switch (kind) + { + case CP_HAS_TRIVIAL_DESTRUCTOR: + if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type)) + value = true; + break; + case CP_IS_CLASS: + if (CLASS_TYPE_P (type) && type_code != UNION_TYPE) + value = true; + break; + case CP_IS_EMPTY: + if (CLASS_TYPE_P (type) && CLASSTYPE_EMPTY_P (type)) + value = true; + break; + case CP_IS_POD: + if (pod_type_p (type)) + value = true; + break; + case CP_IS_UNION: + if (type_code == UNION_TYPE) + value = true; + break; + default: + gcc_unreachable (); + } + + return value ? boolean_true_node : boolean_false_node; +} + #include "gt-cp-semantics.h" Index: cp/lex.c =================================================================== --- cp/lex.c (revision 122814) +++ cp/lex.c (working copy) @@ -199,6 +199,11 @@ { "__const__", RID_CONST, 0 }, { "__extension__", RID_EXTENSION, 0 }, { "__func__", RID_C99_FUNCTION_NAME, 0 }, + { "__gnu_has_trivial_destructor", RID_GNU_HAS_TRIVIAL_DESTRUCTOR, 0 }, + { "__gnu_is_class", RID_GNU_IS_CLASS, 0 }, + { "__gnu_is_empty", RID_GNU_IS_EMPTY, 0 }, + { "__gnu_is_pod", RID_GNU_IS_POD, 0 }, + { "__gnu_is_union", RID_GNU_IS_UNION, 0 }, { "__imag", RID_IMAGPART, 0 }, { "__imag__", RID_IMAGPART, 0 }, { "__inline", RID_INLINE, 0 }, Index: cp/parser.c =================================================================== --- cp/parser.c (revision 122814) +++ cp/parser.c (working copy) @@ -1895,6 +1895,8 @@ (cp_parser *, tree); static tree cp_parser_sizeof_operand (cp_parser *, enum rid); +static tree cp_parser_trait_expr + (cp_parser *, enum rid); static bool cp_parser_declares_only_class_p (cp_parser *); static void cp_parser_set_storage_class @@ -2956,6 +2958,13 @@ __builtin_va_arg ( assignment-expression , type-id ) __builtin_offsetof ( type-id , offsetof-expression ) + C++ Extensions: + __gnu_has_trivial_destructor ( type-id ) + __gnu_is_class ( type-id ) + __gnu_is_empty ( type-id ) + __gnu_is_pod ( type-id ) + __gnu_is_union ( type-id ) + Objective-C++ Extension: primary-expression: @@ -3193,7 +3202,14 @@ case RID_OFFSETOF: return cp_parser_builtin_offsetof (parser); - /* Objective-C++ expressions. */ + case RID_GNU_HAS_TRIVIAL_DESTRUCTOR: + case RID_GNU_IS_CLASS: + case RID_GNU_IS_EMPTY: + case RID_GNU_IS_POD: + case RID_GNU_IS_UNION: + return cp_parser_trait_expr (parser, token->keyword); + + /* Objective-C++ expressions. */ case RID_AT_ENCODE: case RID_AT_PROTOCOL: case RID_AT_SELECTOR: @@ -6273,6 +6289,58 @@ return expr; } +/* Parse a trait expression. */ + +static tree +cp_parser_trait_expr (cp_parser* parser, enum rid keyword) +{ + cp_trait_kind kind; + tree type; + cp_decl_specifier_seq decl_specs; + + switch (keyword) + { + case RID_GNU_HAS_TRIVIAL_DESTRUCTOR: + kind = CP_HAS_TRIVIAL_DESTRUCTOR; + break; + case RID_GNU_IS_CLASS: + kind = CP_IS_CLASS; + break; + case RID_GNU_IS_EMPTY: + kind = CP_IS_EMPTY; + break; + case RID_GNU_IS_POD: + kind = CP_IS_POD; + break; + case RID_GNU_IS_UNION: + kind = CP_IS_UNION; + break; + default: + gcc_unreachable (); + } + + /* Consume the token. */ + cp_lexer_consume_token (parser->lexer); + + cp_parser_require (parser, CPP_OPEN_PAREN, "`('"); + + type = cp_parser_type_id (parser); + + cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); + + /* Build a trivial decl-specifier-seq. */ + clear_decl_specs (&decl_specs); + decl_specs.type = type; + + /* Call grokdeclarator to figure out what type this is. */ + type = grokdeclarator (NULL, &decl_specs, TYPENAME, + /*initialized=*/0, /*attrlist=*/NULL); + + /* Complete the trait expr, which may mean either processing the + static assert now or saving it for template instantiation. */ + return finish_trait_expr (kind, type); +} + /* Statements [gram.stmt.stmt] */ /* Parse a statement. Index: c-common.h =================================================================== --- c-common.h (revision 122814) +++ c-common.h (working copy) @@ -90,6 +90,11 @@ /* casts */ RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, + /* C++ extensions */ + RID_GNU_HAS_TRIVIAL_DESTRUCTOR, + RID_GNU_IS_CLASS, RID_GNU_IS_EMPTY, RID_GNU_IS_POD, + RID_GNU_IS_UNION, + /* C++0x */ RID_STATIC_ASSERT,
Attachment:
Tests.tar
Description: Binary data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |