1/* Obstack wrapper for GDB. 2 3 Copyright (C) 2002-2020 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 27template <typename T> 28static inline T* 29obstack_zalloc (struct obstack *ob) 30{ 31 static_assert (IsMallocable<T>::value, "Trying to use OBSTACK_ZALLOC with a \ 32non-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 38template <typename T> 39static inline T * 40obstack_calloc (struct obstack *ob, size_t number) 41{ 42 static_assert (IsMallocable<T>::value, "Trying to use OBSTACK_CALLOC with a \ 43non-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 53template <typename T, typename... Args> 54static inline T* 55obstack_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 87extern char *obconcat (struct obstack *obstackp, ...) ATTRIBUTE_SENTINEL; 88 89/* Duplicate STRING, returning an equivalent string that's allocated on the 90 obstack OBSTACKP. */ 91 92static inline char * 93obstack_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 101static inline char * 102obstack_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 113static inline char * 114obstack_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. */ 120struct 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. */ 137 138struct allocate_on_obstack 139{ 140 allocate_on_obstack () = default; 141 142 void* operator new (size_t size, struct obstack *obstack) 143 { 144 return obstack_alloc (obstack, size); 145 } 146 147 void* operator new[] (size_t size, struct obstack *obstack) 148 { 149 return obstack_alloc (obstack, size); 150 } 151 152 void operator delete (void *memory) {} 153 void operator delete[] (void *memory) {} 154}; 155 156#endif 157