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