From c84cc57e7b6c801055b7ea4d55943c9b149256d0 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 19 Jun 2019 16:20:30 -0400
Subject: [PATCH 17/61] Replace label_text ctor with "borrow" and "take"

libcpp's label_text class wraps a text buffer, along with a flag to
determine if it "owns" the buffer.

The existing ctor exposed this directly, but I found it difficult
to remember the sense of flag, so this patch hides the ctor, in
favor of static member functions "borrow" and "take", to make
the effect on ownership explicit in the name.

gcc/c-family/ChangeLog:
	* c-format.c (range_label_for_format_type_mismatch::get_text):
	Replace label_text ctor called with true with label_text::take.

gcc/c/ChangeLog:
	* c-objc-common.c (range_label_for_type_mismatch::get_text):
	Replace label_text ctor calls.

gcc/cp/ChangeLog:
	* error.c (range_label_for_type_mismatch::get_text): Replace
	label_text ctor calls with label_text::borrow.

gcc/ChangeLog:
	* gcc-rich-location.c
	(maybe_range_label_for_tree_type_mismatch::get_text): Replace
	label_text ctor call with label_text::borrow.
	* gcc-rich-location.h (text_range_label::get_text): Replace
	label_text ctor called with false with label_text::borrow.

libcpp/ChangeLog:
	* include/line-map.h (label_text::label_text): Make private.
	(label_text::borrow): New.
	(label_text::take): New.
	(label_text::take_or_copy): New.
---
 gcc/c-family/c-format.c   |  2 +-
 gcc/c/c-objc-common.c     |  4 ++--
 gcc/cp/error.c            |  4 ++--
 gcc/gcc-rich-location.c   |  2 +-
 gcc/gcc-rich-location.h   |  2 +-
 libcpp/include/line-map.h | 31 +++++++++++++++++++++++++++----
 6 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 91bae3d..56fd2d4 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -4623,7 +4623,7 @@ class range_label_for_format_type_mismatch
 
     char *result = concat (text.m_buffer, p, NULL);
     text.maybe_free ();
-    return label_text (result, true);
+    return label_text::take (result);
   }
 
  private:
diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c
index e1f3b2e..02132a4 100644
--- a/gcc/c/c-objc-common.c
+++ b/gcc/c/c-objc-common.c
@@ -288,12 +288,12 @@ label_text
 range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const
 {
   if (m_labelled_type == NULL_TREE)
-    return label_text (NULL, false);
+    return label_text::borrow (NULL);
 
   c_pretty_printer cpp;
   bool quoted = false;
   print_type (&cpp, m_labelled_type, &quoted);
-  return label_text (xstrdup (pp_formatted_text (&cpp)), true);
+  return label_text::take (xstrdup (pp_formatted_text (&cpp)));
 }
 
 
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 5620134..33ec1f1 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -4345,7 +4345,7 @@ label_text
 range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const
 {
   if (m_labelled_type == NULL_TREE)
-    return label_text (NULL, false);
+    return label_text::borrow (NULL);
 
   const bool verbose = false;
   const bool show_color = false;
@@ -4360,5 +4360,5 @@ range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const
 
   /* Both of the above return GC-allocated buffers, so the caller mustn't
      free them.  */
-  return label_text (const_cast <char *> (result), false);
+  return label_text::borrow (result);
 }
diff --git a/gcc/gcc-rich-location.c b/gcc/gcc-rich-location.c
index 82d4f52..071463e 100644
--- a/gcc/gcc-rich-location.c
+++ b/gcc/gcc-rich-location.c
@@ -196,7 +196,7 @@ maybe_range_label_for_tree_type_mismatch::get_text (unsigned range_idx) const
 {
   if (m_expr == NULL_TREE
       || !EXPR_P (m_expr))
-    return label_text (NULL, false);
+    return label_text::borrow (NULL);
   tree expr_type = TREE_TYPE (m_expr);
 
   tree other_type = NULL_TREE;
diff --git a/gcc/gcc-rich-location.h b/gcc/gcc-rich-location.h
index 3bee2e8..71f4f3d 100644
--- a/gcc/gcc-rich-location.h
+++ b/gcc/gcc-rich-location.h
@@ -111,7 +111,7 @@ class text_range_label : public range_label
 
   label_text get_text (unsigned /*range_idx*/) const FINAL OVERRIDE
   {
-    return label_text (const_cast <char *> (m_text), false);
+    return label_text::borrow (m_text);
   }
 
  private:
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index bde5e53..e4c7952 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -1791,18 +1791,41 @@ public:
   : m_buffer (NULL), m_caller_owned (false)
   {}
 
-  label_text (char *buffer, bool caller_owned)
-  : m_buffer (buffer), m_caller_owned (caller_owned)
-  {}
-
   void maybe_free ()
   {
     if (m_caller_owned)
       free (m_buffer);
   }
 
+  /* Create a label_text instance that borrows BUFFER from a
+     longer-lived owner.  */
+  static label_text borrow (const char *buffer)
+  {
+    return label_text (const_cast <char *> (buffer), false);
+  }
+
+  /* Create a label_text instance that takes ownership of BUFFER.  */
+  static label_text take (char *buffer)
+  {
+    return label_text (buffer, true);
+  }
+
+  /* Take ownership of the buffer, copying if necessary.  */
+  char *take_or_copy ()
+  {
+    if (m_caller_owned)
+      return m_buffer;
+    else
+      return xstrdup (m_buffer);
+  }
+
   char *m_buffer;
   bool m_caller_owned;
+
+private:
+  label_text (char *buffer, bool owned)
+  : m_buffer (buffer), m_caller_owned (owned)
+  {}
 };
 
 /* Abstract base class for labelling a range within a rich_location
-- 
1.8.5.3

