public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Zoran Zaric <Zoran.Zaric@amd.com>
To: gdb-patches@sourceware.org
Cc: Zoran Zaric <Zoran.Zaric@amd.com>
Subject: [PATCH 21/30] Change DWARF stack to use new dwarf_entry classes
Date: Mon,  7 Dec 2020 19:00:22 +0000	[thread overview]
Message-ID: <20201207190031.13341-22-Zoran.Zaric@amd.com> (raw)
In-Reply-To: <20201207190031.13341-1-Zoran.Zaric@amd.com>

To replace existing DWARF stack element (dwarf_stack_value) with
dwarf_entry class based objects, a support for conversion between
struct value and the new classes is needed. The reason for this is
that dwarf_entry based classes are not designed to be visible outside
the expr.c file. This makes the DWARF expression evaluator more self
contained. This can be beneficial if there is ever a need to have a
DWARF support in gdbserver.

Once the conversion support is added, the current DWARF stack element
can easily be swapped out.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_value_equal_op): New function.
	(dwarf_value_less_op): New function.
	(struct piece_closure): Change to use dwarf_entry based
	classes.
	(allocate_piece_closure): Change to use dwarf_entry based
	classes.
	(rw_pieced_value): Change to use dwarf_entry based classes.
	(check_pieced_synthetic_pointer): Change to use dwarf_entry
	based classes.
	(check_synthetic_pointer_location): New function.
	(indirect_pieced_value): Change to use dwarf_entry based
	classes.
	(indirect_from_location): New function.
	(coerce_pieced_ref): Change to use dwarf_entry based classes.
	(free_pieced_value_closure): Change to use dwarf_entry based
	classes.
	(dwarf_expr_context::~dwarf_expr_context): Instantiate
	dwarf_entry_factory object.
	(dwarf_expr_context::push): Change to use dwarf_entry based
	classes.
	(dwarf_expr_context::push_address): Change to use dwarf_entry
	based classes.
	(dwarf_expr_context::fetch): Change to use dwarf_entry based
	classes.
	(dwarf_expr_context::read_mem): Remove method.
	(dwarf_expr_context::fetch_result): Change to use dwarf_entry
	based classes.
	(dwarf_expr_context::dwarf_entry_deref): New method.
	(dwarf_expr_context::gdb_value_to_dwarf_entry): New method.
	(dwarf_expr_context::dwarf_entry_to_gdb_value): New method.
	(dwarf_expr_context::fetch_address): Change to use dwarf_entry
	based classes.
	(dwarf_expr_context::fetch_in_stack_memory): Change to use
	dwarf_entry based classes.
	(dwarf_expr_context::add_piece): Change to use dwarf_entry based
	classes.
	(dwarf_expr_context::execute_stack_op): Change to use dwarf_entry
	based classes.
	* dwarf2/expr.h (class dwarf_entry): New declaration.
	(class dwarf_entry_factory): New declaration.
	(enum dwarf_value_location): Remove enumeration.
	(struct dwarf_expr_piece): Remove structure.
	(struct dwarf_stack_value): Remove structure.
	(struct dwarf_expr_context): Change to use dwarf_entry based
	classes. Add dwarf_entry_factory object.
---
 gdb/dwarf2/expr.c | 1673 ++++++++++++++++++++++-----------------------
 gdb/dwarf2/expr.h |  227 +++---
 2 files changed, 900 insertions(+), 1000 deletions(-)

diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index f188240d8b..aefbeb3dad 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -1046,6 +1046,30 @@ value_to_gdb_value (const dwarf_value *value, struct type *type,
   return retval;
 }
 
+/* Compare two DWARF value's ARG1 and ARG2 for equality in a context
+   of a value entry comparison.  */
+
+static bool
+dwarf_value_equal_op (dwarf_value *arg1, dwarf_value *arg2)
+{
+  struct value *arg1_value = value_to_gdb_value (arg1, arg1->get_type ());
+  struct value *arg2_value = value_to_gdb_value (arg2, arg2->get_type ());
+
+  return value_equal (arg1_value, arg2_value);
+}
+
+/* Compare if DWARF value ARG1 is lesser then DWARF value ARG2 in a
+   context of a value entry comparison.   */
+
+static bool
+dwarf_value_less_op (dwarf_value *arg1, dwarf_value *arg2)
+{
+  struct value *arg1_value = value_to_gdb_value (arg1, arg1->get_type ());
+  struct value *arg2_value = value_to_gdb_value (arg2, arg2->get_type ());
+
+  return value_less (arg1_value, arg2_value);
+}
+
 /* Factory class for creation and lifetime management of all DWARF
    entries found on a DWARF evaluation stack.  */
 
@@ -1338,8 +1362,8 @@ struct piece_closure
   /* The CU from which this closure's expression came.  */
   struct dwarf2_per_cu_data *per_cu = NULL;
 
-  /* The pieces describing this variable.  */
-  std::vector<dwarf_expr_piece> pieces;
+  /* Location description of this variable.  */
+  dwarf_location *location;
 
   /* Frame ID of frame to which a register value is relative, used
      only by DWARF_VALUE_REGISTER.  */
