Home | History | Annotate | Line # | Download | only in gcc
      1 // Obstack-related utilities.
      2 // Copyright (C) 2020-2022 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:
     71   obstack_watermark (obstack *ob) : m_obstack (ob) { keep (); }
     72   constexpr obstack_watermark (obstack_watermark &&) = default;
     73   ~obstack_watermark () { obstack_free (m_obstack, m_start); }
     74 
     75   operator obstack *() const { return m_obstack; }
     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