[llvm-commits] CVS: llvm-gcc/gcc/c-common.h c-common.c
Chris Lattner
lattner at cs.uiuc.edu
Sat Mar 5 10:49:37 PST 2005
Changes in directory llvm-gcc/gcc:
c-common.h updated: 1.4 -> 1.5
c-common.c updated: 1.8 -> 1.9
---
Log message:
implement new fold-offsetof and getbaseaddress functions.
---
Diffs of the changes: (+95 -0)
c-common.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
c-common.h | 2 +
2 files changed, 95 insertions(+)
Index: llvm-gcc/gcc/c-common.h
diff -u llvm-gcc/gcc/c-common.h:1.4 llvm-gcc/gcc/c-common.h:1.5
--- llvm-gcc/gcc/c-common.h:1.4 Mon Feb 14 15:24:32 2005
+++ llvm-gcc/gcc/c-common.h Sat Mar 5 12:49:20 2005
@@ -1306,6 +1306,8 @@
extern bool c_dump_tree (void *, tree);
+extern tree fold_offsetof (tree);
+
extern void pch_init (void);
extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd);
extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd,
Index: llvm-gcc/gcc/c-common.c
diff -u llvm-gcc/gcc/c-common.c:1.8 llvm-gcc/gcc/c-common.c:1.9
--- llvm-gcc/gcc/c-common.c:1.8 Mon Feb 14 15:24:32 2005
+++ llvm-gcc/gcc/c-common.c Sat Mar 5 12:49:21 2005
@@ -5566,6 +5566,99 @@
return NULL_TREE;
}
+
+
+
+/* Given a memory reference expression T, return its base address.
+ The base address of a memory reference expression is the main
+ object being referenced. For instance, the base address for
+ 'array[i].fld[j]' is 'array'. You can think of this as stripping
+ away the offset part from a memory address.
+
+ This function calls handled_component_p to strip away all the inner
+ parts of the memory reference until it reaches the base object. */
+
+tree
+get_base_address (tree t)
+{
+ while (handled_component_p (t))
+ t = TREE_OPERAND (t, 0);
+
+ if (TREE_CODE (t) == STRING_CST
+ || TREE_CODE (t) == CONSTRUCTOR
+ || TREE_CODE (t) == INDIRECT_REF)
+ return t;
+ else
+ return NULL_TREE;
+}
+
+
+/* Build the result of __builtin_offsetof. EXPR is a nested sequence of
+ component references, with an INDIRECT_REF at the bottom; much like
+ the traditional rendering of offsetof as a macro. Returns the folded
+ and properly cast result. */
+
+static tree
+fold_offsetof_1 (tree expr)
+{
+ enum tree_code code = PLUS_EXPR;
+ tree base, off, t;
+
+ switch (TREE_CODE (expr))
+ {
+ case ERROR_MARK:
+ return expr;
+
+ case INDIRECT_REF:
+ return size_zero_node;
+
+ case COMPONENT_REF:
+ base = fold_offsetof_1 (TREE_OPERAND (expr, 0));
+ if (base == error_mark_node)
+ return base;
+
+ t = TREE_OPERAND (expr, 1);
+ if (DECL_C_BIT_FIELD (t))
+ {
+ error ("attempt to take address of bit-field structure "
+ "member %qs", IDENTIFIER_POINTER (DECL_NAME (t)));
+ return error_mark_node;
+ }
+ off = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (t),
+ size_int (tree_low_cst (DECL_FIELD_BIT_OFFSET (t), 1)
+ / BITS_PER_UNIT));
+ break;
+
+ case ARRAY_REF:
+ base = fold_offsetof_1 (TREE_OPERAND (expr, 0));
+ if (base == error_mark_node)
+ return base;
+
+ t = TREE_OPERAND (expr, 1);
+ if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) < 0)
+ {
+ code = MINUS_EXPR;
+ t = fold (build1 (NEGATE_EXPR, TREE_TYPE (t), t));
+ }
+ t = convert (sizetype, t);
+ off = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (expr)), t);
+ break;
+
+ default:
+ abort ();
+ }
+
+ return size_binop (code, base, off);
+}
+
+tree
+fold_offsetof (tree expr)
+{
+ /* Convert back from the internal sizetype to size_t. */
+ return convert (size_type_node, fold_offsetof_1 (expr));
+}
+
+
/* Check for valid arguments being passed to a function. */
void
More information about the llvm-commits
mailing list