@@ -1352,7 +1376,7 @@ struct piece_closure
 static struct piece_closure *
 allocate_piece_closure (dwarf2_per_cu_data *per_cu,
 			dwarf2_per_objfile *per_objfile,
-			std::vector<dwarf_expr_piece> &&pieces,
+			dwarf_location *location,
 			struct frame_info *frame)
 {
   struct piece_closure *c = new piece_closure;
@@ -1361,16 +1385,13 @@ allocate_piece_closure (dwarf2_per_cu_data *per_cu,
   /* We must capture this here due to sharing of DWARF state.  */
   c->per_objfile = per_objfile;
   c->per_cu = per_cu;
-  c->pieces = std::move (pieces);
   if (frame == NULL)
     c->frame_id = null_frame_id;
   else
     c->frame_id = get_frame_id (frame);
 
-  for (dwarf_expr_piece &piece : c->pieces)
-    if (piece.location == DWARF_VALUE_STACK)
-      value_incref (piece.v.value);
-
+  location->incref ();
+  c->location = location;
   return c;
 }
 
@@ -1382,310 +1403,189 @@ allocate_piece_closure (dwarf2_per_cu_data *per_cu,
 static void
 rw_pieced_value (struct value *v, struct value *from)
 {
-  int i;
-  LONGEST offset = 0, max_offset;
-  ULONGEST bits_to_skip;
-  gdb_byte *v_contents;
-  const gdb_byte *from_contents;
-  struct piece_closure *c
+  LONGEST bit_offset = 0, max_bit_offset;
+  struct piece_closure *closure
     = (struct piece_closure *) value_computed_closure (v);
-  gdb::byte_vector buffer;
-  bool bits_big_endian = type_byte_order (value_type (v)) == BFD_ENDIAN_BIG;
+  bool big_endian = type_byte_order (value_type (v)) == BFD_ENDIAN_BIG;
+  dwarf_entry *entry = closure->location;
+
+  /* Only expect implicit pointer and composite location
+     description here.  */
+  if (entry == nullptr
+      || (dynamic_cast<dwarf_implicit_pointer *> (entry) == nullptr
+          && dynamic_cast<dwarf_composite *> (entry) == nullptr))
+    internal_error (__FILE__, __LINE__, _("invalid location type"));
 
-  if (from != NULL)
-    {
-      from_contents = value_contents (from);
-      v_contents = NULL;
-    }
-  else
+  if (from == NULL)
     {
       if (value_type (v) != value_enclosing_type (v))
-	internal_error (__FILE__, __LINE__,
+        internal_error (__FILE__, __LINE__,
 			_("Should not be able to create a lazy value with "
 			  "an enclosing type"));
-      v_contents = value_contents_raw (v);
-      from_contents = NULL;
     }
 
-  bits_to_skip = 8 * value_offset (v);
+  ULONGEST bits_to_skip = HOST_CHAR_BIT * value_offset (v);
+
+  /* If there are bits that don't complete a byte, count them in.  */
   if (value_bitsize (v))
     {
-      bits_to_skip += (8 * value_offset (value_parent (v))
+      bits_to_skip += (HOST_CHAR_BIT * value_offset (value_parent (v))
 		       + value_bitpos (v));
-      if (from != NULL
-	  && (type_byte_order (value_type (from))
-	      == BFD_ENDIAN_BIG))
+      if (from != NULL && big_endian)
 	{
 	  /* Use the least significant bits of FROM.  */
-	  max_offset = 8 * TYPE_LENGTH (value_type (from));
-	  offset = max_offset - value_bitsize (v);
+	  max_bit_offset = HOST_CHAR_BIT * TYPE_LENGTH (value_type (from));
+	  bit_offset = max_bit_offset - value_bitsize (v);
 	}
       else
-	max_offset = value_bitsize (v);
+	max_bit_offset = value_bitsize (v);
     }
   else
-    max_offset = 8 * TYPE_LENGTH (value_type (v));
+    max_bit_offset = HOST_CHAR_BIT * TYPE_LENGTH (value_type (v));
 
-  /* Advance to the first non-skipped piece.  */
-  for (i = 0; i < c->pieces.size () && bits_to_skip >= c->pieces[i].size; i++)
-    bits_to_skip -= c->pieces[i].size;
-
-  for (; i < c->pieces.size () && offset < max_offset; i++)
+  /* Reading from and writing to an implicit pointer is not meaningful,
+     so we just skip them here.  */
+  if (dynamic_cast<dwarf_implicit_pointer *> (entry) != nullptr)
     {
-      struct dwarf_expr_piece *p = &c->pieces[i];
-      size_t this_size_bits, this_size;
-
-      this_size_bits = p->size - bits_to_skip;
-      if (this_size_bits > max_offset - offset)
-	this_size_bits = max_offset - offset;
+      if (from != NULL)
+	mark_value_bits_optimized_out (v, bits_to_skip,
+				       HOST_CHAR_BIT
+				       * TYPE_LENGTH (value_type (v)));
+      return;
+    }
 
-      switch (p->location)
-	{
-	case DWARF_VALUE_REGISTER:
-	  {
-	    struct frame_info *frame = frame_find_by_id (c->frame_id);
-	    struct gdbarch *arch = get_frame_arch (frame);
-	    int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
-	    ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
-	    int optim, unavail;
-
-	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
-		&& p->offset + p->size < reg_bits)
-	      {
-		/* Big-endian, and we want less than full size.  */
-		bits_to_skip += reg_bits - (p->offset + p->size);
-	      }
-	    else
-	      bits_to_skip += p->offset;
+  struct frame_info *frame = frame_find_by_id (closure->frame_id);
 
-	    this_size = bits_to_bytes (bits_to_skip, this_size_bits);
-	    buffer.resize (this_size);
+  dwarf_composite *composite_entry = dynamic_cast<dwarf_composite *> (entry);
 
-	    if (from == NULL)
-	      {
-		/* Read mode.  */
-		read_from_register (frame, gdb_regnum, bits_to_skip / 8,
-				    this_size, buffer.data (),
-				    &optim, &unavail);
-
-		if (optim)
-		  mark_value_bits_optimized_out (v, offset, this_size_bits);
-		if (unavail)
-		  mark_value_bits_unavailable (v, offset, this_size_bits);
-		/* Only copy data if valid.  */
-		if (!optim && !unavail)
-		  copy_bitwise (v_contents, offset,
-				buffer.data (), bits_to_skip % 8,
-				this_size_bits, bits_big_endian);
-	      }
-	    else
-	      {
-		/* Write mode.  */
-		if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
-		  {
-		    /* Data is copied non-byte-aligned into the register.
-		       Need some bits from original register value.  */
-		    read_from_register (frame, gdb_regnum, bits_to_skip / 8,
-					this_size, buffer.data (),
-					&optim, &unavail);
-		    if (optim)
-		      throw_error (OPTIMIZED_OUT_ERROR,
-				   _("Can't do read-modify-write to "
-				     "update bitfield; containing word "
-				     "has been optimized out"));
-		    if (unavail)
-		      throw_error (NOT_AVAILABLE_ERROR,
-				   _("Can't do read-modify-write to "
-				     "update bitfield; containing word "
-				     "is unavailable"));
-		  }
+  /* Advance to the first non-skipped piece.  */
+  unsigned int i;
+  unsigned int pieces_num = composite_entry->get_pieces_num ();
 
-		copy_bitwise (buffer.data (), bits_to_skip % 8,
-			      from_contents, offset,
-			      this_size_bits, bits_big_endian);
-		write_to_register (frame, gdb_regnum, bits_to_skip / 8,
-				   this_size, buffer.data (),
-				   &optim, &unavail);
-	      }
-	  }
-	  break;
+  for (i = 0; i < pieces_num; i++)
+    {
+      ULONGEST bit_size = composite_entry->get_bit_size_at (i);
 
-	case DWARF_VALUE_MEMORY:
-	  {
-	    bits_to_skip += p->offset;
+      if (bits_to_skip < bit_size)
+	break;
 
-	    CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8;
-	    bool in_stack_memory = p->v.mem.in_stack_memory;
-	    int unavail = 0;
+      bits_to_skip -= bit_size;
+    }
 
-	    if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0
-		&& offset % 8 == 0)
-	      {
-		/* Everything is byte-aligned; no buffer needed.  */
-		if (from != NULL)
-		  write_to_memory (start_addr, (from_contents + offset / 8),
-				   this_size_bits / 8, in_stack_memory,
-				   &unavail);
-		else
-		  read_from_memory (start_addr, (v_contents + offset / 8),
-				    this_size_bits / 8, in_stack_memory,
-				    &unavail);
-	      }
-	    else
-	      {
-		this_size = bits_to_bytes (bits_to_skip, this_size_bits);
-		buffer.resize (this_size);
+  for (; i < pieces_num && bit_offset < max_bit_offset; i++)
+    {
+      const dwarf_location *location = composite_entry->get_piece_at (i);
+      ULONGEST bit_size = composite_entry->get_bit_size_at (i);
+      size_t this_bit_size = bit_size - bits_to_skip;
+      int optimized, unavailable;
 
-		if (from == NULL)
-		  {
-		    /* Read mode.  */
-		    read_from_memory (start_addr, buffer.data (),
-				      this_size, in_stack_memory,
-				      &unavail);
-		    if (!unavail)
-		      copy_bitwise (v_contents, offset,
-				    buffer.data (), bits_to_skip % 8,
-				    this_size_bits, bits_big_endian);
-		  }
-		else
-		  {
-		    /* Write mode.  */
-		    if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
-		      {
-			if (this_size <= 8)
-			  {
-			    /* Perform a single read for small sizes.  */
-			    read_from_memory (start_addr, buffer.data (),
-					      this_size, in_stack_memory,
-					      &unavail);
-			  }
-			else
-			  {
-			    /* Only the first and last bytes can possibly have
-			       any bits reused.  */
-			    read_from_memory (start_addr, buffer.data (),
-					      1, in_stack_memory,
-					      &unavail);
-			    if (!unavail)
-			      read_from_memory (start_addr + this_size - 1,
-						&buffer[this_size - 1], 1,
-						in_stack_memory, &unavail);
-			  }
-		      }
-
-		    if (!unavail)
-		      {
-			copy_bitwise (buffer.data (), bits_to_skip % 8,
-				      from_contents, offset,
-				      this_size_bits, bits_big_endian);
-			write_to_memory (start_addr, buffer.data (),
-					 this_size, in_stack_memory,
-					 &unavail);
-		      }
-		  }
-	      }
+      if (this_bit_size > max_bit_offset - bit_offset)
+	this_bit_size = max_bit_offset - bit_offset;
 
-	    if (unavail)
-	      {
-		if (from == NULL)
-		  mark_value_bits_unavailable (v, (offset + bits_to_skip % 8),
-					       this_size_bits);
-		else
-		  throw_error (NOT_AVAILABLE_ERROR,
-			       _("Can't do read-modify-write to "
-				 "update bitfield; containing word "
-				 "is unavailable"));
-	      }
-	  }
-	  break;
+      if (from == NULL)
+	{
+	  /* Implicit pointers are handled later.  */
+	  if (dynamic_cast<const dwarf_implicit_pointer *>
+		(location) == nullptr)
+	    {
+	      read_from_location (location, frame, bits_to_skip,
+				  value_contents_raw (v), bit_offset,
+				  this_bit_size, bit_size, big_endian,
+				  &optimized, &unavailable);
+
+	      if (optimized)
+		mark_value_bits_optimized_out (v, bit_offset, this_bit_size);
+	      if (unavailable)
+		mark_value_bits_unavailable (v, bit_offset, this_bit_size);
+	    }
+	}
+      else
+	{
+	  write_to_location (location, frame, bits_to_skip,
+			     value_contents (from), bit_offset,
+			     this_bit_size, bit_size, big_endian,
+			     &optimized, &unavailable);
+
+	  if (optimized)
+	    throw_error (OPTIMIZED_OUT_ERROR,
+			 _("Can't do read-modify-write to "
+			   "update bitfield; containing word "
+			   "has been optimized out"));
+	  if (unavailable)
+	    throw_error (NOT_AVAILABLE_ERROR,
+			 _("Can't do read-modify-write to "
+			   "update bitfield; containing word "
+			   "is unavailable"));
+    }
 
-	case DWARF_VALUE_STACK:
-	  {
-	    if (from != NULL)
-	      {
-		mark_value_bits_optimized_out (v, offset, this_size_bits);
-		break;
-	      }
+      bit_offset += this_bit_size;
+      bits_to_skip = 0;
+    }
+}
 
-	    gdbarch *objfile_gdbarch = c->per_objfile->objfile->arch ();
-	    ULONGEST stack_value_size_bits
-	      = 8 * TYPE_LENGTH (value_type (p->v.value));
+static void
+read_pieced_value (struct value *v)
+{
+  rw_pieced_value (v, NULL);
+}
 
-	    /* Use zeroes if piece reaches beyond stack value.  */
-	    if (p->offset + p->size > stack_value_size_bits)
-	      break;
+static void
+write_pieced_value (struct value *to, struct value *from)
+{
+  rw_pieced_value (to, from);
+}
 
-	    /* Piece is anchored at least significant bit end.  */
-	    if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
-	      bits_to_skip += stack_value_size_bits - p->offset - p->size;
-	    else
-	      bits_to_skip += p->offset;
+/* Check if a given location contains an implicit pointer
+   location description of a BIT_LENGTH size on a given
+   BIT_OFFSET offset.  */
 
-	    copy_bitwise (v_contents, offset,
-			  value_contents_all (p->v.value),
-			  bits_to_skip,
-			  this_size_bits, bits_big_endian);
-	  }
-	  break;
+static int
+check_synthetic_pointer_location (const dwarf_location *location,
+				  LONGEST bit_offset, int bit_length)
+{
+  if (dynamic_cast<const dwarf_implicit_pointer *> (location) != nullptr)
+    return 1;
 
-	case DWARF_VALUE_LITERAL:
-	  {
-	    if (from != NULL)
-	      {
-		mark_value_bits_optimized_out (v, offset, this_size_bits);
-		break;
-	      }
+  if (auto composite_entry
+	= dynamic_cast<const dwarf_composite *> (location))
+  {
+    /* Advance to the first non-skipped piece.  */
+    unsigned int pieces_num = composite_entry->get_pieces_num ();
+    LONGEST total_bit_offset = bit_offset;
+    LONGEST total_bit_length = bit_length;
 
-	    ULONGEST literal_size_bits = 8 * p->v.literal.length;
-	    size_t n = this_size_bits;
+    total_bit_offset += HOST_CHAR_BIT * composite_entry->get_offset ()
+			+ composite_entry->get_bit_suboffset ();
 
-	    /* Cut off at the end of the implicit value.  */
-	    bits_to_skip += p->offset;
-	    if (bits_to_skip >= literal_size_bits)
-	      break;
-	    if (n > literal_size_bits - bits_to_skip)
-	      n = literal_size_bits - bits_to_skip;
+    for (unsigned int i = 0; i < pieces_num && total_bit_length != 0; i++)
+      {
+	ULONGEST read_bit_length = composite_entry->get_bit_size_at (i);
 
-	    copy_bitwise (v_contents, offset,
-			  p->v.literal.data, bits_to_skip,
-			  n, bits_big_endian);
+	if (total_bit_offset >= read_bit_length)
+	  {
+	     total_bit_offset -= read_bit_length;
+	     continue;
 	  }
-	  break;
 
-	case DWARF_VALUE_IMPLICIT_POINTER:
-	    if (from != NULL)
-	      {
-		mark_value_bits_optimized_out (v, offset, this_size_bits);
-		break;
-	      }
+	read_bit_length -= total_bit_offset;
 
-	  /* These bits show up as zeros -- but do not cause the value to
-	     be considered optimized-out.  */
-	  break;
+	if (total_bit_length < read_bit_length)
+	  read_bit_length = total_bit_length;
 
-	case DWARF_VALUE_OPTIMIZED_OUT:
-	  mark_value_bits_optimized_out (v, offset, this_size_bits);
-	  break;
+	const dwarf_location *piece = composite_entry->get_piece_at (i);
 
-	default:
-	  internal_error (__FILE__, __LINE__, _("invalid location type"));
-	}
+	if (!check_synthetic_pointer_location (piece, total_bit_offset,
+					       read_bit_length))
+	  return 0;
 
-      offset += this_size_bits;
-      bits_to_skip = 0;
-    }
-}
+	total_bit_offset = 0;
+	total_bit_length -= read_bit_length;
+      }
 
-static void
-read_pieced_value (struct value *v)
-{
-  rw_pieced_value (v, NULL);
-}
+    return 1;
+  }
 
-static void
-write_pieced_value (struct value *to, struct value *from)
-{
-  rw_pieced_value (to, from);
+  return 0;
 }
 
 /* An implementation of an lval_funcs method to see whether a value is
@@ -1695,38 +1595,85 @@ static int
 check_pieced_synthetic_pointer (const struct value *value, LONGEST bit_offset,
 				int bit_length)
 {
-  struct piece_closure *c
-    = (struct piece_closure *) value_computed_closure (value);
-  int i;
+  LONGEST total_bit_offset = bit_offset + HOST_CHAR_BIT * value_offset (value);
 
-  bit_offset += 8 * value_offset (value);
   if (value_bitsize (value))
-    bit_offset += value_bitpos (value);
+    total_bit_offset += value_bitpos (value);
+
+  struct piece_closure *closure
+    = (struct piece_closure *) value_computed_closure (value);
+  dwarf_location *location = closure->location;
+
+  if (location == nullptr)
+    return 0;
+
+  return check_synthetic_pointer_location (location, total_bit_offset,
+					   bit_length);
+}
 
-  for (i = 0; i < c->pieces.size () && bit_length > 0; i++)
+/* Recursive indirect read from a given LOCATION location description
+   in a given FRAME context, using the TYPE as the type of the pointer.
+   Where INDIRECT_OFFSET is an offset applied to the implicit pointer
+   location description before the indirect read. BIT_OFFSET is an bit
+   offset applied to the LOCATION before the indirection and BIT_LENGTH
+   is a bit length of the LOCATION to be used for the read.
+
+   Read is only performed on the implicit pointer location
+   description parts of the LOCATION.  */
+
+static struct value *
+indirect_from_location (const dwarf_location *location,
+			struct frame_info *frame,
+			struct type *type, LONGEST indirect_offset,
+			LONGEST bit_offset, int bit_length)
+{
+  if (auto pointer_entry
+	= dynamic_cast<const dwarf_implicit_pointer *> (location))
+    {
+      gdb_assert (pointer_entry->get_per_cu () != nullptr);
+
+      LONGEST total_indirect_offset
+	= indirect_offset + pointer_entry->get_offset ();
+
+      return indirect_synthetic_pointer (pointer_entry->get_die_offset (),
+					 total_indirect_offset,
+					 pointer_entry->get_per_cu (),
+					 pointer_entry->get_per_objfile (),
+					 frame, type);
+    }
+  else if (auto composite_entry
+	     = dynamic_cast<const dwarf_composite *> (location))
     {
-      struct dwarf_expr_piece *p = &c->pieces[i];
-      size_t this_size_bits = p->size;
+      /* Advance to the first non-skipped piece.  */
+      unsigned int pieces_num = composite_entry->get_pieces_num ();
+      LONGEST total_bit_offset = bit_offset;
 
-      if (bit_offset > 0)
+      total_bit_offset += HOST_CHAR_BIT * composite_entry->get_offset ()
+			  + composite_entry->get_bit_suboffset ();
+
+      for (unsigned int i = 0; i < pieces_num; i++)
 	{
-	  if (bit_offset >= this_size_bits)
+	  ULONGEST read_bit_length = composite_entry->get_bit_size_at (i);
+
+	  if (total_bit_offset >= read_bit_length)
 	    {
-	      bit_offset -= this_size_bits;
+	      total_bit_offset -= read_bit_length;
 	      continue;
 	    }
 
-	  bit_length -= this_size_bits - bit_offset;
-	  bit_offset = 0;
-	}
-      else
-	bit_length -= this_size_bits;
+	  read_bit_length -= total_bit_offset;
 
-      if (p->location != DWARF_VALUE_IMPLICIT_POINTER)
-	return 0;
+	  if (bit_length < read_bit_length)
+	    read_bit_length = bit_length;
+
+	  const dwarf_location *piece = composite_entry->get_piece_at (i);
+
+	  return indirect_from_location (piece, frame, type, indirect_offset,
+					 total_bit_offset, read_bit_length);
+	}
     }
 
-  return 1;
+  return NULL;
 }
 
 /* An implementation of an lval_funcs method to indirect through a
@@ -1735,56 +1682,26 @@ check_pieced_synthetic_pointer (const struct value *value, LONGEST bit_offset,
 static struct value *
 indirect_pieced_value (struct value *value)
 {
-  struct piece_closure *c
+  struct piece_closure *closure
     = (struct piece_closure *) value_computed_closure (value);
-  struct type *type;
-  struct frame_info *frame;
-  int i, bit_length;
-  LONGEST bit_offset;
-  struct dwarf_expr_piece *piece = NULL;
-  LONGEST byte_offset;
-  enum bfd_endian byte_order;
-
-  type = check_typedef (value_type (value));
+
+  struct type *type = check_typedef (value_type (value));
   if (type->code () != TYPE_CODE_PTR)
     return NULL;
 
-  bit_length = 8 * TYPE_LENGTH (type);
-  bit_offset = 8 * value_offset (value);
+  LONGEST bit_length = HOST_CHAR_BIT * TYPE_LENGTH (type);
+  LONGEST bit_offset = HOST_CHAR_BIT * value_offset (value);
+
   if (value_bitsize (value))
     bit_offset += value_bitpos (value);
 
-  for (i = 0; i < c->pieces.size () && bit_length > 0; i++)
-    {
-      struct dwarf_expr_piece *p = &c->pieces[i];
-      size_t this_size_bits = p->size;
-
-      if (bit_offset > 0)
-	{
-	  if (bit_offset >= this_size_bits)
-	    {
-	      bit_offset -= this_size_bits;
-	      continue;
-	    }
-
-	  bit_length -= this_size_bits - bit_offset;
-	  bit_offset = 0;
-	}
-      else
-	bit_length -= this_size_bits;
-
-      if (p->location != DWARF_VALUE_IMPLICIT_POINTER)
-	return NULL;
-
-      if (bit_length != 0)
-	error (_("Invalid use of DW_OP_implicit_pointer"));
+  dwarf_location *location = closure->location;
 
-      piece = p;
-      break;
-    }
+  /* Only location descriptions are meaningful here.  */
+  if (location == nullptr)
+    return NULL;
 
-  gdb_assert (piece != NULL && c->per_cu != nullptr);
-  frame = get_selected_frame (_("No frame selected."));
+  struct frame_info *frame = get_selected_frame (_("No frame selected."));
 
   /* This is an offset requested by GDB, such as value subscripts.
      However, due to how synthetic pointers are implemented, this is
@@ -1796,14 +1713,13 @@ indirect_pieced_value (struct value *value)
      the later would go through gdbarch_pointer_to_address and thus
      return a CORE_ADDR with high bits set on architectures that
      encode address spaces and other things in CORE_ADDR.  */
-  byte_order = gdbarch_byte_order (get_frame_arch (frame));
-  byte_offset = extract_signed_integer (value_contents (value),
-					TYPE_LENGTH (type), byte_order);
-  byte_offset += piece->v.ptr.offset;
+  enum bfd_endian byte_order = gdbarch_byte_order (get_frame_arch (frame));
+  LONGEST indirect_offset
+    = extract_signed_integer (value_contents (value),
+			      TYPE_LENGTH (type), byte_order);
 
-  return indirect_synthetic_pointer (piece->v.ptr.die_sect_off,
-				     byte_offset, c->per_cu,
-				     c->per_objfile, frame, type);
+  return indirect_from_location (location, frame, type, indirect_offset,
+				 bit_offset, bit_length);
 }
 
 /* Implementation of the coerce_ref method of lval_funcs for synthetic C++
@@ -1817,20 +1733,23 @@ coerce_pieced_ref (const struct value *value)
   if (value_bits_synthetic_pointer (value, value_embedded_offset (value),
 				    TARGET_CHAR_BIT * TYPE_LENGTH (type)))
     {
-      const struct piece_closure *closure
+      struct piece_closure *closure
 	= (struct piece_closure *) value_computed_closure (value);
       struct frame_info *frame
 	= get_selected_frame (_("No frame selected."));
 
-      /* gdb represents synthetic pointers as pieced values with a single
-	 piece.  */
-      gdb_assert (closure != NULL);
-      gdb_assert (closure->pieces.size () == 1);
+      auto pointer_entry
+	= dynamic_cast<dwarf_implicit_pointer *> (closure->location);
 
