forked from Imagelibrary/binutils-gdb
This patch (finally!) makes it so that trying to use XNEW with a type
that requires "new" will cause a compilation error. The criterion I
initially used to allow a type to use XNEW (which calls malloc in the
end) was std::is_trivially_constructible, but then realized that gcc 4.8
did not have it. Instead, I went with:
using IsMallocatable = std::is_pod<T>;
which is just a bit more strict, which doesn't hurt. A similar thing is
done for macros that free instead of allocated, the criterion is:
using IsFreeable = gdb::Or<std::is_trivially_destructible<T>, std::is_void<T>>;
Trying to use XNEW on a type that requires new will result in an error
like this:
In file included from /home/simark/src/binutils-gdb/gdb/common/common-utils.h:26:0,
from /home/simark/src/binutils-gdb/gdb/common/common-defs.h:78,
from /home/simark/src/binutils-gdb/gdb/defs.h:28,
from /home/simark/src/binutils-gdb/gdb/lala.c:1:
/home/simark/src/binutils-gdb/gdb/common/poison.h: In instantiation of ‘T* xnew() [with T = bar]’:
/home/simark/src/binutils-gdb/gdb/lala.c:13:3: required from here
/home/simark/src/binutils-gdb/gdb/common/poison.h:103:3: error: static assertion failed: Trying to use XNEW with a non-POD data type. Use operator new instead.
static_assert (IsMallocatable<T>::value, "Trying to use XNEW with a non-POD\
^~~~~~~~~~~~~
Generated-code-wise, it adds one more function call (xnew<T>) when using
XNEW and building with -O0, but it all goes away with optimizations
enabled.
gdb/ChangeLog:
* common/common-utils.h: Include poison.h.
(xfree): Remove declaration, add definition with static_assert.
* common/common-utils.c (xfree): Remove.
* common/poison.h (IsMallocatable): Define.
(IsFreeable): Define.
(free): Delete for non-freeable types.
(xnew): New.
(XNEW): Undef and redefine.
(xcnew): New.
(XCNEW): Undef and redefine.
(xdelete): New.
(XDELETE): Undef and redefine.
(xnewvec): New.
(XNEWVEC): Undef and redefine.
(xcnewvec): New.
(XCNEWVEC): Undef and redefine.
(xresizevec): New.
(XRESIZEVEC): Undef and redefine.
(xdeletevec): New.
(XDELETEVEC): Undef and redefine.
(xnewvar): New.
(XNEWVAR): Undef and redefine.
(xcnewvar): New.
(XCNEWVAR): Undef and redefine.
(xresizevar): New.
(XRESIZEVAR): Undef and redefine.
150 lines
4.7 KiB
C++
150 lines
4.7 KiB
C++
/* Shared general utility routines for GDB, the GNU debugger.
|
|
|
|
Copyright (C) 1986-2017 Free Software Foundation, Inc.
|
|
|
|
This file is part of GDB.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef COMMON_UTILS_H
|
|
#define COMMON_UTILS_H
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "poison.h"
|
|
|
|
/* If possible, define FUNCTION_NAME, a macro containing the name of
|
|
the function being defined. Since this macro may not always be
|
|
defined, all uses must be protected by appropriate macro definition
|
|
checks (Eg: "#ifdef FUNCTION_NAME").
|
|
|
|
Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
|
|
which contains the name of the function currently being defined.
|
|
This is broken in G++ before version 2.6.
|
|
C9x has a similar variable called __func__, but prefer the GCC one since
|
|
it demangles C++ function names. */
|
|
#if (GCC_VERSION >= 2004)
|
|
#define FUNCTION_NAME __PRETTY_FUNCTION__
|
|
#else
|
|
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
|
#define FUNCTION_NAME __func__ /* ARI: func */
|
|
#endif
|
|
#endif
|
|
|
|
/* xmalloc(), xrealloc() and xcalloc() have already been declared in
|
|
"libiberty.h". */
|
|
|
|
/* Like xmalloc, but zero the memory. */
|
|
void *xzalloc (size_t);
|
|
|
|
template <typename T>
|
|
static void
|
|
xfree (T *ptr)
|
|
{
|
|
static_assert (IsFreeable<T>::value, "Trying to use xfree with a non-POD \
|
|
data type. Use operator delete instead.");
|
|
|
|
if (ptr != NULL)
|
|
free (ptr); /* ARI: free */
|
|
}
|
|
|
|
|
|
/* Like asprintf and vasprintf, but return the string, throw an error
|
|
if no memory. */
|
|
char *xstrprintf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
|
|
char *xstrvprintf (const char *format, va_list ap)
|
|
ATTRIBUTE_PRINTF (1, 0);
|
|
|
|
/* Like snprintf, but throw an error if the output buffer is too small. */
|
|
int xsnprintf (char *str, size_t size, const char *format, ...)
|
|
ATTRIBUTE_PRINTF (3, 4);
|
|
|
|
/* Returns a std::string built from a printf-style format string. */
|
|
std::string string_printf (const char* fmt, ...)
|
|
ATTRIBUTE_PRINTF (1, 2);
|
|
|
|
/* Like string_printf, but takes a va_list. */
|
|
std::string string_vprintf (const char* fmt, va_list args)
|
|
ATTRIBUTE_PRINTF (1, 0);
|
|
|
|
/* Like string_printf, but appends to DEST instead of returning a new
|
|
std::string. */
|
|
void string_appendf (std::string &dest, const char* fmt, ...)
|
|
ATTRIBUTE_PRINTF (2, 3);
|
|
|
|
/* Like string_appendf, but takes a va_list. */
|
|
void string_vappendf (std::string &dest, const char* fmt, va_list args)
|
|
ATTRIBUTE_PRINTF (2, 0);
|
|
|
|
/* Make a copy of the string at PTR with LEN characters
|
|
(and add a null character at the end in the copy).
|
|
Uses malloc to get the space. Returns the address of the copy. */
|
|
|
|
char *savestring (const char *ptr, size_t len);
|
|
|
|
/* The strerror() function can return NULL for errno values that are
|
|
out of range. Provide a "safe" version that always returns a
|
|
printable string. */
|
|
|
|
extern char *safe_strerror (int);
|
|
|
|
/* Return non-zero if the start of STRING matches PATTERN, zero
|
|
otherwise. */
|
|
|
|
static inline int
|
|
startswith (const char *string, const char *pattern)
|
|
{
|
|
return strncmp (string, pattern, strlen (pattern)) == 0;
|
|
}
|
|
|
|
ULONGEST strtoulst (const char *num, const char **trailer, int base);
|
|
|
|
/* Skip leading whitespace characters in INP, returning an updated
|
|
pointer. If INP is NULL, return NULL. */
|
|
|
|
extern char *skip_spaces (char *inp);
|
|
|
|
/* A const-correct version of the above. */
|
|
|
|
extern const char *skip_spaces (const char *inp);
|
|
|
|
/* Skip leading non-whitespace characters in INP, returning an updated
|
|
pointer. If INP is NULL, return NULL. */
|
|
|
|
extern char *skip_to_space (char *inp);
|
|
|
|
/* A const-correct version of the above. */
|
|
|
|
extern const char *skip_to_space (const char *inp);
|
|
|
|
/* Assumes that V is an argv for a program, and iterates through
|
|
freeing all the elements. */
|
|
extern void free_vector_argv (std::vector<char *> &v);
|
|
|
|
/* Given a vector of arguments ARGV, return a string equivalent to
|
|
joining all the arguments with a whitespace separating them. */
|
|
extern std::string stringify_argv (const std::vector<char *> &argv);
|
|
|
|
/* Return true if VALUE is in [LOW, HIGH]. */
|
|
|
|
template <typename T>
|
|
static bool
|
|
in_inclusive_range (T value, T low, T high)
|
|
{
|
|
return value >= low && value <= high;
|
|
}
|
|
|
|
#endif
|