1 // Obstack-related utilities.
2 // Copyright (C) 2020-2021 Free Software Foundation, Inc.
3 //
4 // This file is part of GCC.
5 //
6 // GCC is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation; either version 3, or (at your option) any later
9 // version.
10 //
11 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 // for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with GCC; see the file COPYING3.  If not see
18 // <http://www.gnu.org/licenses/>.
19 
20 #ifndef GCC_OBSTACK_UTILS_H
21 #define GCC_OBSTACK_UTILS_H
22 
23 // This RAII class automatically frees memory allocated on an obstack,
24 // unless told not to via keep ().  It automatically converts to an
25 // obstack, so it can (optionally) be used in place of the obstack
26 // to make the scoping clearer.  For example:
27 //
28 //     obstack_watermark watermark (ob);
29 //     auto *ptr1 = XOBNEW (watermark, struct1);
30 //     if (...)
31 //       // Frees ptr1.
32 //       return false;
33 //
34 //     auto *ptr2 = XOBNEW (watermark, struct2);
35 //     if (...)
36 //       // Frees ptr1 and ptr2.
37 //       return false;
38 //
39 //     // Retains ptr1 and ptr2.
40 //     watermark.keep ();
41 //
42 //     auto *ptr3 = XOBNEW (watermark, struct3);
43 //     if (...)
44 //       // Frees ptr3.
45 //       return false;
46 //
47 //     // Retains ptr3 (in addition to ptr1 and ptr2 above).
48 //     watermark.keep ();
49 //     return true;
50 //
51 // The move constructor makes it possible to transfer ownership to a caller:
52 //
53 //     obstack_watermark
54 //     foo ()
55 //     {
56 //       obstack_watermark watermark (ob);
57 //       ...
58 //       return watermark;
59 //     }
60 //
61 //     void
62 //     bar ()
63 //     {
64 //       // Inherit ownership of everything that foo allocated.
65 //       obstack_watermark watermark = foo ();
66 //       ...
67 //     }
68 class obstack_watermark
69 {
70 public:
obstack_watermark(obstack * ob)71   obstack_watermark (obstack *ob) : m_obstack (ob) { keep (); }
72   constexpr obstack_watermark (obstack_watermark &&) = default;
~obstack_watermark()73   ~obstack_watermark () { obstack_free (m_obstack, m_start); }
74 
75   operator obstack *() const { return m_obstack; }
keep()76   void keep () { m_start = XOBNEWVAR (m_obstack, char, 0); }
77 
78 private:
79   DISABLE_COPY_AND_ASSIGN (obstack_watermark);
80 
81 protected:
82   obstack *m_obstack;
83   char *m_start;
84 };
85 
86 #endif
87