-      return indirect_synthetic_pointer
-	(closure->pieces[0].v.ptr.die_sect_off,
-	 closure->pieces[0].v.ptr.offset,
-	 closure->per_cu, closure->per_objfile, frame, type);
+      /* Only implicit pointer location description is meaningful here.  */
+      if (pointer_entry == nullptr)
+	return NULL;
+
+      return indirect_synthetic_pointer (pointer_entry->get_die_offset (),
+					 pointer_entry->get_offset (),
+					 closure->per_cu,
+					 closure->per_objfile,
+					 frame, type);
     }
   else
     {
@@ -1858,10 +1777,7 @@ free_pieced_value_closure (struct value *v)
   --c->refc;
   if (c->refc == 0)
     {
-      for (dwarf_expr_piece &p : c->pieces)
-	if (p.location == DWARF_VALUE_STACK)
-	  value_decref (p.v.value);
-
+      c->location->decref ();
       delete c;
     }
 }
@@ -1951,34 +1867,38 @@ dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile,
   ref_addr_size (0),
   recursion_depth (0),
   max_recursion_depth (0x100),
-  location (DWARF_VALUE_MEMORY),
-  len (0),
-  data (NULL),
-  initialized (0),
   per_objfile (per_objfile),
   frame (nullptr),
   per_cu (nullptr),
   addr_info (nullptr)
 {
+  entry_factory = new dwarf_entry_factory ();
 }
 
-/* Push VALUE onto the stack.  */
+/* See expr.h.  */
+
+dwarf_expr_context::~dwarf_expr_context ()
+{
+  delete entry_factory;
+}
+
+/* See expr.h.  */
 
 void
-dwarf_expr_context::push (struct value *value, bool in_stack_memory)
+dwarf_expr_context::push (dwarf_entry *entry)
 {
-  stack.emplace_back (value, in_stack_memory);
+  stack.emplace_back (entry);
 }
 
-/* Push VALUE onto the stack.  */
+/* See expr.h.  */
 
 void
-dwarf_expr_context::push_address (CORE_ADDR value, bool in_stack_memory)
+dwarf_expr_context::push_address (CORE_ADDR addr, bool in_stack_memory)
 {
-  push (value_from_ulongest (address_type (), value), in_stack_memory);
+  stack.emplace_back (entry_factory->create_memory (addr, 0, in_stack_memory));
 }
 
-/* Pop the top item off of the stack.  */
+/* See expr.h.  */
 
 void
 dwarf_expr_context::pop ()
@@ -1989,16 +1909,16 @@ dwarf_expr_context::pop ()
   stack.pop_back ();
 }
 
-/* Retrieve the N'th item on the stack.  */
+/* See expr.h.  */
 
-struct value *
+dwarf_entry *
 dwarf_expr_context::fetch (int n)
 {
   if (stack.size () <= n)
      error (_("Asked for position %d of stack, "
 	      "stack only has %zu elements on it."),
 	    n, stack.size ());
-  return stack[stack.size () - (1 + n)].value;
+  return stack[stack.size () - (1 + n)];
 }
 
 /* See expr.h.  */
@@ -2075,31 +1995,6 @@ dwarf_expr_context::dwarf_call (cu_offset die_cu_off)
 
 /* See expr.h.  */
 
