aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2001-08-24 08:07:46 -0400
committerJason Merrill <jason@gcc.gnu.org>2001-08-24 08:07:46 -0400
commit0213a355281c1ce387d9fae4061d18f6b9bcd54e (patch)
treeadef91f04544976faec6a008d13e5bd087582d2d /gcc/c-common.c
parent2dc8352c90590135507210ce0638d31eaec88d0e (diff)
downloadgcc-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.c80
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. */