X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Fgdb_obstack.h;h=9b1d907678f58109ae44bab3786722c1bec3bb62;hb=4d91c2a4677b90802c8d369190927921bf8ee97d;hp=32727211545e57bce3f07f4aaf74f9d21dde1de8;hpb=6c214e7cb397bf0de539fec640e764f0131e9677;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdb_obstack.h b/gdb/gdb_obstack.h index 3272721154..9b1d907678 100644 --- a/gdb/gdb_obstack.h +++ b/gdb/gdb_obstack.h @@ -1,6 +1,6 @@ /* Obstack wrapper for GDB. - Copyright (C) 2002-2015 Free Software Foundation, Inc. + Copyright (C) 2002-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -24,12 +24,40 @@ /* Utility macros - wrap obstack alloc into something more robust. */ -#define OBSTACK_ZALLOC(OBSTACK,TYPE) \ - ((TYPE *) memset (obstack_alloc ((OBSTACK), sizeof (TYPE)), 0, sizeof (TYPE))) +template +static inline T* +obstack_zalloc (struct obstack *ob) +{ + static_assert (IsMallocable::value, "Trying to use OBSTACK_ZALLOC with a \ +non-POD data type. Use obstack_new instead."); + return ((T *) memset (obstack_alloc (ob, sizeof (T)), 0, sizeof (T))); +} + +#define OBSTACK_ZALLOC(OBSTACK,TYPE) obstack_zalloc ((OBSTACK)) + +template +static inline T * +obstack_calloc (struct obstack *ob, size_t number) +{ + static_assert (IsMallocable::value, "Trying to use OBSTACK_CALLOC with a \ +non-POD data type. Use obstack_new instead."); + return ((T *) memset (obstack_alloc (ob, number * sizeof (T)), 0, + number * sizeof (T))); +} #define OBSTACK_CALLOC(OBSTACK,NUMBER,TYPE) \ - ((TYPE *) memset (obstack_alloc ((OBSTACK), (NUMBER) * sizeof (TYPE)), \ - 0, (NUMBER) * sizeof (TYPE))) + obstack_calloc ((OBSTACK), (NUMBER)) + +/* Allocate an object on OB and call its constructor. */ + +template +static inline T* +obstack_new (struct obstack *ob, Args&&... args) +{ + T* object = (T *) obstack_alloc (ob, sizeof (T)); + object = new (object) T (std::forward (args)...); + return object; +} /* Unless explicitly specified, GDB obstacks always use xmalloc() and xfree(). */ @@ -61,6 +89,68 @@ extern char *obconcat (struct obstack *obstackp, ...) ATTRIBUTE_SENTINEL; /* Duplicate STRING, returning an equivalent string that's allocated on the obstack OBSTACKP. */ -extern char *obstack_strdup (struct obstack *obstackp, const char *string); +static inline char * +obstack_strdup (struct obstack *obstackp, const char *string) +{ + return (char *) obstack_copy0 (obstackp, string, strlen (string)); +} + +/* Duplicate STRING, returning an equivalent string that's allocated on the + obstack OBSTACKP. */ + +static inline char * +obstack_strdup (struct obstack *obstackp, const std::string &string) +{ + return (char *) obstack_copy0 (obstackp, string.c_str (), + string.size ()); +} + +/* Duplicate the first N characters of STRING, returning a + \0-terminated string that's allocated on the obstack OBSTACKP. + Note that exactly N characters are copied, even if STRING is + shorter. */ + +static inline char * +obstack_strndup (struct obstack *obstackp, const char *string, size_t n) +{ + return (char *) obstack_copy0 (obstackp, string, n); +} + +/* An obstack that frees itself on scope exit. */ +struct auto_obstack : obstack +{ + auto_obstack () + { obstack_init (this); } + + ~auto_obstack () + { obstack_free (this, NULL); } + + DISABLE_COPY_AND_ASSIGN (auto_obstack); + + /* Free all memory in the obstack but leave it valid for further + allocation. */ + void clear () + { obstack_free (this, obstack_base (this)); } +}; + +/* Objects are allocated on obstack instead of heap. */ + +struct allocate_on_obstack +{ + allocate_on_obstack () = default; + + void* operator new (size_t size, struct obstack *obstack) + { + return obstack_alloc (obstack, size); + } + + void* operator new[] (size_t size, struct obstack *obstack) + { + return obstack_alloc (obstack, size); + } + + void operator delete (void *memory) {} + void operator delete[] (void *memory) {} +}; #endif