-void
-dwarf_expr_context::read_mem (gdb_byte *buf, CORE_ADDR addr,
-			      size_t length)
-{
-  if (length == 0)
-    return;
-
-  /* Prefer the passed-in memory, if it exists.  */
-  if (addr_info != nullptr)
-    {
-      CORE_ADDR offset = addr - addr_info->addr;
-
-      if (offset < addr_info->valaddr.size ()
-	  && offset + length <= addr_info->valaddr.size ())
-    {
-      memcpy (buf, addr_info->valaddr.data (), length);
-      return;
-    }
-    }
-
-  read_memory (addr, buf, length);
-}
-
-/* See expr.h.  */
-
 void
 dwarf_expr_context::push_dwarf_reg_entry_value
 		      (enum call_site_parameter_kind kind,
@@ -2157,180 +2052,284 @@ dwarf_expr_context::fetch_result (struct type *type,
 				  LONGEST subobj_offset,
 				  bool as_lval)
 {
-  struct value *retval = nullptr;
-
   if (type == nullptr)
     type = address_type ();
 
   if (subobj_type == nullptr)
     subobj_type = type;
 
-  if (this->pieces.size () > 0)
+  dwarf_entry *entry = fetch (0);
+
+  if (!as_lval)
+    entry = entry_factory->entry_to_value (entry, address_type ());
+   else
+    entry = entry_factory->entry_to_location (entry);
+
+  return dwarf_entry_to_gdb_value (entry, type, subobj_type, subobj_offset);
+}
+
+/* See expr.h.  */
+
+struct value *
+dwarf_expr_context::eval_exp (const gdb_byte *addr, size_t len, bool as_lval,
+			      struct dwarf2_per_cu_data *per_cu,
+			      struct frame_info *frame,
+			      const struct property_addr_info *addr_info,
+			      struct type *type,
+			      struct type *subobj_type,
+			      LONGEST subobj_offset)
+{
+  this->per_cu = per_cu;
+  this->frame = frame;
+  this->addr_info = addr_info;
+
+  if (per_cu != nullptr)
+    this->ref_addr_size = per_cu->ref_addr_size ();
+
+  eval (addr, len);
+  return fetch_result (type, subobj_type, subobj_offset, as_lval);
+}
+
+/* See expr.h.  */
+
+dwarf_entry *
+dwarf_expr_context::dwarf_entry_deref (dwarf_entry *entry,
+				       struct type *type, size_t size)
+{
+  bool big_endian = type_byte_order (type) == BFD_ENDIAN_BIG;
+  dwarf_location *location = entry_factory->entry_to_location (entry);
+  size_t actual_size = size != 0 ? size : TYPE_LENGTH (type);
+
+  if (actual_size > TYPE_LENGTH (type))
+    ill_formed_expression ();
+
+  /* If the size of the object read from memory is different
+     from the type length, we need to zero-extend it.  */
+  gdb::byte_vector read_buf (TYPE_LENGTH (type), 0);
+  size_t size_in_bits = actual_size * HOST_CHAR_BIT;
+  gdb_byte *buf_ptr = read_buf.data();
+  bool passed_in_buf = false;
+
+  if (big_endian)
+    buf_ptr += TYPE_LENGTH (type) - actual_size;
+
+  if (auto memory_entry = dynamic_cast<dwarf_memory *> (location))
     {
-      struct piece_closure *c;
-      ULONGEST bit_size = 0;
+      /* Covers the case where we have a passed in memory that is not
+	 part of the target and requires for the location description
+	 to address it instead of addressing the actual target
+	 memory.  */
+      CORE_ADDR start_address = memory_entry->get_offset ();
+      LONGEST bit_suboffset = location->get_bit_suboffset ();
+      LONGEST this_size = bits_to_bytes (bit_suboffset, size_in_bits);
+
+      /* We shouldn't have a case where we read from a passed in
+	 memory and the same memory being marked as stack. */
+      if (!memory_entry->in_stack () && this_size && addr_info != nullptr)
+	{
+	  CORE_ADDR offset = start_address - addr_info->addr;
 
-      for (dwarf_expr_piece &piece : this->pieces)
-	bit_size += piece.size;
-      /* Complain if the expression is larger than the size of the
-	 outer type.  */
-      if (bit_size > 8 * TYPE_LENGTH (type))
-	invalid_synthetic_pointer ();
+	  /* Using second buffer here because the copy_bitwise
+	     doesn't support in place copy.  */
+	  gdb::byte_vector temp_buf (this_size);
 
-      c = allocate_piece_closure (this->per_cu, this->per_objfile,
-				  std::move (this->pieces), this->frame);
-      retval = allocate_computed_value (subobj_type,
-					&pieced_value_funcs, c);
-      set_value_offset (retval, subobj_offset);
+	  if (offset < addr_info->valaddr.size ()
+	      && offset + this_size <= addr_info->valaddr.size ())
+	    {
+	      memcpy (temp_buf.data (), addr_info->valaddr.data (), this_size);
+	      copy_bitwise (buf_ptr, 0, temp_buf.data (),
+			    bit_suboffset, size_in_bits,
+			    big_endian);
+	      passed_in_buf = true;
+	    }
+	}
     }
-  else
+
+  if (!passed_in_buf)
     {
-      /* If AS_LVAL is false, means that the implicit conversion
-	 from a location description to value is expected.  */
-      if (as_lval == false)
-	this->location = DWARF_VALUE_STACK;
+      int optimized, unavailable;
+
+      read_from_location (location, this->frame, 0, buf_ptr, 0, size_in_bits,
+			  0, big_endian, &optimized, &unavailable);
+
+      if (optimized)
+	throw_error (OPTIMIZED_OUT_ERROR,
+		     _("Can't do read-modify-write to "
+		       "update bitfield; containing word "
+		       "has been optimized out"));
+      if (unavailable)
+	throw_error (NOT_AVAILABLE_ERROR,
+		     _("Can't dereference "
+		       "update bitfield; containing word "
+		       "is unavailable"));
+    }
 
-      switch (this->location)
-	{
-	case DWARF_VALUE_REGISTER:
-	  {
-	    int dwarf_regnum
-	      = longest_to_int (value_as_long (this->fetch (0)));
-	    int gdb_regnum = dwarf_reg_to_regnum_or_error (this->gdbarch,
-							   dwarf_regnum);
+  return entry_factory->create_value (read_buf.data (), type);
+}
 
-	    if (subobj_offset != 0)
-	      error (_("cannot use offset on synthetic pointer to register"));
+/* See expr.h.  */
 
-	    gdb_assert (this->frame != NULL);
+dwarf_entry *
+dwarf_expr_context::gdb_value_to_dwarf_entry (struct value *value)
+{
+  if (value_optimized_out (value))
+    return entry_factory->create_undefined ();
 
-	    retval = value_from_register (subobj_type, gdb_regnum,
-					  this->frame);
-	    if (value_optimized_out (retval))
-	      {
-		struct value *tmp;
-
-		/* This means the register has undefined value / was
-		   not saved.  As we're computing the location of some
-		   variable etc. in the program, not a value for
-		   inspecting a register ($pc, $sp, etc.), return a
-		   generic optimized out value instead, so that we show
-		   <optimized out> instead of <not saved>.  */
-		tmp = allocate_value (subobj_type);
-		value_contents_copy (tmp, 0, retval, 0,
-				     TYPE_LENGTH (subobj_type));
-		retval = tmp;
-	      }
-	  }
-	  break;
+  LONGEST offset = value_offset (value);
 
-	case DWARF_VALUE_MEMORY:
-	  {
-	    struct type *ptr_type;
-	    CORE_ADDR address = this->fetch_address (0);
-	    bool in_stack_memory = this->fetch_in_stack_memory (0);
-
-	    /* DW_OP_deref_size (and possibly other operations too) may
-	       create a pointer instead of an address.  Ideally, the
-	       pointer to address conversion would be performed as part
-	       of those operations, but the type of the object to
-	       which the address refers is not known at the time of
-	       the operation.  Therefore, we do the conversion here
-	       since the type is readily available.  */
-
-	    switch (subobj_type->code ())
-	      {
-		case TYPE_CODE_FUNC:
-		case TYPE_CODE_METHOD:
-		  ptr_type = builtin_type (this->gdbarch)->builtin_func_ptr;
-		  break;
-		default:
-		  ptr_type = builtin_type (this->gdbarch)->builtin_data_ptr;
-		  break;
-	      }
-	    address = value_as_address (value_from_pointer (ptr_type, address));
+  switch (value_lval_const (value))
+    {
+      /* We can only convert struct value to a location because we
+	 can't distinguish between the implicit value and
+	 not_lval.  */
+    case not_lval:
+      {
+	gdb_byte *contents_start = value_contents_raw (value) + offset;
+	struct type *type = value_type (value);
 
-	    retval = value_at_lazy (subobj_type,
-				    address + subobj_offset);
-	    if (in_stack_memory)
-	      set_value_stack (retval, 1);
-	  }
-	  break;
+	return entry_factory->create_implicit (contents_start,
+					       TYPE_LENGTH (type),
+					       type_byte_order (type));
+      }
+    case lval_memory:
+      return entry_factory->create_memory (value_address (value) + offset,
+					   0, value_stack (value));
+    case lval_register:
+      return entry_factory->create_register (VALUE_REGNUM (value), offset);
+    case lval_computed:
+      {
+	/* Dwarf entry is enclosed by the closure anyway so we just
+	   need to unwrap it here.  */
+	struct piece_closure *closure
+	  = (struct piece_closure *) value_computed_closure (value);
+	auto location = dynamic_cast<dwarf_location *> (closure->location);
 
-	case DWARF_VALUE_STACK:
-	  {
-	    struct value *value = this->fetch (0);
-	    size_t n = TYPE_LENGTH (value_type (value));
-	    size_t len = TYPE_LENGTH (subobj_type);
-	    size_t max = TYPE_LENGTH (type);
+	if (location == nullptr)
+	  internal_error (__FILE__, __LINE__, _("invalid closure type"));
 
-	    if (subobj_offset + len > max)
-	      invalid_synthetic_pointer ();
+	location->add_bit_offset (offset * HOST_CHAR_BIT);
+	return location;
+      }
+    default:
+      internal_error (__FILE__, __LINE__, _("invalid location type"));
+  }
+}
 
-	    retval = allocate_value (subobj_type);
+/* See expr.h.  */
 
-	    /* The given offset is relative to the actual object.  */
-	    if (gdbarch_byte_order (this->gdbarch) == BFD_ENDIAN_BIG)
-	      subobj_offset += n - max;
+struct value *
+dwarf_expr_context::dwarf_entry_to_gdb_value (dwarf_entry *entry,
+					      struct type *type,
+					      struct type *subobj_type,
+					      LONGEST subobj_offset)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  struct value *retval = nullptr;
 
-	    memcpy (value_contents_raw (retval),
-		    value_contents_all (value) + subobj_offset, len);
-	  }
-	  break;
+  if (subobj_type == nullptr)
+    subobj_type = type;
 
-	case DWARF_VALUE_LITERAL:
-	  {
-	    bfd_byte *contents;
-	    size_t n = TYPE_LENGTH (subobj_type);
+  if (auto value = dynamic_cast<dwarf_value *> (entry))
+    retval = value_to_gdb_value (value, subobj_type, subobj_offset);
+  else if (dynamic_cast<dwarf_undefined *> (entry) != nullptr)
+    {
+      retval = allocate_value (subobj_type);
+      mark_value_bytes_optimized_out (retval, subobj_offset,
+				      TYPE_LENGTH (subobj_type));
+    }
+  else if (auto memory_entry = dynamic_cast<dwarf_memory *> (entry))
+    {
+      struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+      CORE_ADDR address = memory_entry->get_offset ();
 
-	    if (subobj_offset + n > this->len)
-	      invalid_synthetic_pointer ();
+      if (subobj_type->code () == TYPE_CODE_FUNC
+	  || subobj_type->code () == TYPE_CODE_METHOD)
+	ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
 
-	    retval = allocate_value (subobj_type);
-	    contents = value_contents_raw (retval);
-	    memcpy (contents, this->data + subobj_offset, n);
-	  }
-	  break;
+      address = value_as_address (value_from_pointer (ptr_type, address));
+      retval = value_at_lazy (subobj_type, address + subobj_offset);
+      set_value_stack (retval, memory_entry->in_stack ());
+    }
+  else if (auto register_entry = dynamic_cast<dwarf_register *> (entry))
+    {
+      unsigned int regnum = register_entry->get_regnum ();
+      int gdb_regnum = dwarf_reg_to_regnum_or_error (gdbarch, regnum);
 
-	case DWARF_VALUE_OPTIMIZED_OUT:
-	  retval = allocate_optimized_out_value (subobj_type);
-	  break;
+      /* Construct the value.  */
+      retval = gdbarch_value_from_register (gdbarch, type,
+					    gdb_regnum, get_frame_id (frame));
 
-	  /* DWARF_VALUE_IMPLICIT_POINTER was converted to a pieced
-	     operation by execute_stack_op.  */
-	case DWARF_VALUE_IMPLICIT_POINTER:
-	  /* DWARF_VALUE_OPTIMIZED_OUT can't occur in this context --
-	     it can only be encountered when making a piece.  */
-	default:
-	  internal_error (__FILE__, __LINE__, _("invalid location type"));
+      /* Get the data.  */
+      read_frame_register_value (retval, frame);
+
+      if (value_optimized_out (retval))
+	{
+	  /* This means the register has undefined value / was not saved.
+	     As we're computing the location of some variable etc. in the
+	     program, not a value for inspecting a register ($pc, $sp, etc.),
+	     return a generic optimized out value instead, so that we show
+	     <optimized out> instead of <not saved>.  */
+	  struct value *temp = allocate_value (subobj_type);
+	  value_contents_copy (temp, 0, retval, 0, TYPE_LENGTH (subobj_type));
+	  retval = temp;
 	}
     }
+  else if (auto implicit_entry = dynamic_cast<dwarf_implicit *> (entry))
+    {
+      size_t subtype_len = TYPE_LENGTH (subobj_type);
+      size_t type_len = TYPE_LENGTH (type);
 
-  set_value_initialized (retval, this->initialized);
+      /* To be compatible with expected error output of the existing
+	 tests, the invalid synthetic pointer is not reported for
+	 DW_OP_implicit_value operation.  */
+      if ((subobj_offset + subtype_len > type_len)
+	  && implicit_entry->get_byte_order() != BFD_ENDIAN_UNKNOWN)
+	  invalid_synthetic_pointer ();
 
-  return retval;
-}
+      retval = allocate_value (subobj_type);
 
-/* See expr.h.  */
+      /* The given offset is relative to the actual object.  */
+      if (implicit_entry->get_byte_order() == BFD_ENDIAN_BIG)
+	subobj_offset += implicit_entry->get_size () - type_len;
 
-struct value *
-dwarf_expr_context::eval_exp (const gdb_byte *addr, size_t len, bool as_lval,
-			      struct dwarf2_per_cu_data *per_cu,
-			      struct frame_info *frame,
-			      const struct property_addr_info *addr_info,
-			      struct type *type,
-			      struct type *subobj_type,
-			      LONGEST subobj_offset)
-{
-  this->per_cu = per_cu;
-  this->frame = frame;
-  this->addr_info = addr_info;
+      memcpy ((void *)value_contents_raw (retval),
+	      (void *)(implicit_entry->get_contents () + subobj_offset),
+	      subtype_len);
+    }
+  else if (auto implicit_pointer_entry
+	    = dynamic_cast<dwarf_implicit_pointer *> (entry))
+    {
+      struct piece_closure *closure
+	= allocate_piece_closure (this->per_cu, this->per_objfile,
+				  implicit_pointer_entry, this->frame);
 
-  if (per_cu != nullptr)
-    this->ref_addr_size = per_cu->ref_addr_size ();
+      retval
+	= allocate_computed_value (subobj_type, &pieced_value_funcs, closure);
+      set_value_offset (retval, subobj_offset);
+    }
+  else if (auto composite_entry = dynamic_cast<dwarf_composite *> (entry))
+    {
+      size_t pieces_num = composite_entry->get_pieces_num ();
+      ULONGEST bit_size = 0;
 
-  eval (addr, len);
-  return fetch_result (type, subobj_type, subobj_offset, as_lval);
+      for (unsigned int i = 0; i < pieces_num; i++)
+	bit_size += composite_entry->get_bit_size_at (i);
+
+      /* Complain if the expression is larger than the size of the
+	 outer type.  */
+      if (bit_size > HOST_CHAR_BIT * TYPE_LENGTH (type))
+	invalid_synthetic_pointer ();
+
+      struct piece_closure *closure
+	= allocate_piece_closure (this->per_cu, this->per_objfile,
+				  composite_entry, this->frame);
+
+      retval
+	= allocate_computed_value (subobj_type, &pieced_value_funcs, closure);
+      set_value_offset (retval, subobj_offset);
+  }
+
+  return retval;
 }
 
 /* Require that TYPE be an integral type; throw an exception if not.  */
@@ -2388,52 +2387,7 @@ get_signed_type (struct gdbarch *gdbarch, struct type *type)
     }
 }
 
-/* Retrieve the N'th item on the stack, converted to an address.  */
-
-CORE_ADDR
-dwarf_expr_context::fetch_address (int n)
-{
-  struct value *result_val = fetch (n);
-  enum bfd_endian byte_order = gdbarch_byte_order (this->gdbarch);
-  ULONGEST result;
-
-  dwarf_require_integral (value_type (result_val));
-  result = extract_unsigned_integer (value_contents (result_val),
-				     TYPE_LENGTH (value_type (result_val)),
-				     byte_order);
-
-  /* For most architectures, calling extract_unsigned_integer() alone
-     is sufficient for extracting an address.  However, some
-     architectures (e.g. MIPS) use signed addresses and using
-     extract_unsigned_integer() will not produce a correct
-     result.  Make sure we invoke gdbarch_integer_to_address()
-     for those architectures which require it.  */
-  if (gdbarch_integer_to_address_p (this->gdbarch))
-    {
-      gdb_byte *buf = (gdb_byte *) alloca (this->addr_size);
-      struct type *int_type = get_unsigned_type (this->gdbarch,
-						 value_type (result_val));
-
-      store_unsigned_integer (buf, this->addr_size, byte_order, result);
-      return gdbarch_integer_to_address (this->gdbarch, int_type, buf);
-    }
-
-  return (CORE_ADDR) result;
-}
-
-/* Retrieve the in_stack_memory flag of the N'th item on the stack.  */
-
-bool
-dwarf_expr_context::fetch_in_stack_memory (int n)
-{
-  if (stack.size () <= n)
-     error (_("Asked for position %d of stack, "
-	      "stack only has %zu elements on it."),
-	    n, stack.size ());
-  return stack[stack.size () - (1 + n)].in_stack_memory;
-}
-
-/* Return true if the expression stack is empty.  */
+/* See expr.h.  */
 
 bool
 dwarf_expr_context::stack_empty_p () const
@@ -2441,50 +2395,41 @@ dwarf_expr_context::stack_empty_p () const
   return stack.empty ();
 }
 
-/* Add a new piece to the dwarf_expr_context's piece list.  */
-void
-dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
-{
-  this->pieces.emplace_back ();
-  dwarf_expr_piece &p = this->pieces.back ();
+/* See expr.h.  */
 
-  p.location = this->location;
-  p.size = size;
-  p.offset = offset;
+dwarf_entry *
+dwarf_expr_context::add_piece (ULONGEST bit_size, ULONGEST bit_offset)
+{
+  dwarf_location *piece_entry;
+  dwarf_composite *composite_entry;
 
-  if (p.location == DWARF_VALUE_LITERAL)
-    {
-      p.v.literal.data = this->data;
-      p.v.literal.length = this->len;
-    }
-  else if (stack_empty_p ())
+  if (!stack_empty_p ()
+      && dynamic_cast<dwarf_composite *> (fetch (0)) == nullptr)
     {
-      p.location = DWARF_VALUE_OPTIMIZED_OUT;
-      /* Also reset the context's location, for our callers.  This is
-	 a somewhat strange approach, but this lets us avoid setting
-	 the location to DWARF_VALUE_MEMORY in all the individual
-	 cases in the evaluator.  */
-      this->location = DWARF_VALUE_OPTIMIZED_OUT;
+      piece_entry = entry_factory->entry_to_location (fetch (0));
+      pop ();
     }
-  else if (p.location == DWARF_VALUE_MEMORY)
-    {
-      p.v.mem.addr = fetch_address (0);
-      p.v.mem.in_stack_memory = fetch_in_stack_memory (0);
-    }
-  else if (p.location == DWARF_VALUE_IMPLICIT_POINTER)
-    {
-      p.v.ptr.die_sect_off = (sect_offset) this->len;
-      p.v.ptr.offset = value_as_long (fetch (0));
-    }
-  else if (p.location == DWARF_VALUE_REGISTER)
-    p.v.regno = value_as_long (fetch (0));
+  else
+    piece_entry = entry_factory->create_undefined ();
+
+  piece_entry->add_bit_offset (bit_offset);
+
+  /* If stack is empty then it is a start of a new composite.  In the
+     future this will check if the composite is finished or not.  */
+  if (stack_empty_p ()
+      || dynamic_cast<dwarf_composite *> (fetch (0)) == nullptr)
+    composite_entry = entry_factory->create_composite ();
   else
     {
-      p.v.value = fetch (0);
+      composite_entry = dynamic_cast<dwarf_composite *> (fetch (0));
+      pop ();
     }
+
+  composite_entry->add_piece (piece_entry, bit_size);
+  return composite_entry;
 }
 
-/* Evaluate the expression at ADDR (LEN bytes long).  */
+/* See expr.h.  */
 
 void
 dwarf_expr_context::eval (const gdb_byte *addr, size_t len)
@@ -2498,7 +2443,7 @@ dwarf_expr_context::eval (const gdb_byte *addr, size_t len)
   gdb_assert (this->recursion_depth == old_recursion_depth);
 }
 
