diff options
author | Jason Merrill <jason@redhat.com> | 2001-08-24 08:07:46 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2001-08-24 08:07:46 -0400 |
commit | 0213a355281c1ce387d9fae4061d18f6b9bcd54e (patch) | |
tree | adef91f04544976faec6a008d13e5bd087582d2d /gcc/c-common.c | |
parent | 2dc8352c90590135507210ce0638d31eaec88d0e (diff) | |
download | gcc-0213a355281c1ce387d9fae4061d18f6b9bcd54e.zip gcc-0213a355281c1ce387d9fae4061d18f6b9bcd54e.tar.gz gcc-0213a355281c1ce387d9fae4061d18f6b9bcd54e.tar.bz2 |
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
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 80 |
1 files changed, 80 insertions, 0 deletions
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. */ |