gdb: Don't skip prologue for explicit line breakpoints in assembler
[deliverable/binutils-gdb.git] / gdb / common / vec.h
index 82d4b0d87293bc75201997d615da480ee6ab391d..8ac146d4903e21ab69087c8ae953605486593b2b 100644 (file)
@@ -1,5 +1,5 @@
 /* Vector API for GDB.
-   Copyright (C) 2004-2014 Free Software Foundation, Inc.
+   Copyright (C) 2004-2019 Free Software Foundation, Inc.
    Contributed by Nathan Sidwell <nathan@codesourcery.com>
 
    This file is part of GDB.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#if !defined (GDB_VEC_H)
-#define GDB_VEC_H
+#ifndef COMMON_VEC_H
+#define COMMON_VEC_H
 
-#include <string.h>
+#include "diagnostics.h"
+
+/* clang has a bug that makes it warn (-Wunused-function) about unused functions
+   that are the result of the DEF_VEC_* macro expansion.  See:
+
+     https://bugs.llvm.org/show_bug.cgi?id=22712
+
+   We specifically ignore this warning for the vec functions when the compiler
+   is clang.  */
+#ifdef __clang__
+# define DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
+    DIAGNOSTIC_IGNORE_UNUSED_FUNCTION
+#else
+# define DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION
+#endif
 
 /* The macros here implement a set of templated vector types and
    associated interfaces.  These templates are implemented with
@@ -410,6 +424,8 @@ typedef struct VEC(T)                                                         \
 
 /* Vector of integer-like object.  */
 #define DEF_VEC_I(T)                                                     \
+DIAGNOSTIC_PUSH                                                          \
+DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION                                    \
 static inline void VEC_OP (T,must_be_integral_type) (void)               \
 {                                                                        \
   (void)~(T)0;                                                           \
@@ -418,10 +434,13 @@ static inline void VEC_OP (T,must_be_integral_type) (void)                  \
 VEC_T(T);                                                                \
 DEF_VEC_FUNC_P(T)                                                        \
 DEF_VEC_ALLOC_FUNC_I(T)                                                          \
+DIAGNOSTIC_POP                                                           \
 struct vec_swallow_trailing_semi
 
 /* Vector of pointer to object.  */
 #define DEF_VEC_P(T)                                                     \
+DIAGNOSTIC_PUSH                                                          \
+DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION                                    \
 static inline void VEC_OP (T,must_be_pointer_type) (void)                \
 {                                                                        \
   (void)((T)1 == (void *)1);                                             \
@@ -430,22 +449,36 @@ static inline void VEC_OP (T,must_be_pointer_type) (void)           \
 VEC_T(T);                                                                \
 DEF_VEC_FUNC_P(T)                                                        \
 DEF_VEC_ALLOC_FUNC_P(T)                                                          \
+DIAGNOSTIC_POP                                                           \
 struct vec_swallow_trailing_semi
 
 /* Vector of object.  */
 #define DEF_VEC_O(T)                                                     \
+DIAGNOSTIC_PUSH                                                          \
+DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION                                    \
 VEC_T(T);                                                                \
 DEF_VEC_FUNC_O(T)                                                        \
 DEF_VEC_ALLOC_FUNC_O(T)                                                          \
+DIAGNOSTIC_POP                                                           \
 struct vec_swallow_trailing_semi
 
+/* Avoid offsetof (or its usual C implementation) as it triggers
+   -Winvalid-offsetof warnings with enum_flags types with G++ <= 4.4,
+   even though those types are memcpyable.  This requires allocating a
+   dummy local VEC in all routines that use this, but that has the
+   advantage that it only works if T is default constructible, which
+   is exactly a check we want, to keep C compatibility.  */
+#define vec_offset(T, VPTR) ((size_t) ((char *) &(VPTR)->vec - (char *) VPTR))
+
 #define DEF_VEC_ALLOC_FUNC_I(T)                                                  \
 static inline VEC(T) *VEC_OP (T,alloc)                                   \
      (int alloc_)                                                        \
 {                                                                        \
+  VEC(T) dummy;                                                                  \
+                                                                         \
   /* We must request exact size allocation, hence the negation.  */      \
   return (VEC(T) *) vec_o_reserve (NULL, -alloc_,                        \
-                                   offsetof (VEC(T),vec), sizeof (T));   \
+                                   vec_offset (T, &dummy), sizeof (T));          \
 }                                                                        \
                                                                          \
 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_)                     \