-/* Helper to read a uleb128 value or throw an error.  */
+/* See expr.h.  */
 
 const gdb_byte *
 safe_read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end,
@@ -2510,7 +2455,7 @@ safe_read_uleb128 (const gdb_byte *buf, const gdb_byte *buf_end,
   return buf;
 }
 
-/* Helper to read a sleb128 value or throw an error.  */
+/* See expr.h.  */
 
 const gdb_byte *
 safe_read_sleb128 (const gdb_byte *buf, const gdb_byte *buf_end,
@@ -2530,11 +2475,8 @@ safe_skip_leb128 (const gdb_byte *buf, const gdb_byte *buf_end)
     error (_("DWARF expression error: ran off end of buffer reading leb128 value"));
   return buf;
 }
-\f
 
-/* Check that the current operator is either at the end of an
-   expression, or that it is followed by a composition operator or by
-   DW_OP_GNU_uninit (which should terminate the expression).  */
+/* See expr.h.  */
 
 void
 dwarf_expr_require_composition (const gdb_byte *op_ptr, const gdb_byte *op_end,
@@ -2562,8 +2504,7 @@ base_types_equal_p (struct type *t1, struct type *t2)
   return TYPE_LENGTH (t1) == TYPE_LENGTH (t2);
 }
 
-/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_reg* return the
-   DWARF register number.  Otherwise return -1.  */
+/* See expr.h.  */
 
 int
 dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end)
@@ -2603,10 +2544,7 @@ dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end)
   return dwarf_reg;
 }
 
-/* If <BUF..BUF_END] contains DW_FORM_block* with just DW_OP_breg*(0) and
-   DW_OP_deref* return the DWARF register number.  Otherwise return -1.
-   DEREF_SIZE_RETURN contains -1 for DW_OP_deref; otherwise it contains the
-   size from DW_OP_deref_size.  */
+/* See expr.h.  */
 
 int
 dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf, const gdb_byte *buf_end,
@@ -2664,8 +2602,7 @@ dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf, const gdb_byte *buf_end,
   return dwarf_reg;
 }
 
-/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_fbreg(X) fill
-   in FB_OFFSET_RETURN with the X offset and return 1.  Otherwise return 0.  */
+/* See expr.h.  */
 
 int
 dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
@@ -2690,9 +2627,7 @@ dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
   return 1;
 }
 
-/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_bregSP(X) fill
-   in SP_OFFSET_RETURN with the X offset and return 1.  Otherwise return 0.
-   The matched SP register number depends on GDBARCH.  */
+/* See expr.h.  */
 
 int
 dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf,
@@ -2732,8 +2667,7 @@ dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf,
   return 1;
 }
 
-/* The engine for the expression evaluator.  Using the context in this
-   object, evaluate the expression between OP_PTR and OP_END.  */
+/* See expr.h.  */
 
 void
 dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
@@ -2749,9 +2683,6 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
      CU.  */
   struct type *address_type = this->address_type ();
 
-  this->location = DWARF_VALUE_MEMORY;
-  this->initialized = 1;  /* Default is initialized.  */
-
   if (this->recursion_depth > this->max_recursion_depth)
     error (_("DWARF-2 expression error: Loop detected (%d)."),
 	   this->recursion_depth);
@@ -2761,16 +2692,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
     {
       enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr++;
       ULONGEST result;
-      /* Assume the value is not in stack memory.
-	 Code that knows otherwise sets this to true.
-	 Some arithmetic on stack addresses can probably be assumed to still
-	 be a stack address, but we skip this complication for now.
-	 This is just an optimization, so it's always ok to punt
-	 and leave this as false.  */
-      bool in_stack_memory = false;
       uint64_t uoffset, reg;
       int64_t offset;
-      struct value *result_val = NULL;
+      struct dwarf_entry *result_entry = NULL;
 
       /* The DWARF expression might have a bug causing an infinite
 	 loop.  In that case, quitting is the only way out.  */
@@ -2811,7 +2735,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	case DW_OP_lit30:
 	case DW_OP_lit31:
 	  result = op - DW_OP_lit0;
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  break;
 
 	case DW_OP_addr:
@@ -2823,8 +2747,14 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	     index, not an address.  We don't support things like
 	     branching between the address and the TLS op.  */
 	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
-	    result += this->per_objfile->objfile->text_section_offset ();
-	  result_val = value_from_ulongest (address_type, result);
+	    {
+	      result += this->per_objfile->objfile->text_section_offset ();
+	      result_entry = entry_factory->create_memory (result);
+	    }
+	  else
+	    /* This is a special case where the value is expected to be
+	       created instead of memory location.  */
+	    result_entry = entry_factory->create_value (result, address_type);
 	  break;
 
 	case DW_OP_addrx:
@@ -2835,7 +2765,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	  result = dwarf2_read_addr_index (this->per_cu, this->per_objfile,
 					   uoffset);
 	  result += this->per_objfile->objfile->text_section_offset ();
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_memory (result);
 	  break;
 	case DW_OP_GNU_const_index:
 	  ensure_have_per_cu (per_cu, "DW_OP_GNU_const_index");
@@ -2843,58 +2773,58 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
 	  result = dwarf2_read_addr_index (this->per_cu, this->per_objfile,
 					   uoffset);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  break;
 
 	case DW_OP_const1u:
 	  result = extract_unsigned_integer (op_ptr, 1, byte_order);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const1s:
 	  result = extract_signed_integer (op_ptr, 1, byte_order);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  op_ptr += 1;
 	  break;
 	case DW_OP_const2u:
 	  result = extract_unsigned_integer (op_ptr, 2, byte_order);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const2s:
 	  result = extract_signed_integer (op_ptr, 2, byte_order);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  op_ptr += 2;
 	  break;
 	case DW_OP_const4u:
 	  result = extract_unsigned_integer (op_ptr, 4, byte_order);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const4s:
 	  result = extract_signed_integer (op_ptr, 4, byte_order);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  op_ptr += 4;
 	  break;
 	case DW_OP_const8u:
 	  result = extract_unsigned_integer (op_ptr, 8, byte_order);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_const8s:
 	  result = extract_signed_integer (op_ptr, 8, byte_order);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  op_ptr += 8;
 	  break;
 	case DW_OP_constu:
 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
 	  result = uoffset;
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  break;
 	case DW_OP_consts:
 	  op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
 	  result = offset;
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_value (result, address_type);
 	  break;
 
 	/* The DW_OP_reg operations are required to occur alone in
@@ -2934,8 +2864,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_reg");
 
 	  result = op - DW_OP_reg0;
-	  result_val = value_from_ulongest (address_type, result);
-	  this->location = DWARF_VALUE_REGISTER;
+	  result_entry = entry_factory->create_register (result);
 	  break;
 
 	case DW_OP_regx:
@@ -2943,8 +2872,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
 
 	  result = reg;
-	  result_val = value_from_ulongest (address_type, result);
-	  this->location = DWARF_VALUE_REGISTER;
+	  result_entry = entry_factory->create_register (reg);
 	  break;
 
 	case DW_OP_implicit_value:
@@ -2954,19 +2882,30 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &len);
 	    if (op_ptr + len > op_end)
 	      error (_("DW_OP_implicit_value: too few bytes available."));
-	    this->len = len;
-	    this->data = op_ptr;
-	    this->location = DWARF_VALUE_LITERAL;
+	    result_entry = entry_factory->create_implicit (op_ptr, len,
+							   BFD_ENDIAN_UNKNOWN);
 	    op_ptr += len;
 	    dwarf_expr_require_composition (op_ptr, op_end,
 					    "DW_OP_implicit_value");
 	  }
-	  goto no_push;
+	  break;
 
 	case DW_OP_stack_value:
-	  this->location = DWARF_VALUE_STACK;
-	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_stack_value");
-	  goto no_push;
+	  {
+	    dwarf_value *value
+	      = entry_factory->entry_to_value (fetch (0), address_type);
+	    pop ();
+
+	    struct type* type = value->get_type ();
+
+	    result_entry
+	      = entry_factory->create_implicit (value->get_contents (),
+						TYPE_LENGTH (type),
+						type_byte_order (type));
+
+	    dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_stack_value");
+	  }
+	  break;
 
 	case DW_OP_implicit_pointer:
 	case DW_OP_GNU_implicit_pointer:
@@ -2975,16 +2914,20 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	    ensure_have_per_cu (per_cu, "DW_OP_implicit_pointer");
 
 	    /* The referred-to DIE of sect_offset kind.  */
-	    this->len = extract_unsigned_integer (op_ptr, this->ref_addr_size,
-						 byte_order);
+	    sect_offset die_offset
+	      = (sect_offset) extract_unsigned_integer (op_ptr,
+							this->ref_addr_size,
+							byte_order);
 	    op_ptr += this->ref_addr_size;
 
 	    /* The byte offset into the data.  */
 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &len);
-	    result = (ULONGEST) len;
-	    result_val = value_from_ulongest (address_type, result);
+	    result_entry
+	      = entry_factory->create_implicit_pointer (this->per_objfile,
+							this->per_cu,
+							this->addr_size,
+							die_offset, len);
 
-	    this->location = DWARF_VALUE_IMPLICIT_POINTER;
 	    dwarf_expr_require_composition (op_ptr, op_end,
 					    "DW_OP_implicit_pointer");
 	  }
@@ -3026,9 +2969,16 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
 	    ensure_have_frame (this->frame, "DW_OP_breg");
 
-	    result = read_addr_from_reg (this->frame, op - DW_OP_breg0);
-	    result += offset;
-	    result_val = value_from_ulongest (address_type, result);
+	    reg = op - DW_OP_breg0;
+
+	    int regnum = dwarf_reg_to_regnum_or_error (this->gdbarch, reg);
+	    ULONGEST reg_size = register_size (this->gdbarch, regnum);
+	    dwarf_location *location = entry_factory->create_register (reg);
+	    result_entry
+	      = dwarf_entry_deref (location, address_type, reg_size);
+	    location = entry_factory->entry_to_location (result_entry);
+	    location->add_bit_offset (offset * HOST_CHAR_BIT);
+	    result_entry = location;
 	  }
 	  break;
 	case DW_OP_bregx:
@@ -3037,51 +2987,56 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
 	    ensure_have_frame (this->frame, "DW_OP_bregx");
 
-	    result = read_addr_from_reg (this->frame, reg);
-	    result += offset;
-	    result_val = value_from_ulongest (address_type, result);
+	    int regnum = dwarf_reg_to_regnum_or_error (this->gdbarch, reg);
+	    ULONGEST reg_size = register_size (this->gdbarch, regnum);
+	    dwarf_location *location = entry_factory->create_register (reg);
+	    result_entry
+	      = dwarf_entry_deref (location, address_type, reg_size);
+	    location = entry_factory->entry_to_location (result_entry);
+	    location->add_bit_offset (offset * HOST_CHAR_BIT);
+	    result_entry = location;
 	  }
 	  break;
 	case DW_OP_fbreg:
 	  {
-	    const gdb_byte *datastart;
-	    size_t datalen;
-
 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
 
 	    /* Rather than create a whole new context, we simply
 	       backup the current stack locally and install a new empty stack,
 	       then reset it afterwards, effectively erasing whatever the
 	       recursive call put there.  */
-	    std::vector<dwarf_stack_value> saved_stack = std::move (stack);
+	    std::vector<dwarf_entry *> saved_stack = std::move (stack);
 	    stack.clear ();
 
-	    /* FIXME: cagney/2003-03-26: This code should be using
-	       get_frame_base_address(), and then implement a dwarf2
-	       specific this_base method.  */
+	    const gdb_byte *datastart;
+	    size_t datalen;
+
 	    this->get_frame_base (&datastart, &datalen);
 	    eval (datastart, datalen);
-	    if (this->location == DWARF_VALUE_MEMORY)
-	      result = fetch_address (0);
-	    else if (this->location == DWARF_VALUE_REGISTER)
-	      result = read_addr_from_reg (this->frame, value_as_long (fetch (0)));
-	    else
-	      error (_("Not implemented: computing frame "
-		       "base using explicit value operator"));
-	    result = result + offset;
-	    result_val = value_from_ulongest (address_type, result);
-	    in_stack_memory = true;
+	    result_entry = fetch (0);
+
+	    if (dynamic_cast<dwarf_register *> (result_entry) != nullptr)
+	      result_entry = dwarf_entry_deref (result_entry, address_type);
+
+	    result_entry = entry_factory->entry_to_location (result_entry);
+	    auto memory_entry = dynamic_cast<dwarf_memory *> (result_entry);
+
+	    /* If we get anything else then memory location here,
+	       the DWARF standard defines the expression as ill formed.  */
+	    if (memory_entry == nullptr)
+	      ill_formed_expression ();
+
+	    memory_entry->add_bit_offset (offset * HOST_CHAR_BIT);
+	    memory_entry->set_stack (true);
+	    result_entry = memory_entry;
 
 	    /* Restore the content of the original stack.  */
 	    stack = std::move (saved_stack);
-
-	    this->location = DWARF_VALUE_MEMORY;
 	  }
 	  break;
 
 	case DW_OP_dup:
