1 /* Obstack wrapper for GDB. 2 3 Copyright (C) 2002-2024 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #if !defined (GDB_OBSTACK_H) 21 #define GDB_OBSTACK_H 1 22 23 #include "obstack.h" 24 25 /* Utility macros - wrap obstack alloc into something more robust. */ 26 27 template <typename T> 28 static inline T* 29 obstack_zalloc (struct obstack *ob) 30 { 31 static_assert (IsMallocable<T>::value, "Trying to use OBSTACK_ZALLOC with a \ 32 non-POD data type. Use obstack_new instead."); 33 return ((T *) memset (obstack_alloc (ob, sizeof (T)), 0, sizeof (T))); 34 } 35 36 #define OBSTACK_ZALLOC(OBSTACK,TYPE) obstack_zalloc<TYPE> ((OBSTACK)) 37 38 template <typename T> 39 static inline T * 40 obstack_calloc (struct obstack *ob, size_t number) 41 { 42 static_assert (IsMallocable<T>::value, "Trying to use OBSTACK_CALLOC with a \ 43 non-POD data type. Use obstack_new instead."); 44 return ((T *) memset (obstack_alloc (ob, number * sizeof (T)), 0, 45 number * sizeof (T))); 46 } 47 48 #define OBSTACK_CALLOC(OBSTACK,NUMBER,TYPE) \ 49 obstack_calloc<TYPE> ((OBSTACK), (NUMBER)) 50 51 /* Allocate an object on OB and call its constructor. */ 52 53 template <typename T, typename... Args> 54 static inline T* 55 obstack_new (struct obstack *ob, Args&&... args) 56 { 57 T* object = (T *) obstack_alloc (ob, sizeof (T)); 58 object = new (object) T (std::forward<Args> (args)...); 59 return object; 60 } 61 62 /* Unless explicitly specified, GDB obstacks always use xmalloc() and 63 xfree(). */ 64 /* Note: ezannoni 2004-02-09: One could also specify the allocation 65 functions using a special init function for each obstack, 66 obstack_specify_allocation. However we just use obstack_init and 67 let these defines here do the job. While one could argue the 68 superiority of one approach over the other, we just chose one 69 throughout. */ 70 71 #define obstack_chunk_alloc xmalloc 72 #define obstack_chunk_free xfree 73 74 #define obstack_grow_str(OBSTACK,STRING) \ 75 obstack_grow (OBSTACK, STRING, strlen (STRING)) 76 #define obstack_grow_str0(OBSTACK,STRING) \ 77 obstack_grow0 (OBSTACK, STRING, strlen (STRING)) 78 79 #define obstack_grow_wstr(OBSTACK, WSTRING) \ 80 obstack_grow (OBSTACK, WSTRING, sizeof (gdb_wchar_t) * gdb_wcslen (WSTRING)) 81 82 /* Concatenate NULL terminated variable argument list of `const char 83 *' strings; return the new string. Space is found in the OBSTACKP. 84 Argument list must be terminated by a sentinel expression `(char *) 85 NULL'. */ 86 87 extern char *obconcat (struct obstack *obstackp, ...) ATTRIBUTE_SENTINEL; 88 89 /* Duplicate STRING, returning an equivalent string that's allocated on the 90 obstack OBSTACKP. */ 91 92 static inline char * 93 obstack_strdup (struct obstack *obstackp, const char *string) 94 { 95 return (char *) obstack_copy0 (obstackp, string, strlen (string)); 96 } 97 98 /* Duplicate STRING, returning an equivalent string that's allocated on the 99 obstack OBSTACKP. */ 100 101 static inline char * 102 obstack_strdup (struct obstack *obstackp, const std::string &string) 103 { 104 return (char *) obstack_copy0 (obstackp, string.c_str (), 105 string.size ()); 106 } 107 108 /* Duplicate the first N characters of STRING, returning a 109 \0-terminated string that's allocated on the obstack OBSTACKP. 110 Note that exactly N characters are copied, even if STRING is 111 shorter. */ 112 113 static inline char * 114 obstack_strndup (struct obstack *obstackp, const char *string, size_t n) 115 { 116 return (char *) obstack_copy0 (obstackp, string, n); 117 } 118 119 /* An obstack that frees itself on scope exit. */ 120 struct auto_obstack : obstack 121 { 122 auto_obstack () 123 { obstack_init (this); } 124 125 ~auto_obstack () 126 { obstack_free (this, NULL); } 127 128 DISABLE_COPY_AND_ASSIGN (auto_obstack); 129 130 /* Free all memory in the obstack but leave it valid for further 131 allocation. */ 132 void clear () 133 { obstack_free (this, obstack_base (this)); } 134 }; 135 136 /* Objects are allocated on obstack instead of heap. This is a mixin 137 that uses CRTP to ensure that the type in question is trivially 138 destructible. */ 139 140 template<typename T> 141 struct allocate_on_obstack 142 { 143 allocate_on_obstack () = default; 144 145 void* operator new (size_t size, struct obstack *obstack) 146 { 147 static_assert (IsFreeable<T>::value); 148 return obstack_alloc (obstack, size); 149 } 150 151 void* operator new[] (size_t size, struct obstack *obstack) 152 { 153 return obstack_alloc (obstack, size); 154 } 155 156 void operator delete (void *memory) {} 157 void operator delete[] (void *memory) {} 158 }; 159 160 #endif 161