@@ -455,9 +488,11 @@ static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_)                         \
                                                                          \
   if (len_)                                                              \
     {                                                                    \
+      VEC(T) dummy;                                                      \
+                                                                         \
       /* We must request exact size allocation, hence the negation.  */          \
       new_vec_ = (VEC (T) *)                                             \
-       vec_o_reserve (NULL, -len_, offsetof (VEC(T),vec), sizeof (T));   \
+       vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T));        \
                                                                          \
       new_vec_->num = len_;                                              \
       memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_);              \
@@ -469,12 +504,13 @@ static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_)       \
 {                                                                        \
   if (vec1_ && vec2_)                                                    \
     {                                                                    \
+      VEC(T) dummy;                                                      \
       size_t len_ = vec1_->num + vec2_->num;                             \
       VEC (T) *new_vec_ = NULL;                                                  \
                                                                          \
       /* We must request exact size allocation, hence the negation.  */          \
       new_vec_ = (VEC (T) *)                                             \
-       vec_o_reserve (NULL, -len_, offsetof (VEC(T),vec), sizeof (T));   \
+       vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T));          \
                                                                          \
       new_vec_->num = len_;                                              \
       memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num);       \
@@ -498,7 +534,7 @@ static inline void VEC_OP (T,free)                                    \
 static inline void VEC_OP (T,cleanup)                                    \
      (void *arg_)                                                        \
 {                                                                        \
-  VEC(T) **vec_ = arg_;                                                          \
+  VEC(T) **vec_ = (VEC(T) **) arg_;                                      \
   if (*vec_)                                                             \
     vec_free_ (*vec_);                                                   \
   *vec_ = NULL;                                                                  \
@@ -507,12 +543,13 @@ static inline void VEC_OP (T,cleanup)                                       \
 static inline int VEC_OP (T,reserve)                                     \
      (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL)                         \
 {                                                                        \
+  VEC(T) dummy;                                                                  \
   int extend = !VEC_OP (T,space)                                         \
        (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS);           \
                                                                          \
   if (extend)                                                            \
     *vec_ = (VEC(T) *) vec_o_reserve (*vec_, alloc_,                     \
-                                     offsetof (VEC(T),vec), sizeof (T)); \
+                                     vec_offset (T, &dummy), sizeof (T)); \
                                                                          \
   return extend;                                                         \
 }                                                                        \
@@ -575,7 +612,7 @@ static inline int VEC_OP (T,iterate)                                          \
     }                                                                    \
   else                                                                   \
     {                                                                    \
-      *ptr = 0;                                                                  \
+      *ptr = (T) 0;                                                      \
       return 0;                                                                  \
     }                                                                    \
 }                                                                        \
@@ -583,7 +620,9 @@ static inline int VEC_OP (T,iterate)                                          \
 static inline size_t VEC_OP (T,embedded_size)                            \
      (int alloc_)                                                        \
 {                                                                        \
-  return offsetof (VEC(T),vec) + alloc_ * sizeof(T);                     \
+  VEC(T) dummy;                                                                  \
+                                                                         \
+  return vec_offset (T, &dummy) + alloc_ * sizeof(T);                    \
 }                                                                        \
                                                                          \
 static inline void VEC_OP (T,embedded_init)                              \