-	  result_val = fetch (0);
-	  in_stack_memory = fetch_in_stack_memory (0);
+	  result_entry = fetch (0);
 	  break;
 
 	case DW_OP_drop:
@@ -3090,8 +3045,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 
 	case DW_OP_pick:
 	  offset = *op_ptr++;
-	  result_val = fetch (offset);
-	  in_stack_memory = fetch_in_stack_memory (offset);
+	  result_entry = fetch (offset);
 	  break;
 	  
 	case DW_OP_swap:
@@ -3101,15 +3055,14 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 			"DW_OP_swap.  Need 2, have %zu."),
 		      stack.size ());
 
-	    dwarf_stack_value &t1 = stack[stack.size () - 1];
-	    dwarf_stack_value &t2 = stack[stack.size () - 2];
-	    std::swap (t1, t2);
+	    dwarf_entry *temp = stack[stack.size () - 1];
+	    stack[stack.size () - 1] = stack[stack.size () - 2];
+	    stack[stack.size () - 2] = temp;
 	    goto no_push;
 	  }
 
 	case DW_OP_over:
-	  result_val = fetch (1);
-	  in_stack_memory = fetch_in_stack_memory (1);
+	  result_entry = fetch (1);
 	  break;
 
 	case DW_OP_rot:
@@ -3119,7 +3072,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 			"DW_OP_rot.  Need 3, have %zu."),
 		      stack.size ());
 
-	    dwarf_stack_value temp = stack[stack.size () - 1];
+	    dwarf_entry *temp = stack[stack.size () - 1];
 	    stack[stack.size () - 1] = stack[stack.size () - 2];
 	    stack[stack.size () - 2] = stack[stack.size () - 3];
 	    stack[stack.size () - 3] = temp;
@@ -3132,38 +3085,20 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	case DW_OP_GNU_deref_type:
 	  {
 	    int addr_size = (op == DW_OP_deref ? this->addr_size : *op_ptr++);
-	    gdb_byte *buf = (gdb_byte *) alloca (addr_size);
-	    CORE_ADDR addr = fetch_address (0);
-	    struct type *type;
-
-	    pop ();
+	    struct type *type = address_type;
 
 	    if (op == DW_OP_deref_type || op == DW_OP_GNU_deref_type)
 	      {
 		op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
 		cu_offset type_die_cu_off = (cu_offset) uoffset;
 		type = get_base_type (type_die_cu_off, 0);
-	      }
-	    else
-	      type = address_type;
-
-	    this->read_mem (buf, addr, addr_size);
-
-	    /* If the size of the object read from memory is different
-	       from the type length, we need to zero-extend it.  */
-	    if (TYPE_LENGTH (type) != addr_size)
-	      {
-		ULONGEST datum =
-		  extract_unsigned_integer (buf, addr_size, byte_order);
-
-		buf = (gdb_byte *) alloca (TYPE_LENGTH (type));
-		store_unsigned_integer (buf, TYPE_LENGTH (type),
-					byte_order, datum);
+		addr_size = TYPE_LENGTH (type);
 	      }
 
-	    result_val = value_from_contents_and_address (type, buf, addr);
-	    break;
+	    result_entry = dwarf_entry_deref (fetch (0), type, addr_size);
+	    pop ();
 	  }
+	  break;
 
 	case DW_OP_abs:
 	case DW_OP_neg:
@@ -3171,31 +3106,37 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	case DW_OP_plus_uconst:
 	  {
 	    /* Unary operations.  */
-	    result_val = fetch (0);
+	    dwarf_value *arg
+	      = entry_factory->entry_to_value (fetch (0), address_type);
 	    pop ();
 
 	    switch (op)
 	      {
 	      case DW_OP_abs:
-		if (value_less (result_val,
-				value_zero (value_type (result_val), not_lval)))
-		  result_val = value_neg (result_val);
+		{
+		  struct value *arg_value
+		    = value_to_gdb_value (arg, arg->get_type ());
+
+		  if (value_less (arg_value,
+				  value_zero (arg->get_type (), not_lval)))
+		    arg = entry_factory->value_negation_op (arg);
+		}
 		break;
 	      case DW_OP_neg:
-		result_val = value_neg (result_val);
+		arg = entry_factory->value_negation_op (arg);
 		break;
 	      case DW_OP_not:
-		dwarf_require_integral (value_type (result_val));
-		result_val = value_complement (result_val);
+		dwarf_require_integral (arg->get_type ());
+		arg = entry_factory->value_complement_op (arg);
 		break;
 	      case DW_OP_plus_uconst:
-		dwarf_require_integral (value_type (result_val));
-		result = value_as_long (result_val);
+		dwarf_require_integral (arg->get_type ());
 		op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
-		result += reg;
-		result_val = value_from_ulongest (address_type, result);
+		result = arg->to_long () + reg;
+		arg = entry_factory->create_value (result, address_type);
 		break;
 	      }
+	    result_entry = arg;
 	  }
 	  break;
 
@@ -3218,34 +3159,39 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	case DW_OP_ne:
 	  {
 	    /* Binary operations.  */
-	    struct value *first, *second;
-
-	    second = fetch (0);
+	    dwarf_value *arg2
+	      = entry_factory->entry_to_value (fetch (0), address_type);
 	    pop ();
 
-	    first = fetch (0);
+	    dwarf_value *arg1
+	      = entry_factory->entry_to_value (fetch (0), address_type);
 	    pop ();
 
-	    if (! base_types_equal_p (value_type (first), value_type (second)))
+	    if (! base_types_equal_p (arg1->get_type (), arg2->get_type ()))
 	      error (_("Incompatible types on DWARF stack"));
 
+	    dwarf_value *op_result;
+
 	    switch (op)
 	      {
 	      case DW_OP_and:
-		dwarf_require_integral (value_type (first));
-		dwarf_require_integral (value_type (second));
-		result_val = value_binop (first, second, BINOP_BITWISE_AND);
+		dwarf_require_integral (arg1->get_type ());
+		dwarf_require_integral (arg2->get_type ());
+		op_result = entry_factory->value_binary_op (arg1, arg2,
+							    BINOP_BITWISE_AND);
 		break;
 	      case DW_OP_div:
-		result_val = value_binop (first, second, BINOP_DIV);
+		op_result
+		  = entry_factory->value_binary_op (arg1, arg2, BINOP_DIV);
 		break;
 	      case DW_OP_minus:
-		result_val = value_binop (first, second, BINOP_SUB);
+		op_result
+		  = entry_factory->value_binary_op (arg1, arg2, BINOP_SUB);
 		break;
 	      case DW_OP_mod:
 		{
 		  int cast_back = 0;
-		  struct type *orig_type = value_type (first);
+		  struct type *orig_type = arg1->get_type ();
 
 		  /* We have to special-case "old-style" untyped values
 		     -- these must have mod computed using unsigned
@@ -3256,102 +3202,113 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 			= get_unsigned_type (this->gdbarch, orig_type);
 
 		      cast_back = 1;
-		      first = value_cast (utype, first);
-		      second = value_cast (utype, second);
+		      arg1 = entry_factory->value_cast_op (arg1, utype);
+		      arg2 = entry_factory->value_cast_op (arg2, utype);
 		    }
 		  /* Note that value_binop doesn't handle float or
 		     decimal float here.  This seems unimportant.  */
-		  result_val = value_binop (first, second, BINOP_MOD);
+		  op_result
+		    = entry_factory->value_binary_op (arg1, arg2, BINOP_MOD);
 		  if (cast_back)
-		    result_val = value_cast (orig_type, result_val);
+		    op_result
+		      = entry_factory->value_cast_op (op_result, orig_type);
 		}
 		break;
 	      case DW_OP_mul:
-		result_val = value_binop (first, second, BINOP_MUL);
+		op_result
+		  = entry_factory->value_binary_op (arg1, arg2, BINOP_MUL);
 		break;
 	      case DW_OP_or:
-		dwarf_require_integral (value_type (first));
-		dwarf_require_integral (value_type (second));
-		result_val = value_binop (first, second, BINOP_BITWISE_IOR);
+		dwarf_require_integral (arg1->get_type ());
+		dwarf_require_integral (arg2->get_type ());
+		op_result = entry_factory->value_binary_op (arg1, arg2,
+							    BINOP_BITWISE_IOR);
 		break;
 	      case DW_OP_plus:
-		result_val = value_binop (first, second, BINOP_ADD);
+		op_result
+		  = entry_factory->value_binary_op (arg1, arg2, BINOP_ADD);
 		break;
 	      case DW_OP_shl:
-		dwarf_require_integral (value_type (first));
-		dwarf_require_integral (value_type (second));
-		result_val = value_binop (first, second, BINOP_LSH);
+		dwarf_require_integral (arg1->get_type ());
+		dwarf_require_integral (arg2->get_type ());
+		op_result
+		  = entry_factory->value_binary_op (arg1, arg2, BINOP_LSH);
 		break;
 	      case DW_OP_shr:
-		dwarf_require_integral (value_type (first));
-		dwarf_require_integral (value_type (second));
-		if (!value_type (first)->is_unsigned ())
+		dwarf_require_integral (arg1->get_type ());
+		dwarf_require_integral (arg2->get_type ());
+		if (!arg1->get_type ()->is_unsigned ())
 		  {
 		    struct type *utype
-		      = get_unsigned_type (this->gdbarch, value_type (first));
+		      = get_unsigned_type (this->gdbarch, arg1->get_type ());
 
-		    first = value_cast (utype, first);
+		    arg1 = entry_factory->value_cast_op (arg1, utype);
 		  }
 
-		result_val = value_binop (first, second, BINOP_RSH);
+		op_result
+		  = entry_factory->value_binary_op (arg1, arg2, BINOP_RSH);
 		/* Make sure we wind up with the same type we started
 		   with.  */
-		if (value_type (result_val) != value_type (second))
-		  result_val = value_cast (value_type (second), result_val);
+		if (op_result->get_type () != arg2->get_type ())
+		  op_result = entry_factory->value_cast_op (op_result,
+							    arg2->get_type ());
 		break;
 	      case DW_OP_shra:
-		dwarf_require_integral (value_type (first));
-		dwarf_require_integral (value_type (second));
-		if (value_type (first)->is_unsigned ())
+		dwarf_require_integral (arg1->get_type ());
+		dwarf_require_integral (arg2->get_type ());
+		if (arg1->get_type ()->is_unsigned ())
 		  {
 		    struct type *stype
-		      = get_signed_type (this->gdbarch, value_type (first));
+		      = get_signed_type (this->gdbarch, arg1->get_type ());
 
-		    first = value_cast (stype, first);
+		    arg1 = entry_factory->value_cast_op (arg1, stype);
 		  }
 
-		result_val = value_binop (first, second, BINOP_RSH);
-		/* Make sure we wind up with the same type we started
-		   with.  */
-		if (value_type (result_val) != value_type (second))
-		  result_val = value_cast (value_type (second), result_val);
+		op_result
+		  = entry_factory->value_binary_op (arg1, arg2, BINOP_RSH);
+		/* Make sure we wind up with the same type we started  with.  */
+		if (op_result->get_type () != arg2->get_type ())
+		  op_result = entry_factory->value_cast_op (op_result,
+							    arg2->get_type ());
 		break;
 	      case DW_OP_xor:
-		dwarf_require_integral (value_type (first));
-		dwarf_require_integral (value_type (second));
-		result_val = value_binop (first, second, BINOP_BITWISE_XOR);
+		dwarf_require_integral (arg1->get_type ());
+		dwarf_require_integral (arg2->get_type ());
+		op_result = entry_factory->value_binary_op (arg1, arg2,
+							    BINOP_BITWISE_XOR);
 		break;
 	      case DW_OP_le:
 		/* A <= B is !(B < A).  */
-		result = ! value_less (second, first);
-		result_val = value_from_ulongest (address_type, result);
+		result = ! dwarf_value_less_op (arg2, arg1);
+		op_result = entry_factory->create_value (result, address_type);
 		break;
 	      case DW_OP_ge:
 		/* A >= B is !(A < B).  */
-		result = ! value_less (first, second);
-		result_val = value_from_ulongest (address_type, result);
+		result = ! dwarf_value_less_op (arg1, arg2);
+		op_result = entry_factory->create_value (result, address_type);
 		break;
 	      case DW_OP_eq:
-		result = value_equal (first, second);
-		result_val = value_from_ulongest (address_type, result);
+		result = dwarf_value_equal_op (arg1, arg2);
+		op_result = entry_factory->create_value (result, address_type);
 		break;
 	      case DW_OP_lt:
-		result = value_less (first, second);
-		result_val = value_from_ulongest (address_type, result);
+		result = dwarf_value_less_op (arg1, arg2);
+		op_result = entry_factory->create_value (result, address_type);
 		break;
 	      case DW_OP_gt:
 		/* A > B is B < A.  */
-		result = value_less (second, first);
-		result_val = value_from_ulongest (address_type, result);
+		result = dwarf_value_less_op (arg2, arg1);
+		op_result = entry_factory->create_value (result, address_type);
 		break;
 	      case DW_OP_ne:
-		result = ! value_equal (first, second);
-		result_val = value_from_ulongest (address_type, result);
+		result = ! dwarf_value_equal_op (arg1, arg2);
+		op_result = entry_factory->create_value (result, address_type);
 		break;
 	      default:
 		internal_error (__FILE__, __LINE__,
 				_("Can't be reached."));
 	      }
+	    result_entry = op_result;
 	  }
 	  break;
 
