From 9ae1d0a1507fcb593d158372af58ab96ac1d05da Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 23 Nov 2015 12:04:52 -0500
Subject: [PATCH 08/35] FIXME: WIP: 1st part of c++ rewrite

---
 gcc/cp/cp-tree.h     |  98 +++------------------------
 gcc/cp/name-lookup.c |   6 +-
 gcc/cp/name-lookup.h |   2 +-
 gcc/cp/parser.c      | 183 ++++++++++++++++++++++++---------------------------
 gcc/cp/semantics.c   |  26 ++++----
 gcc/cp/typeck.c      |  43 +++++-------
 gcc/tree.h           |  30 +++++++++
 7 files changed, 155 insertions(+), 233 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 542cdfc..160bf1e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -40,86 +40,6 @@ c-common.h, not after.
 #include "c-family/c-common.h"
 #include "diagnostic.h"
 
-/* A tree node, together with a location, so that we can track locations
-   (and ranges) during parsing.
-
-   The location is redundant for node kinds that have locations,
-   but not all node kinds do (e.g. constants, and references to
-   params, locals, etc), so we stash a copy here.  */
-
-class cp_expr
-{
-public:
-  cp_expr () :
-    m_value (NULL), m_loc (UNKNOWN_LOCATION) {}
-
-  cp_expr (tree value) :
-    m_value (value), m_loc (EXPR_LOCATION (m_value))
-  {
-#if 0
-    /* FIXME: various assertions can be put in here when debugging,
-       for tracking down where location information gets thrown
-       away (during a trip through a purely "tree" value).  */
-    if (m_value && m_value != error_mark_node)
-      {
-	if (TREE_CODE (m_value) == FUNCTION_DECL)
-	  return; // for now
-	gcc_assert (CAN_HAVE_LOCATION_P (m_value));
-	//gcc_assert (m_loc != UNKNOWN_LOCATION);
-      }
-#endif
-  }
-
-  cp_expr (tree value, location_t loc):
-    m_value (value), m_loc (loc)
-  {
-    if (m_value)
-      gcc_assert (m_loc != UNKNOWN_LOCATION);
-  }
-
-  cp_expr (const cp_expr &other) :
-    m_value (other.m_value), m_loc (other.m_loc) {}
-
-  /* Implicit conversions to tree.  */
-  operator tree () const { return m_value; }
-  tree & operator* () { return m_value; }
-  tree & operator-> () { return m_value; }
-
-  tree get_value () const { return m_value; }
-  location_t get_location () const { return m_loc; }
-  location_t get_start () const
-  {
-    source_range src_range = get_range_from_loc (line_table, m_loc);
-    return src_range.m_start;
-  }
-  location_t get_finish () const
-  {
-    source_range src_range = get_range_from_loc (line_table, m_loc);
-    return src_range.m_finish;
-  }
-
-  void set_location (location_t loc)
-  {
-    protected_set_expr_location (m_value, loc);
-    m_loc = loc;
-  }
-
-  void set_range (location_t start, location_t finish)
-  {
-    m_loc = set_source_range (m_value, start, finish);
-  }
-
- private:
-  tree m_value;
-  location_t m_loc;
-};
-
-inline bool
-operator == (const cp_expr &lhs, tree rhs)
-{
-  return lhs.get_value () == rhs;
-}
-
 #include "name-lookup.h"
 
 /* Usage of TREE_LANG_FLAG_?:
@@ -6368,15 +6288,15 @@ extern tree finish_stmt_expr_expr		(tree, tree);
 extern tree finish_stmt_expr			(tree, bool);
 extern tree stmt_expr_value_expr		(tree);
 bool empty_expr_stmt_p				(tree);
-extern cp_expr perform_koenig_lookup		(cp_expr, vec<tree, va_gc> *,
+extern tree perform_koenig_lookup		(tree, vec<tree, va_gc> *,
 						 tsubst_flags_t);
 extern tree finish_call_expr			(tree, vec<tree, va_gc> **, bool,
 						 bool, tsubst_flags_t);
 extern tree finish_template_variable		(tree, tsubst_flags_t = tf_warning_or_error);
-extern cp_expr finish_increment_expr		(cp_expr, enum tree_code);
+extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr       (tree, tree, tree, location_t);
-extern cp_expr finish_unary_op_expr		(location_t, enum tree_code, cp_expr,
+extern tree finish_unary_op_expr		(location_t, enum tree_code, tree,
 						 tsubst_flags_t);
 extern tree finish_compound_literal		(tree, tree, tsubst_flags_t);
 extern tree finish_fname			(tree);
@@ -6390,7 +6310,7 @@ extern tree finish_base_specifier		(tree, tree, bool);
 extern void finish_member_declaration		(tree);
 extern bool outer_automatic_var_p		(tree);
 extern tree process_outer_var_ref		(tree, tsubst_flags_t);
-extern cp_expr finish_id_expression		(tree, tree, tree,
+extern tree finish_id_expression		(tree, tree, tree,
 						 cp_id_kind *,
 						 bool, bool, bool *,
 						 bool, bool, bool, bool,
@@ -6632,9 +6552,9 @@ extern tree unlowered_expr_type                 (const_tree);
 extern tree decay_conversion			(tree,
                                                  tsubst_flags_t,
                                                  bool = true);
-extern tree build_class_member_access_expr      (cp_expr, tree, tree, bool,
+extern tree build_class_member_access_expr      (tree, tree, tree, bool,
 						 tsubst_flags_t);
-extern tree finish_class_member_access_expr     (cp_expr, tree, bool,
+extern tree finish_class_member_access_expr     (tree, tree, bool, 
 						 tsubst_flags_t);
 extern tree build_x_indirect_ref		(location_t, tree,
 						 ref_operator, tsubst_flags_t);
@@ -6656,7 +6576,7 @@ extern tree build_x_binary_op			(location_t,
 extern tree build_x_array_ref			(location_t, tree, tree,
 						 tsubst_flags_t);
 extern tree build_x_unary_op			(location_t,
-						 enum tree_code, cp_expr,
+						 enum tree_code, tree,
                                                  tsubst_flags_t);
 extern tree cp_build_addr_expr			(tree, tsubst_flags_t);
 extern tree cp_build_unary_op                   (enum tree_code, tree, int, 
@@ -6676,10 +6596,8 @@ extern tree build_static_cast			(tree, tree, tsubst_flags_t);
 extern tree build_reinterpret_cast		(tree, tree, tsubst_flags_t);
 extern tree build_const_cast			(tree, tree, tsubst_flags_t);
 extern tree build_c_cast			(location_t, tree, tree);
-extern cp_expr build_c_cast			(location_t loc, tree type,
-						 cp_expr expr);
 extern tree cp_build_c_cast			(tree, tree, tsubst_flags_t);
-extern cp_expr build_x_modify_expr		(location_t, tree,
+extern tree build_x_modify_expr			(location_t, tree,
 						 enum tree_code, tree,
 						 tsubst_flags_t);
 extern tree cp_build_modify_expr		(tree, enum tree_code, tree,
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 86c07ef..cebe57e 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5659,7 +5659,7 @@ arg_assoc (struct arg_lookup *k, tree n)
 /* Performs Koenig lookup depending on arguments, where fns
    are the functions found in normal lookup.  */
 
