From 0213a355281c1ce387d9fae4061d18f6b9bcd54e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 24 Aug 2001 08:07:46 -0400 Subject: c-common.c (c_alignof, [...]): Move here... * c-common.c (c_alignof, c_alignof_expr): Move here... * c-typeck.c: ...from here. * c-tree.h, c-common.h: Adjust. * tree.c (cp_build_qualified_type_real): Use get_qualified_type. (build_cplus_array_type): Use cp_build_qualified_type, not TYPE_MAIN_VARIANT, to get an unqualified version. * decl2.c (grok_alignof): Lose. (build_expr_from_tree): Use expr_sizeof and c_alignof_expr. * typeck.c (c_alignof): Lose. * semantics.c (finish_sizeof, finish_alignof): New. * parse.y: Use them. * cp-tree.h: Declare them. From-SVN: r45145 --- gcc/c-common.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'gcc/c-common.c') diff --git a/gcc/c-common.c b/gcc/c-common.c index 8fe6e53..84a9262 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2851,7 +2851,87 @@ lang_get_alias_set (t) return -1; } + +/* Implement the __alignof keyword: Return the minimum required + alignment of TYPE, measured in bytes. */ + +tree +c_alignof (type) + tree type; +{ + enum tree_code code = TREE_CODE (type); + tree t; + /* In C++, sizeof applies to the referent. Handle alignof the same way. */ + if (code == REFERENCE_TYPE) + { + type = TREE_TYPE (type); + code = TREE_CODE (type); + } + + if (code == FUNCTION_TYPE) + t = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); + else if (code == VOID_TYPE || code == ERROR_MARK) + t = size_one_node; + else if (!COMPLETE_TYPE_P (type)) + { + error ("__alignof__ applied to an incomplete type"); + t = size_zero_node; + } + else + t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT); + + return fold (build1 (NOP_EXPR, c_size_type_node, t)); +} + +/* Implement the __alignof keyword: Return the minimum required + alignment of EXPR, measured in bytes. For VAR_DECL's and + FIELD_DECL's return DECL_ALIGN (which can be set from an + "aligned" __attribute__ specification). */ + +tree +c_alignof_expr (expr) + tree expr; +{ + tree t; + + if (TREE_CODE (expr) == VAR_DECL) + t = size_int (DECL_ALIGN (expr) / BITS_PER_UNIT); + + else if (TREE_CODE (expr) == COMPONENT_REF + && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) + { + error ("`__alignof' applied to a bit-field"); + t = size_one_node; + } + else if (TREE_CODE (expr) == COMPONENT_REF + && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL) + t = size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT); + + else if (TREE_CODE (expr) == INDIRECT_REF) + { + tree t = TREE_OPERAND (expr, 0); + tree best = t; + int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); + + while (TREE_CODE (t) == NOP_EXPR + && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE) + { + int thisalign; + + t = TREE_OPERAND (t, 0); + thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); + if (thisalign > bestalign) + best = t, bestalign = thisalign; + } + return c_alignof (TREE_TYPE (TREE_TYPE (best))); + } + else + return c_alignof (TREE_TYPE (expr)); + + return fold (build1 (NOP_EXPR, c_size_type_node, t)); +} + /* Build tree nodes and builtin functions common to both C and C++ language frontends. */ -- cgit v1.1