@@ -3359,8 +3316,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	  ensure_have_frame (this->frame, "DW_OP_call_frame_cfa");
 
 	  result = dwarf2_frame_cfa (this->frame);
-	  result_val = value_from_ulongest (address_type, result);
-	  in_stack_memory = true;
+	  result_entry = entry_factory->create_memory (result, 0, true);
 	  break;
 
 	case DW_OP_GNU_push_tls_address:
@@ -3373,11 +3329,13 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	  control block at which the variable is located.  Nothing
 	  should follow this operator, so the top of stack would be
 	  returned.  */
-	  result = value_as_long (fetch (0));
+	  result
+	    = entry_factory->entry_to_value (fetch (0),
+					     address_type)->to_long ();
 	  pop ();
 	  result = target_translate_tls_address (this->per_objfile->objfile,
 						 result);
-	  result_val = value_from_ulongest (address_type, result);
+	  result_entry = entry_factory->create_memory (result);
 	  break;
 
 	case DW_OP_skip:
@@ -3388,13 +3346,13 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 
 	case DW_OP_bra:
 	  {
-	    struct value *val;
+	    dwarf_value *dwarf_value
+	      = entry_factory->entry_to_value (fetch (0), address_type);
 
 	    offset = extract_signed_integer (op_ptr, 2, byte_order);
 	    op_ptr += 2;
-	    val = fetch (0);
-	    dwarf_require_integral (value_type (val));
-	    if (value_as_long (val) != 0)
+	    dwarf_require_integral (dwarf_value->get_type ());
+	    if (dwarf_value->to_long () != 0)
 	      op_ptr += offset;
 	    pop ();
 	  }
@@ -3409,16 +3367,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 
 	    /* Record the piece.  */
 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &size);
-	    add_piece (8 * size, 0);
-
-	    /* Pop off the address/regnum, and reset the location
-	       type.  */
-	    if (this->location != DWARF_VALUE_LITERAL
-		&& this->location != DWARF_VALUE_OPTIMIZED_OUT)
-	      pop ();
-	    this->location = DWARF_VALUE_MEMORY;
+	    result_entry = add_piece (HOST_CHAR_BIT * size, 0);
 	  }
-	  goto no_push;
+	  break;
 
 	case DW_OP_bit_piece:
 	  {
@@ -3427,23 +3378,24 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	    /* Record the piece.  */
 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &size);
 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &uleb_offset);
-	    add_piece (size, uleb_offset);
-
-	    /* Pop off the address/regnum, and reset the location
-	       type.  */
-	    if (this->location != DWARF_VALUE_LITERAL
-		&& this->location != DWARF_VALUE_OPTIMIZED_OUT)
-	      pop ();
-	    this->location = DWARF_VALUE_MEMORY;
+	    result_entry = add_piece (size, uleb_offset);
 	  }
-	  goto no_push;
+	  break;
 
 	case DW_OP_GNU_uninit:
-	  if (op_ptr != op_end)
-	    error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always "
-		   "be the very last op."));
+	  {
+	    if (op_ptr != op_end)
+	      error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always "
+		     "be the very last op."));
 
-	  this->initialized = 0;
+	    auto location = dynamic_cast<dwarf_location *> (fetch (0));
+
+	    if (location == nullptr)
+	      ill_formed_expression ();
+
+	    location->set_initialised (false);
+	    result_entry = location;
+	  }
 	  goto no_push;
 
 	case DW_OP_call2:
@@ -3473,9 +3425,16 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 							this->ref_addr_size,
 							byte_order);
 	    op_ptr += this->ref_addr_size;
-	    result_val = sect_variable_value (sect_off, this->per_cu,
-					      this->per_objfile);
-	    result_val = value_cast (address_type, result_val);
+	    struct value *value
+	      = sect_variable_value (sect_off, per_cu, per_objfile);
+	    value = value_cast (address_type, value);
+
+	    result_entry = gdb_value_to_dwarf_entry (value);
+
+	    if (dynamic_cast<dwarf_undefined *> (result_entry) != nullptr)
+	      error_value_optimized_out ();
+	    else
+	      result_entry = dwarf_entry_deref (result_entry, address_type);
 	  }
 	  break;
 	
@@ -3483,7 +3442,6 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	case DW_OP_GNU_entry_value:
 	  {
 	    uint64_t len;
-	    CORE_ADDR deref_size;
 	    union call_site_parameter_u kind_u;
 
 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &len);
@@ -3500,6 +3458,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 		goto no_push;
 	      }
 
+	    CORE_ADDR deref_size;
+
 	    kind_u.dwarf_reg = dwarf_block_to_dwarf_reg_deref (op_ptr,
 							       op_ptr + len,
 							       &deref_size);
@@ -3534,19 +3494,16 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	case DW_OP_const_type:
 	case DW_OP_GNU_const_type:
 	  {
-	    int n;
-	    const gdb_byte *data;
-	    struct type *type;
-
 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
 	    cu_offset type_die_cu_off = (cu_offset) uoffset;
 
-	    n = *op_ptr++;
-	    data = op_ptr;
+	    int n = *op_ptr++;
+	    const gdb_byte *data = op_ptr;
 	    op_ptr += n;
 
-	    type = get_base_type (type_die_cu_off, n);
-	    result_val = value_from_contents (type, data);
+	    struct type *type = get_base_type (type_die_cu_off, n);
+	    result_entry
+	      = entry_factory->create_value (data, type);
 	  }
 	  break;
 
@@ -3558,12 +3515,11 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	    cu_offset type_die_cu_off = (cu_offset) uoffset;
 
 	    ensure_have_frame (this->frame, "DW_OP_regval_type");
-
 	    struct type *type = get_base_type (type_die_cu_off, 0);
-	    int regnum
-	      = dwarf_reg_to_regnum_or_error (get_frame_arch (this->frame),
-					      reg);
-	    result_val = value_from_register (type, regnum, this->frame);
+
+	    dwarf_register *register_descr
+	      = entry_factory->create_register (reg);
+	    result_entry = dwarf_entry_deref (register_descr, type);
 	  }
 	  break;
 
@@ -3572,42 +3528,45 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	case DW_OP_reinterpret:
 	case DW_OP_GNU_reinterpret:
 	  {
-	    struct type *type;
+	    dwarf_value *dwarf_value
+	      = entry_factory->entry_to_value (fetch (0), address_type);
+
+	    pop ();
 
 	    op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
 	    cu_offset type_die_cu_off = (cu_offset) uoffset;
 
+	    struct type *type;
+
 	    if (to_underlying (type_die_cu_off) == 0)
 	      type = address_type;
 	    else
 	      type = get_base_type (type_die_cu_off, 0);
 
-	    result_val = fetch (0);
-	    pop ();
-
 	    if (op == DW_OP_convert || op == DW_OP_GNU_convert)
-	      result_val = value_cast (type, result_val);
-	    else if (type == value_type (result_val))
+	      dwarf_value = entry_factory->value_cast_op (dwarf_value, type);
+	    else if (type == dwarf_value->get_type ())
 	      {
 		/* Nothing.  */
 	      }
 	    else if (TYPE_LENGTH (type)
-		     != TYPE_LENGTH (value_type (result_val)))
+		     != TYPE_LENGTH (dwarf_value->get_type ()))
 	      error (_("DW_OP_reinterpret has wrong size"));
 	    else
-	      result_val
-		= value_from_contents (type,
-				       value_contents_all (result_val));
+	      dwarf_value
+		= entry_factory->create_value (dwarf_value->get_contents (),
+					       type);
+	    result_entry = dwarf_value;
 	  }
 	  break;
 
 	case DW_OP_push_object_address:
-	  /* Return the address of the object we are currently observing.  */
 	  if (addr_info == nullptr)
 	    error (_("Location address is not set."));
 
-	  result_val
-	    = value_from_ulongest (address_type, this->addr_info->addr);
+	  /* Return the address of the object we are currently observing.  */
+	  result_entry
+	    = entry_factory->create_memory (this->addr_info->addr);
 	  break;
 
 	default:
@@ -3615,18 +3574,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	}
 
       /* Most things push a result value.  */
-      gdb_assert (result_val != NULL);
-      push (result_val, in_stack_memory);
+      gdb_assert (result_entry != NULL);
+      push (result_entry);
     no_push:
       ;
     }
 
-  /* To simplify our main caller, if the result is an implicit
-     pointer, then make a pieced value.  This is ok because we can't
-     have implicit pointers in contexts where pieces are invalid.  */
-  if (this->location == DWARF_VALUE_IMPLICIT_POINTER)
-    add_piece (8 * this->addr_size, 0);
-
   this->recursion_depth--;
   gdb_assert (this->recursion_depth >= 0);
 }
diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h
index 739731daf8..19c28754bb 100644
--- a/gdb/dwarf2/expr.h
+++ b/gdb/dwarf2/expr.h
@@ -25,109 +25,28 @@
 #include "leb128.h"
 #include "gdbtypes.h"
 
+class dwarf_entry;
+class dwarf_entry_factory;
 struct dwarf2_per_objfile;
 
-/* The location of a value.  */
-enum dwarf_value_location
-{
-  /* The piece is in memory.
-     The value on the dwarf stack is its address.  */
-  DWARF_VALUE_MEMORY,
-
-  /* The piece is in a register.
-     The value on the dwarf stack is the register number.  */
-  DWARF_VALUE_REGISTER,
-
-  /* The piece is on the dwarf stack.  */
-  DWARF_VALUE_STACK,
-
-  /* The piece is a literal.  */
-  DWARF_VALUE_LITERAL,
-
-  /* The piece was optimized out.  */
-  DWARF_VALUE_OPTIMIZED_OUT,
-
-  /* The piece is an implicit pointer.  */
-  DWARF_VALUE_IMPLICIT_POINTER
-};
-
-/* A piece of an object, as recorded by DW_OP_piece or DW_OP_bit_piece.  */
-struct dwarf_expr_piece
-{
-  enum dwarf_value_location location;
-
-  union
-  {
-    struct
-    {
-      /* This piece's address, for DWARF_VALUE_MEMORY pieces.  */
-      CORE_ADDR addr;
-      /* Non-zero if the piece is known to be in memory and on
-	 the program's stack.  */
-      bool in_stack_memory;
-    } mem;
-
-    /* The piece's register number, for DWARF_VALUE_REGISTER pieces.  */
-    int regno;
-
-    /* The piece's literal value, for DWARF_VALUE_STACK pieces.  */
-    struct value *value;
-
-    struct
-    {
-      /* A pointer to the data making up this piece,
-	 for DWARF_VALUE_LITERAL pieces.  */
-      const gdb_byte *data;
-      /* The length of the available data.  */
-      ULONGEST length;
-    } literal;
-
-    /* Used for DWARF_VALUE_IMPLICIT_POINTER.  */
-    struct
-    {
-      /* The referent DIE from DW_OP_implicit_pointer.  */
-      sect_offset die_sect_off;
-      /* The byte offset into the resulting data.  */
-      LONGEST offset;
-    } ptr;
-  } v;
-
-  /* The length of the piece, in bits.  */
-  ULONGEST size;
-  /* The piece offset, in bits.  */
-  ULONGEST offset;
-};
-
-/* The dwarf expression stack.  */
-
-struct dwarf_stack_value
-{
-  dwarf_stack_value (struct value *value_, int in_stack_memory_)
-  : value (value_), in_stack_memory (in_stack_memory_)
-  {}
-
-  struct value *value;
-
-  /* True if the piece is in memory and is known to be on the program's stack.
-     It is always ok to set this to zero.  This is used, for example, to
-     optimize memory access from the target.  It can vastly speed up backtraces
-     on long latency connections when "set stack-cache on".  */
-  bool in_stack_memory;
-};
-
 /* The expression evaluator works with a dwarf_expr_context, describing
    its current state and its callbacks.  */
 struct dwarf_expr_context
 {
-  /* We should ever only pass in the PER_OBJFILE, while the ADDR_SIZE
+  /* Create a new context for the expression evaluator.
+
+     We should ever only pass in the PER_OBJFILE and the ADDR_SIZE
      information should be retrievable from there.  The PER_OBJFILE
      contains a pointer to the PER_BFD information anyway and the
      address size information must be the same for the whole BFD.  */
   dwarf_expr_context (struct dwarf2_per_objfile *per_objfile,
 		      int addr_size);
-  virtual ~dwarf_expr_context () = default;
 
-  void push_address (CORE_ADDR value, bool in_stack_memory);
+  /* Destroy dwarf entry factory object.  */
+  virtual ~dwarf_expr_context ();
+
+  /* Push ADDR onto the stack.  */
+  void push_address (CORE_ADDR addr, bool in_stack_memory);
 
   /* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU
      FRAME context.  AS_LVAL defines if the returned struct value is
@@ -146,7 +65,7 @@ struct dwarf_expr_context
 
 private:
   /* The stack of values.  */
-  std::vector<dwarf_stack_value> stack;
+  std::vector<dwarf_entry *> stack;
 
   /* Target architecture to use for address operations.  */
   struct gdbarch *gdbarch;
@@ -154,8 +73,9 @@ struct dwarf_expr_context
   /* Target address size in bytes.  */
   int addr_size;
 
-  /* DW_FORM_ref_addr size in bytes.  If -1 DWARF is executed from a frame
-     context and operations depending on DW_FORM_ref_addr are not allowed.  */
+  /* DW_FORM_ref_addr size in bytes.  If -1 DWARF is executed
+     from a frame context and operations depending on DW_FORM_ref_addr
+     are not allowed.  */
   int ref_addr_size;
 
   /* The current depth of dwarf expression recursion, via DW_OP_call*,
@@ -163,43 +83,6 @@ struct dwarf_expr_context
      depth we'll tolerate before raising an error.  */
   int recursion_depth, max_recursion_depth;
 
-  /* Location of the value.  */
-  enum dwarf_value_location location;
-
-  /* For DWARF_VALUE_LITERAL, the current literal value's length and
-     data.  For DWARF_VALUE_IMPLICIT_POINTER, LEN is the offset of the
-     target DIE of sect_offset kind.  */
-  ULONGEST len;
-  const gdb_byte *data;
-
-  /* Initialization status of variable: Non-zero if variable has been
-     initialized; zero otherwise.  */
-  int initialized;
-
-  /* A vector of pieces.
-
-     Each time DW_OP_piece is executed, we add a new element to the
-     end of this array, recording the current top of the stack, the
-     current location, and the size given as the operand to
-     DW_OP_piece.  We then pop the top value from the stack, reset the
-     location, and resume evaluation.
-
-     The Dwarf spec doesn't say whether DW_OP_piece pops the top value
-     from the stack.  We do, ensuring that clients of this interface
-     expecting to see a value left on the top of the stack (say, code
-     evaluating frame base expressions or CFA's specified with
-     DW_CFA_def_cfa_expression) will get an error if the expression
-     actually marks all the values it computes as pieces.
-
-     If an expression never uses DW_OP_piece, num_pieces will be zero.
-     (It would be nice to present these cases as expressions yielding
-     a single piece, so that callers need not distinguish between the
-     no-DW_OP_piece and one-DW_OP_piece cases.  But expressions with
-     no DW_OP_piece operations have no value to place in a piece's
-     'size' field; the size comes from the surrounding data.  So the
-     two cases need to be handled separately.)  */
-  std::vector<dwarf_expr_piece> pieces;
-
   /* We evaluate the expression in the context of this objfile.  */
   dwarf2_per_objfile *per_objfile;
 
@@ -212,16 +95,40 @@ struct dwarf_expr_context
   /* Property address info used for the evaluation.  */
   const struct property_addr_info *addr_info;
 
+  /* Factory in charge of the dwarf entry's life cycle.  */
+  dwarf_entry_factory *entry_factory;
+
+  /* Evaluate the expression at ADDR (LEN bytes long).  */
   void eval (const gdb_byte *addr, size_t len);
+
+  /* Return the type used for DWARF operations where the type is
+     unspecified in the DWARF spec.  Only certain sizes are
+     supported.  */
   struct type *address_type () const;
-  void push (struct value *value, bool in_stack_memory);
+
+  /* Push ENTRY onto the stack.  */
+  void push (dwarf_entry *value);
+
+  /* Return true if the expression stack is empty.  */
   bool stack_empty_p () const;
-  void add_piece (ULONGEST size, ULONGEST offset);
+
+  /* Pop a top element of the stack and add as a composite piece.
+
+     If the fallowing top element of the stack is a composite
+     location description, the piece will be added to it.  Otherwise
+     a new composite location description will be created and
+     the piece will be added to that composite.  */
+  dwarf_entry *add_piece (ULONGEST bit_size, ULONGEST bit_offset);
+
+  /* The engine for the expression evaluator.  Using the context in this
+     object, evaluate the expression between OP_PTR and OP_END.  */
   void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end);
