[PATCH 02/14] Support for adding and stripping location_t wrapper nodes
David Malcolm
dmalcolm@redhat.com
Fri Nov 10 21:43:00 GMT 2017
This patch provides a mechanism in tree.c for adding a wrapper node
for expressing a location_t, for those nodes for which
!CAN_HAVE_LOCATION_P, along with a new method of cp_expr.
It's called in later patches in the kit via that new method.
In this version of the patch, I use NON_LVALUE_EXPR for wrapping
constants, and VIEW_CONVERT_EXPR for other nodes.
I also turned off wrapper nodes for EXCEPTIONAL_CLASS_P, for the sake
of keeping the patch kit more minimal.
The patch also adds a STRIP_ANY_LOCATION_WRAPPER macro for stripping
such nodes, used later on in the patch kit.
gcc/ChangeLog:
PR c++/43486
* tree.c (maybe_wrap_with_location): New function.
* tree.h (STRIP_ANY_LOCATION_WRAPPER): New macro.
(maybe_wrap_with_location): New decl.
(location_wrapper_p): New inline function.
gcc/cp/ChangeLog:
PR c++/43486
* cp-tree.h (cp_expr::maybe_add_location_wrapper): New method.
---
gcc/cp/cp-tree.h | 6 ++++++
gcc/tree.c | 27 +++++++++++++++++++++++++++
gcc/tree.h | 26 ++++++++++++++++++++++++++
3 files changed, 59 insertions(+)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 874cbcb..726b6f5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -93,6 +93,12 @@ public:
set_location (make_location (m_loc, start, finish));
}
+ cp_expr& maybe_add_location_wrapper ()
+ {
+ m_value = maybe_wrap_with_location (m_value, m_loc);
+ return *this;
+ }
+
private:
tree m_value;
location_t m_loc;
diff --git a/gcc/tree.c b/gcc/tree.c
index 28e157f..50c818c 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -13747,6 +13747,33 @@ set_source_range (tree expr, source_range src_range)
return adhoc;
}
+/* Return EXPR, potentially wrapped with a LOCATION_WRAPPER_EXPR node
+ at LOC, if !CAN_HAVE_LOCATION_P (expr). */
+
+tree
+maybe_wrap_with_location (tree expr, location_t loc)
+{
+ if (expr == NULL)
+ return NULL;
+ if (loc == UNKNOWN_LOCATION)
+ return expr;
+ if (CAN_HAVE_LOCATION_P (expr))
+ return expr;
+ /* We should only be adding wrappers for constants and for decls,
+ or for some exceptional tree nodes (e.g. BASELINK in the C++ FE). */
+ gcc_assert (CONSTANT_CLASS_P (expr)
+ || DECL_P (expr)
+ || EXCEPTIONAL_CLASS_P (expr));
+
+ if (EXCEPTIONAL_CLASS_P (expr))
+ return expr;
+
+ if (CONSTANT_CLASS_P (expr))
+ return build1_loc (loc, NON_LVALUE_EXPR, TREE_TYPE (expr), expr);
+ else
+ return build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
+}
+
/* Return the name of combined function FN, for debugging purposes. */
const char *
diff --git a/gcc/tree.h b/gcc/tree.h
index 277aa91..fb45a8d 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -483,6 +483,15 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define STRIP_USELESS_TYPE_CONVERSION(EXP) \
(EXP) = tree_ssa_strip_useless_type_conversions (EXP)
+/* Remove any VIEW_CONVERT_EXPR or NON_LVALUE_EXPR that's purely
+ in use to provide a location_t. */
+
+#define STRIP_ANY_LOCATION_WRAPPER(EXP) \
+ do { \
+ if (location_wrapper_p (EXP)) \
+ (EXP) = TREE_OPERAND ((EXP), 0); \
+ } while (0)
+
/* Nonzero if TYPE represents a vector type. */
#define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE)
@@ -1147,6 +1156,8 @@ get_expr_source_range (tree expr)
extern void protected_set_expr_location (tree, location_t);
+extern tree maybe_wrap_with_location (tree, location_t);
+
/* In a TARGET_EXPR node. */
#define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0)
#define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1)
@@ -3637,6 +3648,21 @@ id_equal (const char *str, const_tree id)
return !strcmp (str, IDENTIFIER_POINTER (id));
}
+/* Test if EXP is merely a wrapper node, added to express a location_t
+ on behalf of its child. */
+
+inline bool location_wrapper_p (const_tree exp)
+{
+ if (((TREE_CODE (exp) == NON_LVALUE_EXPR
+ && CONSTANT_CLASS_P (TREE_OPERAND (exp, 0)))
+ || (TREE_CODE (exp) == VIEW_CONVERT_EXPR
+ && !CONSTANT_CLASS_P (TREE_OPERAND (exp, 0))))
+ && (TREE_TYPE (exp)
+ == TREE_TYPE (TREE_OPERAND (exp, 0))))
+ return true;
+ return false;
+}
+
#define error_mark_node global_trees[TI_ERROR_MARK]
#define intQI_type_node global_trees[TI_INTQI_TYPE]
--
1.8.5.3
More information about the Gcc-patches
mailing list