-static cp_expr
+static tree
 lookup_arg_dependent_1 (tree name, tree fns, vec<tree, va_gc> *args)
 {
   struct arg_lookup k;
@@ -5720,10 +5720,10 @@ lookup_arg_dependent_1 (tree name, tree fns, vec<tree, va_gc> *args)
 
 /* Wrapper for lookup_arg_dependent_1.  */
 
-cp_expr
+tree
 lookup_arg_dependent (tree name, tree fns, vec<tree, va_gc> *args)
 {
-  cp_expr ret;
+  tree ret;
   bool subtime;
   subtime = timevar_cond_start (TV_NAME_LOOKUP);
   ret = lookup_arg_dependent_1 (name, fns, args);
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index d2453e9..d430edb 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -347,7 +347,7 @@ extern void do_toplevel_using_decl (tree, tree, tree);
 extern void do_local_using_decl (tree, tree, tree);
 extern tree do_class_using_decl (tree, tree);
 extern void do_using_directive (tree);
-extern cp_expr lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);
+extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);
 extern bool is_associated_namespace (tree, tree);
 extern void parse_using_directive (tree, tree);
 extern tree innermost_non_namespace_value (tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b180223..427641b 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1785,7 +1785,7 @@ struct cp_parser_expression_stack_entry
 {
   /* Left hand side of the binary operation we are currently
      parsing.  */
-  cp_expr lhs;
+  tree lhs;
   /* Original tree code for left hand side, if it was a binary
      expression itself (used for -Wparentheses).  */
   enum tree_code lhs_type;
@@ -1939,15 +1939,15 @@ static cp_parser *cp_parser_new
 
 /* Lexical conventions [gram.lex]  */
 
-static cp_expr cp_parser_identifier
+static tree cp_parser_identifier
   (cp_parser *);
-static cp_expr cp_parser_string_literal
+static tree cp_parser_string_literal
   (cp_parser *, bool, bool, bool);
-static cp_expr cp_parser_userdef_char_literal
+static tree cp_parser_userdef_char_literal
   (cp_parser *);
 static tree cp_parser_userdef_string_literal
   (tree);
-static cp_expr cp_parser_userdef_numeric_literal
+static tree cp_parser_userdef_numeric_literal
   (cp_parser *);
 
 /* Basic concepts [gram.basic]  */
@@ -1957,11 +1957,11 @@ static bool cp_parser_translation_unit
 
 /* Expressions [gram.expr]  */
 
-static cp_expr cp_parser_primary_expression
+static tree cp_parser_primary_expression
   (cp_parser *, bool, bool, bool, cp_id_kind *);
-static cp_expr cp_parser_id_expression
+static tree cp_parser_id_expression
   (cp_parser *, bool, bool, bool *, bool, bool);
-static cp_expr cp_parser_unqualified_id
+static tree cp_parser_unqualified_id
   (cp_parser *, bool, bool, bool, bool);
 static tree cp_parser_nested_name_specifier_opt
   (cp_parser *, bool, bool, bool, bool);
@@ -1969,19 +1969,19 @@ static tree cp_parser_nested_name_specifier
   (cp_parser *, bool, bool, bool, bool);
 static tree cp_parser_qualifying_entity
   (cp_parser *, bool, bool, bool, bool, bool);
-static cp_expr cp_parser_postfix_expression
+static tree cp_parser_postfix_expression
   (cp_parser *, bool, bool, bool, bool, cp_id_kind *);
 static tree cp_parser_postfix_open_square_expression
   (cp_parser *, tree, bool, bool);
 static tree cp_parser_postfix_dot_deref_expression
-  (cp_parser *, enum cpp_ttype, cp_expr, bool, cp_id_kind *, location_t);
+  (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
 static vec<tree, va_gc> *cp_parser_parenthesized_expression_list
   (cp_parser *, int, bool, bool, bool *, location_t * = NULL);
 /* Values for the second parameter of cp_parser_parenthesized_expression_list.  */
 enum { non_attr = 0, normal_attr = 1, id_attr = 2 };
 static void cp_parser_pseudo_destructor_name
   (cp_parser *, tree, tree *, tree *);
-static cp_expr cp_parser_unary_expression
+static tree cp_parser_unary_expression
   (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
 static enum tree_code cp_parser_unary_operator
   (cp_token *);
@@ -1999,23 +1999,23 @@ static vec<tree, va_gc> *cp_parser_new_initializer
   (cp_parser *);
 static tree cp_parser_delete_expression
   (cp_parser *);
-static cp_expr cp_parser_cast_expression
+static tree cp_parser_cast_expression
   (cp_parser *, bool, bool, bool, cp_id_kind *);
-static cp_expr cp_parser_binary_expression
+static tree cp_parser_binary_expression
   (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *);
 static tree cp_parser_question_colon_clause
-  (cp_parser *, cp_expr);
-static cp_expr cp_parser_assignment_expression
+  (cp_parser *, tree);
+static tree cp_parser_assignment_expression
   (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false);
 static enum tree_code cp_parser_assignment_operator_opt
   (cp_parser *);
-static cp_expr cp_parser_expression
+static tree cp_parser_expression
   (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false);
-static cp_expr cp_parser_constant_expression
+static tree cp_parser_constant_expression
   (cp_parser *, bool = false, bool * = NULL);
 static tree cp_parser_builtin_offsetof
   (cp_parser *);
-static cp_expr cp_parser_lambda_expression
+static tree cp_parser_lambda_expression
   (cp_parser *);
 static void cp_parser_lambda_introducer
   (cp_parser *, tree);
@@ -2170,7 +2170,7 @@ static void cp_parser_function_body
   (cp_parser *, bool);
 static tree cp_parser_initializer
   (cp_parser *, bool *, bool *);
-static cp_expr cp_parser_initializer_clause
+static tree cp_parser_initializer_clause
   (cp_parser *, bool *);
 static tree cp_parser_braced_list
   (cp_parser*, bool*);
@@ -2238,9 +2238,9 @@ static tree cp_parser_mem_initializer_id
 
 /* Overloading [gram.over] */
 
-static cp_expr cp_parser_operator_function_id
+static tree cp_parser_operator_function_id
   (cp_parser *);
-static cp_expr cp_parser_operator
+static tree cp_parser_operator
   (cp_parser *);
 
 /* Templates [gram.temp] */
@@ -2411,7 +2411,7 @@ static tree cp_parser_objc_struct_declaration
 
 /* Utility Routines */
 
-static cp_expr cp_parser_lookup_name
+static tree cp_parser_lookup_name
   (cp_parser *, tree, enum tag_types, bool, bool, bool, tree *, location_t);
 static tree cp_parser_lookup_name_simple
   (cp_parser *, tree, location_t);
@@ -2421,7 +2421,7 @@ static bool cp_parser_check_declarator_template_parameters
   (cp_parser *, cp_declarator *, location_t);
 static bool cp_parser_check_template_parameters
   (cp_parser *, unsigned, location_t, cp_declarator *);
-static cp_expr cp_parser_simple_cast_expression
+static tree cp_parser_simple_cast_expression
   (cp_parser *);
 static tree cp_parser_global_scope_opt
   (cp_parser *, bool);
@@ -3670,7 +3670,7 @@ cp_parser_pop_lexer (cp_parser *parser)
 /* Parse an identifier.  Returns an IDENTIFIER_NODE representing the
    identifier.  */
 
-static cp_expr
+static tree
 cp_parser_identifier (cp_parser* parser)
 {
   cp_token *token;
@@ -3698,7 +3698,7 @@ cp_parser_identifier (cp_parser* parser)
    This code is largely lifted from lex_string() in c-lex.c.
 
    FUTURE: ObjC++ will need to handle @-strings here.  */
-static cp_expr
+static tree
 cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
 			  bool lookup_udlit = true)
 {
@@ -3930,7 +3930,7 @@ lookup_literal_operator (tree name, vec<tree, va_gc> *args)
 /* Parse a user-defined char constant.  Returns a call to a user-defined
    literal operator taking the character as an argument.  */
 
-static cp_expr
+static tree
 cp_parser_userdef_char_literal (cp_parser *parser)
 {
   cp_token *token = cp_lexer_consume_token (parser->lexer);
@@ -4022,7 +4022,7 @@ make_string_pack (tree value)
 /* Parse a user-defined numeric constant.  returns a call to a user-defined
    literal operator.  */
 
-static cp_expr
+static tree
 cp_parser_userdef_numeric_literal (cp_parser *parser)
 {
   cp_token *token = cp_lexer_consume_token (parser->lexer);
@@ -4423,7 +4423,7 @@ cp_parser_fold_operator (cp_parser *parser)
 
    Note that the '(' and ')' are matched in primary expression. */
 
-static cp_expr
+static tree
 cp_parser_fold_expression (cp_parser *parser, tree expr1)
 {
   cp_id_kind pidk;
@@ -4543,7 +4543,7 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1)
    Returns a representation of the expression.  Upon return, *IDK
    indicates what kind of id-expression (if any) was present.  */
 
-static cp_expr
+static tree
 cp_parser_primary_expression (cp_parser *parser,
 			      bool address_p,
 			      bool cast_p,
@@ -4686,7 +4686,7 @@ cp_parser_primary_expression (cp_parser *parser,
 	}
       /* Otherwise it's a normal parenthesized expression.  */
       {
-	cp_expr expr;
+	tree expr;
 	bool saved_greater_than_is_operator_p;
 
 	location_t open_paren_loc = token->location;
@@ -4739,7 +4739,7 @@ cp_parser_primary_expression (cp_parser *parser,
 	/* Consume the `)'.  */
 	token = cp_lexer_peek_token (parser->lexer);
 	location_t close_paren_loc = token->location;
-	expr.set_range (open_paren_loc, close_paren_loc);
+        set_source_range (expr, open_paren_loc, close_paren_loc);
 	if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)
 	    && !cp_parser_uncommitted_to_tentative_parse_p (parser))
 	  cp_parser_skip_to_end_of_statement (parser);
@@ -4759,7 +4759,7 @@ cp_parser_primary_expression (cp_parser *parser,
 	      return msg;
 	    /* ... else, fall though to see if it's a lambda.  */
 	  }
-	cp_expr lam = cp_parser_lambda_expression (parser);
+	tree lam = cp_parser_lambda_expression (parser);
 	/* Don't warn about a failed tentative parse.  */
 	if (cp_parser_error_occurred (parser))
 	  return error_mark_node;
@@ -4942,8 +4942,8 @@ cp_parser_primary_expression (cp_parser *parser,
     case CPP_NESTED_NAME_SPECIFIER:
       {
       id_expression:
-	cp_expr id_expression;
-	cp_expr decl;
+	tree id_expression;
+	tree decl;
 	const char *error_msg;
 	bool template_p;
 	bool done;
@@ -5017,20 +5017,8 @@ cp_parser_primary_expression (cp_parser *parser,
 	      }
 
 	    /* In Objective-C++, an instance variable (ivar) may be preferred
-	       to whatever cp_parser_lookup_name() found.
-	       Call objc_lookup_ivar.  To avoid exposing cp_expr to the
-	       rest of c-family, we have to do a little extra work to preserve
-	       any location information in cp_expr "decl".  Given that
-	       objc_lookup_ivar is implemented in "c-family" and "objc", we
-	       have a trip through the pure "tree" type, rather than cp_expr.
-	       Naively copying it back to "decl" would implicitly give the
-	       new cp_expr value an UNKNOWN_LOCATION for nodes that don't
-	       store an EXPR_LOCATION.  Hence we only update "decl" (and
-	       hence its location_t) if we get back a different tree node.  */
-	    tree decl_tree = objc_lookup_ivar (decl.get_value (),
-					       id_expression);
-	    if (decl_tree != decl.get_value ())
-	      decl = cp_expr (decl_tree);
+	       to whatever cp_parser_lookup_name() found.  */
+	    decl = objc_lookup_ivar (decl, id_expression);
 
 	    /* If name lookup gives us a SCOPE_REF, then the
 	       qualifying scope was dependent.  */
@@ -5071,7 +5059,7 @@ cp_parser_primary_expression (cp_parser *parser,
 		  {
 		    error_at (id_expr_token->location,
 			      "local variable %qD may not appear in this context",
-			      decl.get_value ());
+			      decl);
 		    return error_mark_node;
 		  }
 	      }
@@ -5099,7 +5087,7 @@ cp_parser_primary_expression (cp_parser *parser,
     }
 }
 
-static inline cp_expr
+static inline tree
 cp_parser_primary_expression (cp_parser *parser,
 			      bool address_p,
 			      bool cast_p,
@@ -5144,7 +5132,7 @@ cp_parser_primary_expression (cp_parser *parser,
    If DECLARATOR_P is true, the id-expression is appearing as part of
    a declarator, rather than as part of an expression.  */
 
-static cp_expr
+static tree
 cp_parser_id_expression (cp_parser *parser,
 			 bool template_keyword_p,
 			 bool check_dependency_p,
@@ -5279,7 +5267,7 @@ cp_parser_id_expression (cp_parser *parser,
    is true, the unqualified-id is appearing as part of a declarator,
    rather than as part of an expression.  */
 
-static cp_expr
+static tree
 cp_parser_unqualified_id (cp_parser* parser,
 			  bool template_keyword_p,
 			  bool check_dependency_p,
@@ -5542,7 +5530,7 @@ cp_parser_unqualified_id (cp_parser* parser,
     case CPP_KEYWORD:
       if (token->keyword == RID_OPERATOR)
 	{
-	  cp_expr id;
+	  tree id;
 
 	  /* This could be a template-id, so we try that first.  */
 	  cp_parser_parse_tentatively (parser);
@@ -6132,7 +6120,7 @@ cp_parser_compound_literal_p (cp_parser *parser)
 
    Returns a representation of the expression.  */
 
-static cp_expr
+static tree
 cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                               bool member_access_only_p, bool decltype_p,
 			      cp_id_kind * pidk_return)
@@ -6141,7 +6129,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
   location_t loc;
   enum rid keyword;
   cp_id_kind idk = CP_ID_KIND_NONE;
-  cp_expr postfix_expression = NULL_TREE;
+  tree postfix_expression = NULL_TREE;
   bool is_member_access = false;
   int saved_in_statement = -1;
 
@@ -6160,7 +6148,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
     case RID_CONSTCAST:
       {
 	tree type;
-	cp_expr expression;
+	tree expression;
 	const char *saved_message;
 	bool saved_in_type_id_in_expr_p;
 
@@ -6236,7 +6224,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
 	   ranging from the start of the "*_cast" token to the final closing
 	   paren, with the caret at the start.  */
 	location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);
-	postfix_expression.set_location (cp_cast_loc);
+	protected_set_expr_location (postfix_expression, cp_cast_loc);
       }
       break;
 
@@ -6516,9 +6504,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
 							postfix_expression,
 							false,
 							decltype_p);
-          postfix_expression.set_range (start_loc,
-                                        postfix_expression.get_location ());
-
+          set_source_range (postfix_expression, start_loc,
+                            EXPR_LOCATION (postfix_expression));
 	  idk = CP_ID_KIND_NONE;
           is_member_access = false;
 	  break;
@@ -6760,7 +6747,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
           if (member_access_only_p)
             return is_member_access
               ? postfix_expression
-              : cp_expr (error_mark_node);
+              : error_mark_node;
           else
             return postfix_expression;
 	}
@@ -6960,7 +6947,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
 static tree
 cp_parser_postfix_dot_deref_expression (cp_parser *parser,
 					enum cpp_ttype token_type,
-					cp_expr postfix_expression,
+					tree postfix_expression,
 					bool for_offsetof, cp_id_kind *idk,
 					location_t location)
 {
@@ -6997,7 +6984,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
       if (scope == unknown_type_node)
 	{
 	  error_at (location, "%qE does not have class type",
-		    postfix_expression.get_value ());
+		    postfix_expression);
 	  scope = NULL_TREE;
 	}
       /* Unlike the object expression in other contexts, *this is not
@@ -7439,7 +7426,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
 
    Returns a representation of the expression.  */
 
-static cp_expr
+static tree
 cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
 			    bool address_p, bool cast_p, bool decltype_p)
 {
@@ -7653,8 +7640,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
     }
   if (unary_operator != ERROR_MARK)
     {
-      cp_expr cast_expression;
-      cp_expr expression = error_mark_node;
+      tree cast_expression;
+      tree expression = error_mark_node;
       non_integral_constant non_constant_p = NIC_NONE;
       location_t loc = token->location;
       tsubst_flags_t complain = complain_flags (decltype_p);
@@ -7676,7 +7663,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
 	    ^~~~~~~~~~~~~~~~~~~~~~~~~
 	 with start==caret at the operator token, and
 	 extending to the end of the cast_expression.  */
-      loc = make_location (loc, loc, cast_expression.get_finish ());
+      loc = make_location (loc, loc, get_expr_finish (cast_expression));
 
       /* Now, build an appropriate representation.  */
       switch (unary_operator)
@@ -8274,7 +8261,7 @@ cp_parser_tokens_start_cast_expression (cp_parser *parser)
 
    Returns a representation of the expression.  */
 
-static cp_expr
+static tree
 cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
 			   bool decltype_p, cp_id_kind * pidk)
 {
@@ -8282,7 +8269,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
     {
       tree type = NULL_TREE;
-      cp_expr expr (NULL_TREE);
+      tree expr = NULL_TREE;
       int cast_expression = 0;
       const char *saved_message;
 
@@ -8406,7 +8393,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
 		 end of "expr".  */
 	      location_t cast_loc = make_location (open_paren_loc,
 						   open_paren_loc,
-						   expr.get_finish ());
+						   get_expr_finish (expr));
 	      expr = build_c_cast (cast_loc, type, expr);
 	      return expr;
 	    }
@@ -8500,7 +8487,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
  ? PREC_NOT_OPERATOR					     \
  : binops_by_token[token->type].prec)
 
-static cp_expr
+static tree
 cp_parser_binary_expression (cp_parser* parser, bool cast_p,
 			     bool no_toplevel_fold_p,
 			     bool decltype_p,
@@ -8510,7 +8497,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
   cp_parser_expression_stack stack;
   cp_parser_expression_stack_entry *sp = &stack[0];
   cp_parser_expression_stack_entry current;
-  cp_expr rhs;
+  tree rhs;
   cp_token *token;
   enum tree_code rhs_type;
   enum cp_parser_prec new_prec, lookahead_prec;
@@ -8652,8 +8639,8 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
       overload = NULL;
 
       location_t combined_loc = make_location (current.loc,
-					       current.lhs.get_start (),
-					       rhs.get_finish ());
+					       get_expr_start (current.lhs),
+					       get_expr_finish (rhs));
 
       /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
 	 ERROR_MARK for everything that is not a binary expression.
@@ -8693,7 +8680,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
   return current.lhs;
 }
 
-static cp_expr
+static tree
 cp_parser_binary_expression (cp_parser* parser, bool cast_p,
 			     bool no_toplevel_fold_p,
 			     enum cp_parser_prec prec,
@@ -8717,10 +8704,10 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
      ? : assignment-expression */
 
 static tree
-cp_parser_question_colon_clause (cp_parser* parser, cp_expr logical_or_expr)
+cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
 {
   tree expr, folded_logical_or_expr = cp_fully_fold (logical_or_expr);
-  cp_expr assignment_expr;
+  tree assignment_expr;
   struct cp_token *token;
   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
@@ -8765,8 +8752,8 @@ cp_parser_question_colon_clause (cp_parser* parser, cp_expr logical_or_expr)
      with the caret at the "?", ranging from the start of
      the logical_or_expr to the end of the assignment_expr.  */
   loc = make_location (loc,
-		       logical_or_expr.get_start (),
-		       assignment_expr.get_finish ());
+		       get_expr_start (logical_or_expr),
+		       get_expr_finish (assignment_expr));
 
   /* Build the conditional-expression.  */
   return build_x_conditional_expr (loc, logical_or_expr,
@@ -8787,11 +8774,11 @@ cp_parser_question_colon_clause (cp_parser* parser, cp_expr logical_or_expr)
 
    Returns a representation for the expression.  */
 
-static cp_expr
+static tree
 cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk,
 				 bool cast_p, bool decltype_p)
 {
-  cp_expr expr;
+  tree expr;
 
   /* If the next token is the `throw' keyword, then we're looking at
      a throw-expression.  */
@@ -8823,7 +8810,7 @@ cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk,
 	      location_t saved_input_location;
 
 	      /* Parse the right-hand side of the assignment.  */
-	      cp_expr rhs = cp_parser_initializer_clause (parser,
+	      tree rhs = cp_parser_initializer_clause (parser,
 							  &non_constant_p);
 
 	      if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
@@ -8843,8 +8830,8 @@ cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk,
 		 end of the rhs.  */
 	      saved_input_location = input_location;
 	      loc = make_location (loc,
-				   expr.get_start (),
-				   rhs.get_finish ());
+				   get_expr_start (expr),
+				   get_expr_finish (rhs));
 	      input_location = loc;
 	      expr = build_x_modify_expr (loc, expr,
 					  assignment_operator,
@@ -8960,16 +8947,16 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
 
    Returns a representation of the expression.  */
 
-static cp_expr
+static tree
 cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
 		      bool cast_p, bool decltype_p)
 {
-  cp_expr expression = NULL_TREE;
+  tree expression = NULL_TREE;
   location_t loc = UNKNOWN_LOCATION;
 
   while (true)
     {
-      cp_expr assignment_expression;
+      tree assignment_expression;
 
       /* Parse the next assignment-expression.  */
       assignment_expression
@@ -8995,8 +8982,8 @@ cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
 	  /* Create a location with caret at the comma, ranging
 	     from the start of the LHS to the end of the RHS.  */
 	  loc = make_location (loc,
-			       expression.get_start (),
-			       assignment_expression.get_finish ());
+			       get_expr_start (expression),
+			       get_expr_finish (assignment_expression));
 	  expression = build_x_compound_expr (loc, expression,
 					      assignment_expression,
 					      complain_flags (decltype_p));
@@ -9028,7 +9015,7 @@ cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
   constant, *NON_CONSTANT_P is set to TRUE.  If ALLOW_NON_CONSTANT_P
   is false, NON_CONSTANT_P should be NULL.  */
 
-static cp_expr
+static tree
 cp_parser_constant_expression (cp_parser* parser,
 			       bool allow_non_constant_p,
 			       bool *non_constant_p)
@@ -9036,7 +9023,7 @@ cp_parser_constant_expression (cp_parser* parser,
   bool saved_integral_constant_expression_p;
   bool saved_allow_non_integral_constant_expression_p;
   bool saved_non_integral_constant_expression_p;
-  cp_expr expression;
+  tree expression;
 
   /* It might seem that we could simply parse the
      conditional-expression, and then check to see if it were
@@ -9406,7 +9393,7 @@ finish_lambda_scope (void)
 
    Returns a representation of the expression.  */
 
-static cp_expr
+static tree
 cp_parser_lambda_expression (cp_parser* parser)
 {
   tree lambda_expr = build_lambda_expr ();
@@ -13408,7 +13395,7 @@ cp_parser_mem_initializer_id (cp_parser* parser)
    Returns an IDENTIFIER_NODE for the operator which is a
    human-readable spelling of the identifier, e.g., `operator +'.  */
 
-static cp_expr
+static tree
 cp_parser_operator_function_id (cp_parser* parser)
 {
   /* Look for the `operator' keyword.  */
@@ -13448,7 +13435,7 @@ cp_literal_operator_id (const char* name)
    Returns an IDENTIFIER_NODE for the operator which is a
    human-readable spelling of the identifier, e.g., `operator +'.  */
 
-static cp_expr
+static tree
 cp_parser_operator (cp_parser* parser)
 {
   tree id = NULL_TREE;
@@ -20436,10 +20423,10 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
 
    Otherwise, calls cp_parser_braced_list.  */
 
-static cp_expr
+static tree
 cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
 {
-  cp_expr initializer;
+  tree initializer;
 
   /* Assume the expression is constant.  */
   *non_constant_p = false;
@@ -24205,7 +24192,7 @@ cp_parser_nested_requirement (cp_parser *parser)
    TREE_LIST of candidates if name-lookup results in an ambiguity, and
    NULL_TREE otherwise.  */
 
-static cp_expr
+static tree
 cp_parser_lookup_name (cp_parser *parser, tree name,
 		       enum tag_types tag_type,
 		       bool is_template,
@@ -25451,7 +25438,7 @@ cp_parser_single_declaration (cp_parser* parser,
 
 /* Parse a cast-expression that is not the operand of a unary "&".  */
 
-static cp_expr
+static tree
 cp_parser_simple_cast_expression (cp_parser *parser)
 {
   return cp_parser_cast_expression (parser, /*address_p=*/false,
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 57d3458..6b8642e 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2164,8 +2164,8 @@ empty_expr_stmt_p (tree expr_stmt)
    the function (or functions) to call; ARGS are the arguments to the
    call.  Returns the functions to be considered by overload resolution.  */
 
-cp_expr
-perform_koenig_lookup (cp_expr fn, vec<tree, va_gc> *args,
+tree
+perform_koenig_lookup (tree fn, vec<tree, va_gc> *args,
 		       tsubst_flags_t complain)
 {
   tree identifier = NULL_TREE;
@@ -2460,14 +2460,14 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
    is indicated by CODE, which should be POSTINCREMENT_EXPR or
    POSTDECREMENT_EXPR.)  */
 
-cp_expr
-finish_increment_expr (cp_expr expr, enum tree_code code)
+tree
+finish_increment_expr (tree expr, enum tree_code code)
 {
   /* input_location holds the location of the trailing operator token.  */
-  cp_expr result = build_x_unary_op (input_location, code, expr,
+  tree result = build_x_unary_op (input_location, code, expr,
 				     tf_warning_or_error);
-  result.set_range (expr.get_start (),
-		    get_range_from_loc (line_table, input_location).m_finish);
+  set_source_range (result, get_expr_start (expr),
+		    get_finish (input_location));
   return result;
 }
 
@@ -2562,17 +2562,17 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
 
 /* Finish an expression of the form CODE EXPR.  */
 
-cp_expr
-finish_unary_op_expr (location_t op_loc, enum tree_code code, cp_expr expr,
+tree
+finish_unary_op_expr (location_t op_loc, enum tree_code code, tree expr,
 		      tsubst_flags_t complain)
 {
   location_t combined_loc = make_location (op_loc,
-					   op_loc, expr.get_finish ());
+					   op_loc, get_expr_finish (expr));
   tree result = build_x_unary_op (combined_loc, code, expr, complain);
   tree result_ovl, expr_ovl;
 
   if (!(complain & tf_warning))
-    return cp_expr (result, combined_loc);
+    return result;
 
   result_ovl = result;
   expr_ovl = expr;
@@ -2582,7 +2582,7 @@ finish_unary_op_expr (location_t op_loc, enum tree_code code, cp_expr expr,
 
   if (!CONSTANT_CLASS_P (expr_ovl)
       || TREE_OVERFLOW_P (expr_ovl))
-    return cp_expr (result, combined_loc);
+    return result;
 
   if (!processing_template_decl)
     result_ovl = cp_fully_fold (result_ovl);
@@ -3331,7 +3331,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain)
    the use of "this" explicit.
 
    Upon return, *IDK will be filled in appropriately.  */
-cp_expr
+tree
 finish_id_expression (tree id_expression,
 		      tree decl,
 		      tree scope,
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 1332b06..9c27add 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2261,7 +2261,7 @@ lookup_anon_field (tree t, tree type)
    functions indicated by MEMBER.  */
 
 tree
-build_class_member_access_expr (cp_expr object, tree member,
+build_class_member_access_expr (tree object, tree member,
 				tree access_path, bool preserve_reference,
 				tsubst_flags_t complain)
 {
@@ -2291,10 +2291,10 @@ build_class_member_access_expr (cp_expr object, tree member,
 	      && CLASS_TYPE_P (TREE_TYPE (object_type)))
 	    error ("request for member %qD in %qE, which is of pointer "
 		   "type %qT (maybe you meant to use %<->%> ?)",
-		   member, object.get_value (), object_type);
+		   member, object, object_type);
 	  else
 	    error ("request for member %qD in %qE, which is of non-class "
-		   "type %qT", member, object.get_value (), object_type);
+		   "type %qT", member, object, object_type);
 	}
       return error_mark_node;
     }
@@ -2437,9 +2437,8 @@ build_class_member_access_expr (cp_expr object, tree member,
 
       location_t combined_loc =
 	make_location (input_location,
-		       object.get_start (),
-		       get_range_from_loc (line_table,
-					   input_location).m_finish);
+		       get_expr_start (object),
+		       get_finish (input_location));
       result = build3_loc (combined_loc, COMPONENT_REF, member_type,
 			   object, member, NULL_TREE);
 
@@ -2629,7 +2628,7 @@ check_template_keyword (tree decl)
    be a template via the use of the "A::template B" syntax.  */
 
 tree
-finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
+finish_class_member_access_expr (tree object, tree name, bool template_p,
 				 tsubst_flags_t complain)
 {
   tree expr;
@@ -2663,7 +2662,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
 	      && TYPE_P (TREE_OPERAND (name, 0))
 	      && dependent_type_p (TREE_OPERAND (name, 0))))
 	return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
-				 object.get_value (), name, NULL_TREE);
+				 object, name, NULL_TREE);
       object = build_non_dependent_expr (object);
     }
   else if (c_dialect_objc ()
@@ -2686,10 +2685,10 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
 	      && CLASS_TYPE_P (TREE_TYPE (object_type)))
 	    error ("request for member %qD in %qE, which is of pointer "
 		   "type %qT (maybe you meant to use %<->%> ?)",
-		   name, object.get_value (), object_type);
+		   name, object, object_type);
 	  else
 	    error ("request for member %qD in %qE, which is of non-class "
-		   "type %qT", name, object.get_value (), object_type);
+		   "type %qT", name, object, object_type);
 	}
       return error_mark_node;
     }
@@ -5265,7 +5264,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
    and XARG is the operand.  */
 
 tree
-build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
+build_x_unary_op (location_t loc, enum tree_code code, tree xarg,
 		  tsubst_flags_t complain)
 {
   tree orig_expr = xarg;
@@ -5275,7 +5274,7 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
   if (processing_template_decl)
     {
       if (type_dependent_expression_p (xarg))
-	return build_min_nt_loc (loc, code, xarg.get_value (), NULL_TREE);
+	return build_min_nt_loc (loc, code, xarg, NULL_TREE);
 
       xarg = build_non_dependent_expr (xarg);
     }
@@ -5310,7 +5309,7 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
 		error (DECL_CONSTRUCTOR_P (fn)
 		       ? G_("taking address of constructor %qE")
 		       : G_("taking address of destructor %qE"),
-		       xarg.get_value ());
+		       xarg);
 	      return error_mark_node;
 	    }
 	}
@@ -5326,7 +5325,7 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
 	      if (complain & tf_error)
 		{
 		  error ("invalid use of %qE to form a "
-			 "pointer-to-member-function", xarg.get_value ());
+			 "pointer-to-member-function", xarg);
 		  if (TREE_CODE (xarg) != OFFSET_REF)
 		    inform (input_location, "  a qualified-id is required");
 		}
@@ -5337,7 +5336,7 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg,
 	      if (complain & tf_error)
 		error ("parentheses around %qE cannot be used to form a"
 		       " pointer-to-member-function",
-		       xarg.get_value ());
+		       xarg);
 	      else
 		return error_mark_node;
 	      PTRMEM_OK_P (xarg) = 1;
@@ -7266,18 +7265,6 @@ build_c_cast (location_t loc, tree type, tree expr)
   return result;
 }
 
-/* Like the "build_c_cast" used for c-common, but using cp_expr to
-   preserve location information even for tree nodes that don't
-   support it.  */
-
-cp_expr
-build_c_cast (location_t loc, tree type, cp_expr expr)
-{
-  tree result = cp_build_c_cast (type, expr, tf_warning_or_error);
-  protected_set_expr_location (result, loc);
-  return cp_expr (result, loc);
-}
-
 /* Build an expression representing an explicit C-style cast to type
    TYPE of expression EXPR.  */
 
@@ -7783,7 +7770,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
   return result;
 }
 
-cp_expr
+tree
 build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
 		     tree rhs, tsubst_flags_t complain)
 {
diff --git a/gcc/tree.h b/gcc/tree.h
index 7919860..54164f1 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5362,4 +5362,34 @@ get_decl_source_range (tree decl)
 extern location_t
 make_location (location_t caret, location_t start, location_t finish);
 
+/* FIXME.  */
+inline location_t
+get_start (location_t loc)
+{
+  source_range src_range = get_range_from_loc (line_table, loc);
+  return src_range.m_start;
+}
+
+/* FIXME.  */
+inline location_t
+get_finish (location_t loc)
+{
+  source_range src_range = get_range_from_loc (line_table, loc);
+  return src_range.m_finish;
+}
+
+/* FIXME.  */
+inline location_t
+get_expr_start (tree expr)
+{
+  return get_start (EXPR_LOCATION (expr));
+}
+
+/* FIXME.  */
+inline location_t
+get_expr_finish (tree expr)
+{
+  return get_finish (EXPR_LOCATION (expr));
+}
+
 #endif  /* GCC_TREE_H  */
-- 
1.8.5.3