@@ -745,7 +784,7 @@ static inline void VEC_OP (T,free)                                    \
 static inline void VEC_OP (T,cleanup)                                    \
      (void *arg_)                                                        \
 {                                                                        \
-  VEC(T) **vec_ = arg_;                                                          \
+  VEC(T) **vec_ = (VEC(T) **) arg_;                                      \
   if (*vec_)                                                             \
     vec_free_ (*vec_);                                                   \
   *vec_ = NULL;                                                                  \
@@ -865,7 +904,9 @@ static inline int VEC_OP (T,iterate)                                          \
 static inline size_t VEC_OP (T,embedded_size)                            \
      (int alloc_)                                                        \
 {                                                                        \
-  return offsetof (VEC(T),vec) + alloc_ * sizeof(T);                     \
+  VEC(T) dummy;                                                                  \
+                                                                         \
+  return vec_offset (T, &dummy) + alloc_ * sizeof(T);                    \
 }                                                                        \
                                                                          \
 static inline void VEC_OP (T,embedded_init)                              \
@@ -1000,9 +1041,11 @@ static inline unsigned VEC_OP (T,lower_bound)                              \
 static inline VEC(T) *VEC_OP (T,alloc)                                   \
      (int alloc_)                                                        \
 {                                                                        \
+  VEC(T) dummy;                                                                  \
+                                                                         \
   /* We must request exact size allocation, hence the negation.  */      \
   return (VEC(T) *) vec_o_reserve (NULL, -alloc_,                        \
-                                   offsetof (VEC(T),vec), sizeof (T));   \
+                                   vec_offset (T, &dummy), sizeof (T));          \
 }                                                                        \
                                                                          \
 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_)                     \
@@ -1012,9 +1055,11 @@ static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_)                       \
                                                                          \
   if (len_)                                                              \
     {                                                                    \
+      VEC(T) dummy;                                                      \
+                                                                         \
       /* We must request exact size allocation, hence the negation.  */          \
       new_vec_ = (VEC (T) *)                                             \
-       vec_o_reserve  (NULL, -len_, offsetof (VEC(T),vec), sizeof (T));  \
+       vec_o_reserve  (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
                                                                          \
       new_vec_->num = len_;                                              \
       memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_);              \
@@ -1026,12 +1071,13 @@ static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_)     \
 {                                                                        \
   if (vec1_ && vec2_)                                                    \
     {                                                                    \
+      VEC(T) dummy;                                                      \
       size_t len_ = vec1_->num + vec2_->num;                             \
       VEC (T) *new_vec_ = NULL;                                                  \
                                                                          \
       /* We must request exact size allocation, hence the negation.  */          \
       new_vec_ = (VEC (T) *)                                             \
-       vec_o_reserve (NULL, -len_, offsetof (VEC(T),vec), sizeof (T));   \
+       vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T));  \
                                                                          \
       new_vec_->num = len_;                                              \
       memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num);       \
@@ -1055,7 +1101,7 @@ static inline void VEC_OP (T,free)                                          \
 static inline void VEC_OP (T,cleanup)                                    \
      (void *arg_)                                                        \
 {                                                                        \
-  VEC(T) **vec_ = arg_;                                                          \
+  VEC(T) **vec_ = (VEC(T) **) arg_;                                      \
   if (*vec_)                                                             \
     vec_free_ (*vec_);                                                   \
   *vec_ = NULL;                                                                  \
@@ -1064,12 +1110,13 @@ static inline void VEC_OP (T,cleanup)                                     \
 static inline int VEC_OP (T,reserve)                                     \
      (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL)                         \
 {                                                                        \
+  VEC(T) dummy;                                                                  \
   int extend = !VEC_OP (T,space) (*vec_, alloc_ < 0 ? -alloc_ : alloc_   \
                                  VEC_ASSERT_PASS);                       \
                                                                          \
   if (extend)                                                            \
     *vec_ = (VEC(T) *)                                                   \
-       vec_o_reserve (*vec_, alloc_, offsetof (VEC(T),vec), sizeof (T)); \
+      vec_o_reserve (*vec_, alloc_, vec_offset (T, &dummy), sizeof (T));  \
                                                                          \
   return extend;                                                         \
 }                                                                        \
@@ -1100,4 +1147,4 @@ static inline T *VEC_OP (T,safe_insert)                                     \
   return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS);     \
 }
 
-#endif /* GDB_VEC_H */
+#endif /* COMMON_VEC_H */
This page took 0.031405 seconds and 4 git commands to generate.