+
+  /* Pop the top item off of the stack.  */
   void pop ();
-  struct value *fetch (int n);
-  CORE_ADDR fetch_address (int n);
-  bool fetch_in_stack_memory (int n);
+
+  /* Retrieve the N'th item on the stack.  */
+  dwarf_entry *fetch (int n);
 
   /* Fetch the result of the expression evaluation in a form of
      a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET
@@ -251,13 +158,36 @@ struct dwarf_expr_context
   void dwarf_call (cu_offset die_cu_off);
 
   /* Push on DWARF stack an entry evaluated for DW_TAG_call_site's
-     parameter matching KIND and KIND_U at the caller of specified BATON.
-     If DEREF_SIZE is not -1 then use DW_AT_call_data_value instead of
-     DW_AT_call_value.  */
+     parameter matching KIND and KIND_U at the caller of specified
+     BATON. If DEREF_SIZE is not -1 then use DW_AT_call_data_value
+     instead of DW_AT_call_value.  */
   void push_dwarf_reg_entry_value (enum call_site_parameter_kind kind,
 				   union call_site_parameter_u kind_u,
 				   int deref_size);
-  void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t length);
+
+  /* Apply dereference operation on the DWARF ENTRY.  In the case of a
+     value entry, the entry will be implicitly converted to the
+     appropriate location description before the operation is applied.
+     If the SIZE is specified, it must be equal or smaller then the
+     TYPE type size.  If SIZE is smaller then the type size, the value
+     will be zero extended to the difference.  */
+  dwarf_entry* dwarf_entry_deref (dwarf_entry *entry, struct type *type,
+				  size_t size = 0);
+
+  /* Convert struct value to the matching DWARF entry representation.
+     Used for non-standard DW_OP_GNU_variable_value operation
+     support.  */
+  dwarf_entry *gdb_value_to_dwarf_entry (struct value *value);
+
+  /* Convert DWARF entry to the matching struct value representation
+     of the given TYPE type. SUBOBJ_TYPE information if specified, will
+     be used for more precise description of the source variable type
+     information.  Where SUBOBJ_OFFSET defines an offset into the DWARF
+     entry contents.  */
+  struct value *dwarf_entry_to_gdb_value (dwarf_entry *entry,
+					  struct type *type,
+					  struct type *subobj_type = nullptr,
+					  LONGEST subobj_offset = 0);
 };
 
 /* Return the address type used of the GDBARCH architecture and
@@ -268,18 +198,32 @@ struct type *address_type (struct gdbarch *gdbarch, int addr_size);
    read as an address in a given FRAME.  */
 CORE_ADDR read_addr_from_reg (struct frame_info *, int);
 
+/* Check that the current operator is either at the end of an
+   expression, or that it is followed by a composition operator or by
+   DW_OP_GNU_uninit (which should terminate the expression).  */
 void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *,
 				     const char *);
 
+/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_reg* return the
+   DWARF register number.  Otherwise return -1.  */
 int dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end);
 
+/* If <BUF..BUF_END] contains DW_FORM_block* with just DW_OP_breg*(0) and
+   DW_OP_deref* return the DWARF register number.  Otherwise return -1.
+   DEREF_SIZE_RETURN contains -1 for DW_OP_deref; otherwise it contains the
+   size from DW_OP_deref_size.  */
 int dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf,
 				    const gdb_byte *buf_end,
 				    CORE_ADDR *deref_size_return);
 
+/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_fbreg(X) fill
+   in FB_OFFSET_RETURN with the X offset and return 1.  Otherwise return 0.  */
 int dwarf_block_to_fb_offset (const gdb_byte *buf, const gdb_byte *buf_end,
 			      CORE_ADDR *fb_offset_return);
 
+/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_bregSP(X) fill
+   in SP_OFFSET_RETURN with the X offset and return 1.  Otherwise return 0.
+   The matched SP register number depends on GDBARCH.  */
 int dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf,
 			      const gdb_byte *buf_end,
 			      CORE_ADDR *sp_offset_return);
@@ -319,14 +263,17 @@ gdb_skip_leb128 (const gdb_byte *buf, const gdb_byte *buf_end)
   return buf + bytes_read;
 }
 
+/* Helper to read a uleb128 value or throw an error.  */
 extern const gdb_byte *safe_read_uleb128 (const gdb_byte *buf,
 					  const gdb_byte *buf_end,
 					  uint64_t *r);
 
+/* Helper to read a sleb128 value or throw an error.  */
 extern const gdb_byte *safe_read_sleb128 (const gdb_byte *buf,
 					  const gdb_byte *buf_end,
 					  int64_t *r);
 
+/* Helper to skip a leb128 value or throw an error.  */
 extern const gdb_byte *safe_skip_leb128 (const gdb_byte *buf,
 					 const gdb_byte *buf_end);
 
-- 
2.17.1


  parent reply	other threads:[~2020-12-07 19:01 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-07 19:00 [PATCH 00/30] Allow location description on the DWARF stack Zoran Zaric
2020-12-07 19:00 ` [PATCH 01/30] Replace the symbol needs evaluator with a parser Zoran Zaric
2021-01-21 21:16   ` Tom Tromey
2021-01-21 21:48     ` Zoran Zaric
2021-02-23 14:15     ` Zoran Zaric
2020-12-07 19:00 ` [PATCH 02/30] Move frame context info to dwarf_expr_context Zoran Zaric
2021-01-21 21:23   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 03/30] Remove get_frame_cfa from dwarf_expr_context Zoran Zaric
2021-01-21 21:23   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 04/30] Move compilation unit info to dwarf_expr_context Zoran Zaric
2021-01-21 21:28   ` Tom Tromey
2021-02-23 14:21     ` Zoran Zaric
2020-12-07 19:00 ` [PATCH 05/30] Move dwarf_call " Zoran Zaric
2021-01-21 21:30   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 06/30] Move get_object_address " Zoran Zaric
2021-01-21 21:31   ` Tom Tromey
2021-02-23 14:33     ` Zoran Zaric
2020-12-07 19:00 ` [PATCH 07/30] Move read_mem " Zoran Zaric
2021-01-21 21:34   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 08/30] Move push_dwarf_reg_entry_value to expr.c Zoran Zaric
2021-01-21 21:35   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 09/30] Inline get_reg_value method of dwarf_expr_context Zoran Zaric
2021-01-21 21:36   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 10/30] Remove empty frame and full evaluators Zoran Zaric
2021-01-21 21:37   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 11/30] Merge evaluate_for_locexpr_baton evaluator Zoran Zaric
2021-02-08 21:21   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 12/30] Move piece_closure and its support to expr.c Zoran Zaric
2021-02-08 21:32   ` Tom Tromey
2021-02-09 14:53     ` Zoran Zaric
2020-12-07 19:00 ` [PATCH 13/30] Make DWARF evaluator return a single struct value Zoran Zaric
2021-02-08 21:35   ` Tom Tromey
2021-02-09 14:55     ` Zoran Zaric
2021-02-09 17:13       ` Tom Tromey
2020-12-07 19:00 ` [PATCH 14/30] Simplify dwarf_expr_context class interface Zoran Zaric
2021-02-08 21:38   ` Tom Tromey
2021-02-09 14:56     ` Zoran Zaric
2021-02-23 14:38     ` Zoran Zaric
2020-12-07 19:00 ` [PATCH 15/30] Add as_lval argument to expression evaluator Zoran Zaric
2021-02-08 21:41   ` Tom Tromey
2021-02-09 15:25     ` Zoran Zaric
2021-02-09 20:33       ` Tom Tromey
2020-12-07 19:00 ` [PATCH 16/30] Add new register access interface to expr.c Zoran Zaric
2021-02-09 19:37   ` Tom Tromey
2020-12-07 19:00 ` [PATCH 17/30] Add new memory " Zoran Zaric
2021-02-09 19:45   ` Tom Tromey
2021-02-23 15:35     ` Zoran Zaric
2020-12-07 19:00 ` [PATCH 18/30] Add new classes that model DWARF stack element Zoran Zaric
2021-02-08 21:54   ` Tom Tromey
2021-02-09 17:34     ` Zoran Zaric
2021-02-09 20:36       ` Tom Tromey
2021-02-09 21:07         ` Tom Tromey
2021-02-09 21:26           ` Zoran Zaric
2021-02-23 14:57             ` Zoran Zaric
2020-12-07 19:00 ` [PATCH 19/30] Add new location description access interface Zoran Zaric
2021-02-08 21:46   ` Tom Tromey
2021-02-09 16:00     ` Zoran Zaric
2021-02-09 17:30       ` Zoran Zaric
2021-02-23 14:49         ` Zoran Zaric
2020-12-07 19:00 ` [PATCH 20/30] Add dwarf_entry factory class to expr.c Zoran Zaric
2021-02-09 19:54   ` Tom Tromey
2020-12-07 19:00 ` Zoran Zaric [this message]
2021-02-09 20:11   ` [PATCH 21/30] Change DWARF stack to use new dwarf_entry classes Tom Tromey
2020-12-07 19:00 ` [PATCH 22/30] Remove dwarf_expr_context from expr.h interface Zoran Zaric
2020-12-07 19:00 ` [PATCH 23/30] Rename and update the piece_closure structure Zoran Zaric
2020-12-07 19:00 ` [PATCH 24/30] Move read_addr_from_reg function to frame.c Zoran Zaric
2020-12-07 19:00 ` [PATCH 25/30] Add frame info check to DW_OP_reg operations Zoran Zaric
2020-12-07 19:00 ` [PATCH 26/30] Remove DWARF expression composition check Zoran Zaric
2020-12-07 19:00 ` [PATCH 27/30] Add support for any location description in CFI Zoran Zaric
2020-12-07 19:00 ` [PATCH 28/30] Add DWARF operations for byte and bit offset Zoran Zaric
2020-12-07 19:00 ` [PATCH 29/30] Add support for DW_OP_LLVM_undefined operation Zoran Zaric
2020-12-07 19:00 ` [PATCH 30/30] Add support for nested composite locations Zoran Zaric
2020-12-08 14:48 ` [PATCH 00/30] Allow location description on the DWARF stack Metzger, Markus T
2020-12-08 16:17   ` Simon Marchi
2020-12-09  0:30   ` Tye, Tony

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201207190031.13341-22-Zoran.Zaric@amd.com \
    --to=zoran.zaric@amd.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).