1 /* Vector API for GNU compiler.
2    Copyright (C) 2004-2020 Free Software Foundation, Inc.
3    Contributed by Nathan Sidwell <nathan@codesourcery.com>
4    Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 #ifndef GCC_VEC_H
23 #define GCC_VEC_H
24 
25 /* Some gen* file have no ggc support as the header file gtype-desc.h is
26    missing.  Provide these definitions in case ggc.h has not been included.
27    This is not a problem because any code that runs before gengtype is built
28    will never need to use GC vectors.*/
29 
30 extern void ggc_free (void *);
31 extern size_t ggc_round_alloc_size (size_t requested_size);
32 extern void *ggc_realloc (void *, size_t MEM_STAT_DECL);
33 
34 /* Templated vector type and associated interfaces.
35 
36    The interface functions are typesafe and use inline functions,
37    sometimes backed by out-of-line generic functions.  The vectors are
38    designed to interoperate with the GTY machinery.
39 
40    There are both 'index' and 'iterate' accessors.  The index accessor
41    is implemented by operator[].  The iterator returns a boolean
42    iteration condition and updates the iteration variable passed by
43    reference.  Because the iterator will be inlined, the address-of
44    can be optimized away.
45 
46    Each operation that increases the number of active elements is
47    available in 'quick' and 'safe' variants.  The former presumes that
48    there is sufficient allocated space for the operation to succeed
49    (it dies if there is not).  The latter will reallocate the
50    vector, if needed.  Reallocation causes an exponential increase in
51    vector size.  If you know you will be adding N elements, it would
52    be more efficient to use the reserve operation before adding the
53    elements with the 'quick' operation.  This will ensure there are at
54    least as many elements as you ask for, it will exponentially
55    increase if there are too few spare slots.  If you want reserve a
56    specific number of slots, but do not want the exponential increase
57    (for instance, you know this is the last allocation), use the
58    reserve_exact operation.  You can also create a vector of a
59    specific size from the get go.
60 
61    You should prefer the push and pop operations, as they append and
62    remove from the end of the vector. If you need to remove several
63    items in one go, use the truncate operation.  The insert and remove
64    operations allow you to change elements in the middle of the
65    vector.  There are two remove operations, one which preserves the
66    element ordering 'ordered_remove', and one which does not
67    'unordered_remove'.  The latter function copies the end element
68    into the removed slot, rather than invoke a memmove operation.  The
69    'lower_bound' function will determine where to place an item in the
70    array using insert that will maintain sorted order.
71 
72    Vectors are template types with three arguments: the type of the
73    elements in the vector, the allocation strategy, and the physical
74    layout to use
75 
76    Four allocation strategies are supported:
77 
78 	- Heap: allocation is done using malloc/free.  This is the
79 	  default allocation strategy.
80 
81   	- GC: allocation is done using ggc_alloc/ggc_free.
82 
83   	- GC atomic: same as GC with the exception that the elements
84 	  themselves are assumed to be of an atomic type that does
85 	  not need to be garbage collected.  This means that marking
86 	  routines do not need to traverse the array marking the
87 	  individual elements.  This increases the performance of
88 	  GC activities.
89 
90    Two physical layouts are supported:
91 
92 	- Embedded: The vector is structured using the trailing array
93 	  idiom.  The last member of the structure is an array of size
94 	  1.  When the vector is initially allocated, a single memory
95 	  block is created to hold the vector's control data and the
96 	  array of elements.  These vectors cannot grow without
97 	  reallocation (see discussion on embeddable vectors below).
98 
99 	- Space efficient: The vector is structured as a pointer to an
100 	  embedded vector.  This is the default layout.  It means that
101 	  vectors occupy a single word of storage before initial
102 	  allocation.  Vectors are allowed to grow (the internal
103 	  pointer is reallocated but the main vector instance does not
104 	  need to relocate).
105 
106    The type, allocation and layout are specified when the vector is
107    declared.
108 
109    If you need to directly manipulate a vector, then the 'address'
110    accessor will return the address of the start of the vector.  Also
111    the 'space' predicate will tell you whether there is spare capacity
112    in the vector.  You will not normally need to use these two functions.
113 
114    Notes on the different layout strategies
115 
116    * Embeddable vectors (vec<T, A, vl_embed>)
117 
118      These vectors are suitable to be embedded in other data
119      structures so that they can be pre-allocated in a contiguous
120      memory block.
121 
122      Embeddable vectors are implemented using the trailing array
123      idiom, thus they are not resizeable without changing the address
124      of the vector object itself.  This means you cannot have
125      variables or fields of embeddable vector type -- always use a
126      pointer to a vector.  The one exception is the final field of a
127      structure, which could be a vector type.
128 
129      You will have to use the embedded_size & embedded_init calls to
130      create such objects, and they will not be resizeable (so the
131      'safe' allocation variants are not available).
132 
133      Properties of embeddable vectors:
134 
135 	  - The whole vector and control data are allocated in a single
136 	    contiguous block.  It uses the trailing-vector idiom, so
137 	    allocation must reserve enough space for all the elements
138 	    in the vector plus its control data.
139 	  - The vector cannot be re-allocated.
140 	  - The vector cannot grow nor shrink.
141 	  - No indirections needed for access/manipulation.
142 	  - It requires 2 words of storage (prior to vector allocation).
143 
144 
145    * Space efficient vector (vec<T, A, vl_ptr>)
146 
147      These vectors can grow dynamically and are allocated together
148      with their control data.  They are suited to be included in data
149      structures.  Prior to initial allocation, they only take a single
150      word of storage.
151 
152      These vectors are implemented as a pointer to embeddable vectors.
153      The semantics allow for this pointer to be NULL to represent
154      empty vectors.  This way, empty vectors occupy minimal space in
155      the structure containing them.
156 
157      Properties:
158 
159 	- The whole vector and control data are allocated in a single
160 	  contiguous block.
161   	- The whole vector may be re-allocated.
162   	- Vector data may grow and shrink.
163   	- Access and manipulation requires a pointer test and
164 	  indirection.
165   	- It requires 1 word of storage (prior to vector allocation).
166 
167    An example of their use would be,
168 
169    struct my_struct {
170      // A space-efficient vector of tree pointers in GC memory.
171      vec<tree, va_gc, vl_ptr> v;
172    };
173 
174    struct my_struct *s;
175 
176    if (s->v.length ()) { we have some contents }
177    s->v.safe_push (decl); // append some decl onto the end
178    for (ix = 0; s->v.iterate (ix, &elt); ix++)
179      { do something with elt }
180 */
181 
182 /* Support function for statistics.  */
183 extern void dump_vec_loc_statistics (void);
184 
185 /* Hashtable mapping vec addresses to descriptors.  */
186 extern htab_t vec_mem_usage_hash;
187 
188 /* Control data for vectors.  This contains the number of allocated
189    and used slots inside a vector.  */
190 
191 struct vec_prefix
192 {
193   /* FIXME - These fields should be private, but we need to cater to
194 	     compilers that have stricter notions of PODness for types.  */
195 
196   /* Memory allocation support routines in vec.c.  */
197   void register_overhead (void *, size_t, size_t CXX_MEM_STAT_INFO);
198   void release_overhead (void *, size_t, size_t, bool CXX_MEM_STAT_INFO);
199   static unsigned calculate_allocation (vec_prefix *, unsigned, bool);
200   static unsigned calculate_allocation_1 (unsigned, unsigned);
201 
202   /* Note that vec_prefix should be a base class for vec, but we use
203      offsetof() on vector fields of tree structures (e.g.,
204      tree_binfo::base_binfos), and offsetof only supports base types.
205 
206      To compensate, we make vec_prefix a field inside vec and make
207      vec a friend class of vec_prefix so it can access its fields.  */
208   template <typename, typename, typename> friend struct vec;
209 
210   /* The allocator types also need access to our internals.  */
211   friend struct va_gc;
212   friend struct va_gc_atomic;
213   friend struct va_heap;
214 
215   unsigned m_alloc : 31;
216   unsigned m_using_auto_storage : 1;
217   unsigned m_num;
218 };
219 
220 /* Calculate the number of slots to reserve a vector, making sure that
221    RESERVE slots are free.  If EXACT grow exactly, otherwise grow
222    exponentially.  PFX is the control data for the vector.  */
223 
224 inline unsigned
calculate_allocation(vec_prefix * pfx,unsigned reserve,bool exact)225 vec_prefix::calculate_allocation (vec_prefix *pfx, unsigned reserve,
226 				  bool exact)
227 {
228   if (exact)
229     return (pfx ? pfx->m_num : 0) + reserve;
230   else if (!pfx)
231     return MAX (4, reserve);
232   return calculate_allocation_1 (pfx->m_alloc, pfx->m_num + reserve);
233 }
234 
235 template<typename, typename, typename> struct vec;
236 
237 /* Valid vector layouts
238 
239    vl_embed	- Embeddable vector that uses the trailing array idiom.
240    vl_ptr	- Space efficient vector that uses a pointer to an
241 		  embeddable vector.  */
242 struct vl_embed { };
243 struct vl_ptr { };
244 
245 
246 /* Types of supported allocations
247 
248    va_heap	- Allocation uses malloc/free.
249    va_gc	- Allocation uses ggc_alloc.
250    va_gc_atomic	- Same as GC, but individual elements of the array
251 		  do not need to be marked during collection.  */
252 
253 /* Allocator type for heap vectors.  */
254 struct va_heap
255 {
256   /* Heap vectors are frequently regular instances, so use the vl_ptr
257      layout for them.  */
258   typedef vl_ptr default_layout;
259 
260   template<typename T>
261   static void reserve (vec<T, va_heap, vl_embed> *&, unsigned, bool
262 		       CXX_MEM_STAT_INFO);
263 
264   template<typename T>
265   static void release (vec<T, va_heap, vl_embed> *&);
266 };
267 
268 
269 /* Allocator for heap memory.  Ensure there are at least RESERVE free
270    slots in V.  If EXACT is true, grow exactly, else grow
271    exponentially.  As a special case, if the vector had not been
272    allocated and RESERVE is 0, no vector will be created.  */
273 
274 template<typename T>
275 inline void
reserve(vec<T,va_heap,vl_embed> * & v,unsigned reserve,bool exact MEM_STAT_DECL)276 va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact
277 		  MEM_STAT_DECL)
278 {
279   size_t elt_size = sizeof (T);
280   unsigned alloc
281     = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact);
282   gcc_checking_assert (alloc);
283 
284   if (GATHER_STATISTICS && v)
285     v->m_vecpfx.release_overhead (v, elt_size * v->allocated (),
286 				  v->allocated (), false);
287 
288   size_t size = vec<T, va_heap, vl_embed>::embedded_size (alloc);
289   unsigned nelem = v ? v->length () : 0;
290   v = static_cast <vec<T, va_heap, vl_embed> *> (xrealloc (v, size));
291   v->embedded_init (alloc, nelem);
292 
293   if (GATHER_STATISTICS)
294     v->m_vecpfx.register_overhead (v, alloc, elt_size PASS_MEM_STAT);
295 }
296 
297 
298 #if GCC_VERSION >= 4007
299 #pragma GCC diagnostic push
300 #pragma GCC diagnostic ignored "-Wfree-nonheap-object"
301 #endif
302 
303 /* Free the heap space allocated for vector V.  */
304 
305 template<typename T>
306 void
release(vec<T,va_heap,vl_embed> * & v)307 va_heap::release (vec<T, va_heap, vl_embed> *&v)
308 {
309   size_t elt_size = sizeof (T);
310   if (v == NULL)
311     return;
312 
313   if (GATHER_STATISTICS)
314     v->m_vecpfx.release_overhead (v, elt_size * v->allocated (),
315 				  v->allocated (), true);
316   ::free (v);
317   v = NULL;
318 }
319 
320 #if GCC_VERSION >= 4007
321 #pragma GCC diagnostic pop
322 #endif
323 
324 /* Allocator type for GC vectors.  Notice that we need the structure
325    declaration even if GC is not enabled.  */
326 
327 struct va_gc
328 {
329   /* Use vl_embed as the default layout for GC vectors.  Due to GTY
330      limitations, GC vectors must always be pointers, so it is more
331      efficient to use a pointer to the vl_embed layout, rather than
332      using a pointer to a pointer as would be the case with vl_ptr.  */
333   typedef vl_embed default_layout;
334 
335   template<typename T, typename A>
336   static void reserve (vec<T, A, vl_embed> *&, unsigned, bool
337 		       CXX_MEM_STAT_INFO);
338 
339   template<typename T, typename A>
340   static void release (vec<T, A, vl_embed> *&v);
341 };
342 
343 
344 /* Free GC memory used by V and reset V to NULL.  */
345 
346 template<typename T, typename A>
347 inline void
release(vec<T,A,vl_embed> * & v)348 va_gc::release (vec<T, A, vl_embed> *&v)
349 {
350   if (v)
351     ::ggc_free (v);
352   v = NULL;
353 }
354 
355 
356 /* Allocator for GC memory.  Ensure there are at least RESERVE free
357    slots in V.  If EXACT is true, grow exactly, else grow
358    exponentially.  As a special case, if the vector had not been
359    allocated and RESERVE is 0, no vector will be created.  */
360 
361 template<typename T, typename A>
362 void
reserve(vec<T,A,vl_embed> * & v,unsigned reserve,bool exact MEM_STAT_DECL)363 va_gc::reserve (vec<T, A, vl_embed> *&v, unsigned reserve, bool exact
364 		MEM_STAT_DECL)
365 {
366   unsigned alloc
367     = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact);
368   if (!alloc)
369     {
370       ::ggc_free (v);
371       v = NULL;
372       return;
373     }
374 
375   /* Calculate the amount of space we want.  */
376   size_t size = vec<T, A, vl_embed>::embedded_size (alloc);
377 
378   /* Ask the allocator how much space it will really give us.  */
379   size = ::ggc_round_alloc_size (size);
380 
381   /* Adjust the number of slots accordingly.  */
382   size_t vec_offset = sizeof (vec_prefix);
383   size_t elt_size = sizeof (T);
384   alloc = (size - vec_offset) / elt_size;
385 
386   /* And finally, recalculate the amount of space we ask for.  */
387   size = vec_offset + alloc * elt_size;
388 
389   unsigned nelem = v ? v->length () : 0;
390   v = static_cast <vec<T, A, vl_embed> *> (::ggc_realloc (v, size
391 							       PASS_MEM_STAT));
392   v->embedded_init (alloc, nelem);
393 }
394 
395 
396 /* Allocator type for GC vectors.  This is for vectors of types
397    atomics w.r.t. collection, so allocation and deallocation is
398    completely inherited from va_gc.  */
399 struct va_gc_atomic : va_gc
400 {
401 };
402 
403 
404 /* Generic vector template.  Default values for A and L indicate the
405    most commonly used strategies.
406 
407    FIXME - Ideally, they would all be vl_ptr to encourage using regular
408            instances for vectors, but the existing GTY machinery is limited
409 	   in that it can only deal with GC objects that are pointers
410 	   themselves.
411 
412 	   This means that vector operations that need to deal with
413 	   potentially NULL pointers, must be provided as free
414 	   functions (see the vec_safe_* functions above).  */
415 template<typename T,
416          typename A = va_heap,
417          typename L = typename A::default_layout>
418 struct GTY((user)) vec
419 {
420 };
421 
422 /* Generic vec<> debug helpers.
423 
424    These need to be instantiated for each vec<TYPE> used throughout
425    the compiler like this:
426 
427     DEFINE_DEBUG_VEC (TYPE)
428 
429    The reason we have a debug_helper() is because GDB can't
430    disambiguate a plain call to debug(some_vec), and it must be called
431    like debug<TYPE>(some_vec).  */
432 
433 template<typename T>
434 void
debug_helper(vec<T> & ref)435 debug_helper (vec<T> &ref)
436 {
437   unsigned i;
438   for (i = 0; i < ref.length (); ++i)
439     {
440       fprintf (stderr, "[%d] = ", i);
441       debug_slim (ref[i]);
442       fputc ('\n', stderr);
443     }
444 }
445 
446 /* We need a separate va_gc variant here because default template
447    argument for functions cannot be used in c++-98.  Once this
448    restriction is removed, those variant should be folded with the
449    above debug_helper.  */
450 
451 template<typename T>
452 void
debug_helper(vec<T,va_gc> & ref)453 debug_helper (vec<T, va_gc> &ref)
454 {
455   unsigned i;
456   for (i = 0; i < ref.length (); ++i)
457     {
458       fprintf (stderr, "[%d] = ", i);
459       debug_slim (ref[i]);
460       fputc ('\n', stderr);
461     }
462 }
463 
464 /* Macro to define debug(vec<T>) and debug(vec<T, va_gc>) helper
465    functions for a type T.  */
466 
467 #define DEFINE_DEBUG_VEC(T) \
468   template void debug_helper (vec<T> &);		\
469   template void debug_helper (vec<T, va_gc> &);		\
470   /* Define the vec<T> debug functions.  */		\
471   DEBUG_FUNCTION void					\
472   debug (vec<T> &ref)					\
473   {							\
474     debug_helper <T> (ref);				\
475   }							\
476   DEBUG_FUNCTION void					\
477   debug (vec<T> *ptr)					\
478   {							\
479     if (ptr)						\
480       debug (*ptr);					\
481     else						\
482       fprintf (stderr, "<nil>\n");			\
483   }							\
484   /* Define the vec<T, va_gc> debug functions.  */	\
485   DEBUG_FUNCTION void					\
486   debug (vec<T, va_gc> &ref)				\
487   {							\
488     debug_helper <T> (ref);				\
489   }							\
490   DEBUG_FUNCTION void					\
491   debug (vec<T, va_gc> *ptr)				\
492   {							\
493     if (ptr)						\
494       debug (*ptr);					\
495     else						\
496       fprintf (stderr, "<nil>\n");			\
497   }
498 
499 /* Default-construct N elements in DST.  */
500 
501 template <typename T>
502 inline void
vec_default_construct(T * dst,unsigned n)503 vec_default_construct (T *dst, unsigned n)
504 {
505 #ifdef BROKEN_VALUE_INITIALIZATION
506   /* Versions of GCC before 4.4 sometimes leave certain objects
507      uninitialized when value initialized, though if the type has
508      user defined default ctor, that ctor is invoked.  As a workaround
509      perform clearing first and then the value initialization, which
510      fixes the case when value initialization doesn't initialize due to
511      the bugs and should initialize to all zeros, but still allows
512      vectors for types with user defined default ctor that initializes
513      some or all elements to non-zero.  If T has no user defined
514      default ctor and some non-static data members have user defined
515      default ctors that initialize to non-zero the workaround will
516      still not work properly; in that case we just need to provide
517      user defined default ctor.  */
518   memset (dst, '\0', sizeof (T) * n);
519 #endif
520   for ( ; n; ++dst, --n)
521     ::new (static_cast<void*>(dst)) T ();
522 }
523 
524 /* Copy-construct N elements in DST from *SRC.  */
525 
526 template <typename T>
527 inline void
vec_copy_construct(T * dst,const T * src,unsigned n)528 vec_copy_construct (T *dst, const T *src, unsigned n)
529 {
530   for ( ; n; ++dst, ++src, --n)
531     ::new (static_cast<void*>(dst)) T (*src);
532 }
533 
534 /* Type to provide NULL values for vec<T, A, L>.  This is used to
535    provide nil initializers for vec instances.  Since vec must be
536    a POD, we cannot have proper ctor/dtor for it.  To initialize
537    a vec instance, you can assign it the value vNULL.  This isn't
538    needed for file-scope and function-local static vectors, which
539    are zero-initialized by default.  */
540 struct vnull
541 {
542   template <typename T, typename A, typename L>
543   CONSTEXPR operator vec<T, A, L> () { return vec<T, A, L>(); }
544 };
545 extern vnull vNULL;
546 
547 
548 /* Embeddable vector.  These vectors are suitable to be embedded
549    in other data structures so that they can be pre-allocated in a
550    contiguous memory block.
551 
552    Embeddable vectors are implemented using the trailing array idiom,
553    thus they are not resizeable without changing the address of the
554    vector object itself.  This means you cannot have variables or
555    fields of embeddable vector type -- always use a pointer to a
556    vector.  The one exception is the final field of a structure, which
557    could be a vector type.
558 
559    You will have to use the embedded_size & embedded_init calls to
560    create such objects, and they will not be resizeable (so the 'safe'
561    allocation variants are not available).
562 
563    Properties:
564 
565 	- The whole vector and control data are allocated in a single
566 	  contiguous block.  It uses the trailing-vector idiom, so
567 	  allocation must reserve enough space for all the elements
568   	  in the vector plus its control data.
569   	- The vector cannot be re-allocated.
570   	- The vector cannot grow nor shrink.
571   	- No indirections needed for access/manipulation.
572   	- It requires 2 words of storage (prior to vector allocation).  */
573 
574 template<typename T, typename A>
575 struct GTY((user)) vec<T, A, vl_embed>
576 {
577 public:
578   unsigned allocated (void) const { return m_vecpfx.m_alloc; }
579   unsigned length (void) const { return m_vecpfx.m_num; }
580   bool is_empty (void) const { return m_vecpfx.m_num == 0; }
581   T *address (void) { return m_vecdata; }
582   const T *address (void) const { return m_vecdata; }
583   T *begin () { return address (); }
584   const T *begin () const { return address (); }
585   T *end () { return address () + length (); }
586   const T *end () const { return address () + length (); }
587   const T &operator[] (unsigned) const;
588   T &operator[] (unsigned);
589   T &last (void);
590   bool space (unsigned) const;
591   bool iterate (unsigned, T *) const;
592   bool iterate (unsigned, T **) const;
593   vec *copy (ALONE_CXX_MEM_STAT_INFO) const;
594   void splice (const vec &);
595   void splice (const vec *src);
596   T *quick_push (const T &);
597   T &pop (void);
598   void truncate (unsigned);
599   void quick_insert (unsigned, const T &);
600   void ordered_remove (unsigned);
601   void unordered_remove (unsigned);
602   void block_remove (unsigned, unsigned);
603   void qsort (int (*) (const void *, const void *));
604   void sort (int (*) (const void *, const void *, void *), void *);
605   T *bsearch (const void *key, int (*compar)(const void *, const void *));
606   T *bsearch (const void *key,
607 	      int (*compar)(const void *, const void *, void *), void *);
608   unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
609   bool contains (const T &search) const;
610   static size_t embedded_size (unsigned);
611   void embedded_init (unsigned, unsigned = 0, unsigned = 0);
612   void quick_grow (unsigned len);
613   void quick_grow_cleared (unsigned len);
614 
615   /* vec class can access our internal data and functions.  */
616   template <typename, typename, typename> friend struct vec;
617 
618   /* The allocator types also need access to our internals.  */
619   friend struct va_gc;
620   friend struct va_gc_atomic;
621   friend struct va_heap;
622 
623   /* FIXME - These fields should be private, but we need to cater to
624 	     compilers that have stricter notions of PODness for types.  */
625   vec_prefix m_vecpfx;
626   T m_vecdata[1];
627 };
628 
629 
630 /* Convenience wrapper functions to use when dealing with pointers to
631    embedded vectors.  Some functionality for these vectors must be
632    provided via free functions for these reasons:
633 
634 	1- The pointer may be NULL (e.g., before initial allocation).
635 
636   	2- When the vector needs to grow, it must be reallocated, so
637   	   the pointer will change its value.
638 
639    Because of limitations with the current GC machinery, all vectors
640    in GC memory *must* be pointers.  */
641 
642 
643 /* If V contains no room for NELEMS elements, return false. Otherwise,
644    return true.  */
645 template<typename T, typename A>
646 inline bool
647 vec_safe_space (const vec<T, A, vl_embed> *v, unsigned nelems)
648 {
649   return v ? v->space (nelems) : nelems == 0;
650 }
651 
652 
653 /* If V is NULL, return 0.  Otherwise, return V->length().  */
654 template<typename T, typename A>
655 inline unsigned
656 vec_safe_length (const vec<T, A, vl_embed> *v)
657 {
658   return v ? v->length () : 0;
659 }
660 
661 
662 /* If V is NULL, return NULL.  Otherwise, return V->address().  */
663 template<typename T, typename A>
664 inline T *
665 vec_safe_address (vec<T, A, vl_embed> *v)
666 {
667   return v ? v->address () : NULL;
668 }
669 
670 
671 /* If V is NULL, return true.  Otherwise, return V->is_empty().  */
672 template<typename T, typename A>
673 inline bool
674 vec_safe_is_empty (vec<T, A, vl_embed> *v)
675 {
676   return v ? v->is_empty () : true;
677 }
678 
679 /* If V does not have space for NELEMS elements, call
680    V->reserve(NELEMS, EXACT).  */
681 template<typename T, typename A>
682 inline bool
683 vec_safe_reserve (vec<T, A, vl_embed> *&v, unsigned nelems, bool exact = false
684 		  CXX_MEM_STAT_INFO)
685 {
686   bool extend = nelems ? !vec_safe_space (v, nelems) : false;
687   if (extend)
688     A::reserve (v, nelems, exact PASS_MEM_STAT);
689   return extend;
690 }
691 
692 template<typename T, typename A>
693 inline bool
694 vec_safe_reserve_exact (vec<T, A, vl_embed> *&v, unsigned nelems
695 			CXX_MEM_STAT_INFO)
696 {
697   return vec_safe_reserve (v, nelems, true PASS_MEM_STAT);
698 }
699 
700 
701 /* Allocate GC memory for V with space for NELEMS slots.  If NELEMS
702    is 0, V is initialized to NULL.  */
703 
704 template<typename T, typename A>
705 inline void
706 vec_alloc (vec<T, A, vl_embed> *&v, unsigned nelems CXX_MEM_STAT_INFO)
707 {
708   v = NULL;
709   vec_safe_reserve (v, nelems, false PASS_MEM_STAT);
710 }
711 
712 
713 /* Free the GC memory allocated by vector V and set it to NULL.  */
714 
715 template<typename T, typename A>
716 inline void
717 vec_free (vec<T, A, vl_embed> *&v)
718 {
719   A::release (v);
720 }
721 
722 
723 /* Grow V to length LEN.  Allocate it, if necessary.  */
724 template<typename T, typename A>
725 inline void
726 vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
727 {
728   unsigned oldlen = vec_safe_length (v);
729   gcc_checking_assert (len >= oldlen);
730   vec_safe_reserve_exact (v, len - oldlen PASS_MEM_STAT);
731   v->quick_grow (len);
732 }
733 
734 
735 /* If V is NULL, allocate it.  Call V->safe_grow_cleared(LEN).  */
736 template<typename T, typename A>
737 inline void
738 vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
739 {
740   unsigned oldlen = vec_safe_length (v);
741   vec_safe_grow (v, len PASS_MEM_STAT);
742   vec_default_construct (v->address () + oldlen, len - oldlen);
743 }
744 
745 
746 /* Assume V is not NULL.  */
747 
748 template<typename T>
749 inline void
750 vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
751 		       unsigned len CXX_MEM_STAT_INFO)
752 {
753   v->safe_grow_cleared (len PASS_MEM_STAT);
754 }
755 
756 /* If V does not have space for NELEMS elements, call
757    V->reserve(NELEMS, EXACT).  */
758 
759 template<typename T>
760 inline bool
761 vec_safe_reserve (vec<T, va_heap, vl_ptr> *&v, unsigned nelems, bool exact = false
762 		  CXX_MEM_STAT_INFO)
763 {
764   return v->reserve (nelems, exact);
765 }
766 
767 
768 /* If V is NULL return false, otherwise return V->iterate(IX, PTR).  */
769 template<typename T, typename A>
770 inline bool
771 vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T **ptr)
772 {
773   if (v)
774     return v->iterate (ix, ptr);
775   else
776     {
777       *ptr = 0;
778       return false;
779     }
780 }
781 
782 template<typename T, typename A>
783 inline bool
784 vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T *ptr)
785 {
786   if (v)
787     return v->iterate (ix, ptr);
788   else
789     {
790       *ptr = 0;
791       return false;
792     }
793 }
794 
795 
796 /* If V has no room for one more element, reallocate it.  Then call
797    V->quick_push(OBJ).  */
798 template<typename T, typename A>
799 inline T *
800 vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj CXX_MEM_STAT_INFO)
801 {
802   vec_safe_reserve (v, 1, false PASS_MEM_STAT);
803   return v->quick_push (obj);
804 }
805 
806 
807 /* if V has no room for one more element, reallocate it.  Then call
808    V->quick_insert(IX, OBJ).  */
809 template<typename T, typename A>
810 inline void
811 vec_safe_insert (vec<T, A, vl_embed> *&v, unsigned ix, const T &obj
812 		 CXX_MEM_STAT_INFO)
813 {
814   vec_safe_reserve (v, 1, false PASS_MEM_STAT);
815   v->quick_insert (ix, obj);
816 }
817 
818 
819 /* If V is NULL, do nothing.  Otherwise, call V->truncate(SIZE).  */
820 template<typename T, typename A>
821 inline void
822 vec_safe_truncate (vec<T, A, vl_embed> *v, unsigned size)
823 {
824   if (v)
825     v->truncate (size);
826 }
827 
828 
829 /* If SRC is not NULL, return a pointer to a copy of it.  */
830 template<typename T, typename A>
831 inline vec<T, A, vl_embed> *
832 vec_safe_copy (vec<T, A, vl_embed> *src CXX_MEM_STAT_INFO)
833 {
834   return src ? src->copy (ALONE_PASS_MEM_STAT) : NULL;
835 }
836 
837 /* Copy the elements from SRC to the end of DST as if by memcpy.
838    Reallocate DST, if necessary.  */
839 template<typename T, typename A>
840 inline void
841 vec_safe_splice (vec<T, A, vl_embed> *&dst, const vec<T, A, vl_embed> *src
842 		 CXX_MEM_STAT_INFO)
843 {
844   unsigned src_len = vec_safe_length (src);
845   if (src_len)
846     {
847       vec_safe_reserve_exact (dst, vec_safe_length (dst) + src_len
848 			      PASS_MEM_STAT);
849       dst->splice (*src);
850     }
851 }
852 
853 /* Return true if SEARCH is an element of V.  Note that this is O(N) in the
854    size of the vector and so should be used with care.  */
855 
856 template<typename T, typename A>
857 inline bool
858 vec_safe_contains (vec<T, A, vl_embed> *v, const T &search)
859 {
860   return v ? v->contains (search) : false;
861 }
862 
863 /* Index into vector.  Return the IX'th element.  IX must be in the
864    domain of the vector.  */
865 
866 template<typename T, typename A>
867 inline const T &
868 vec<T, A, vl_embed>::operator[] (unsigned ix) const
869 {
870   gcc_checking_assert (ix < m_vecpfx.m_num);
871   return m_vecdata[ix];
872 }
873 
874 template<typename T, typename A>
875 inline T &
876 vec<T, A, vl_embed>::operator[] (unsigned ix)
877 {
878   gcc_checking_assert (ix < m_vecpfx.m_num);
879   return m_vecdata[ix];
880 }
881 
882 
883 /* Get the final element of the vector, which must not be empty.  */
884 
885 template<typename T, typename A>
886 inline T &
887 vec<T, A, vl_embed>::last (void)
888 {
889   gcc_checking_assert (m_vecpfx.m_num > 0);
890   return (*this)[m_vecpfx.m_num - 1];
891 }
892 
893 
894 /* If this vector has space for NELEMS additional entries, return
895    true.  You usually only need to use this if you are doing your
896    own vector reallocation, for instance on an embedded vector.  This
897    returns true in exactly the same circumstances that vec::reserve
898    will.  */
899 
900 template<typename T, typename A>
901 inline bool
902 vec<T, A, vl_embed>::space (unsigned nelems) const
903 {
904   return m_vecpfx.m_alloc - m_vecpfx.m_num >= nelems;
905 }
906 
907 
908 /* Return iteration condition and update PTR to point to the IX'th
909    element of this vector.  Use this to iterate over the elements of a
910    vector as follows,
911 
912      for (ix = 0; vec<T, A>::iterate (v, ix, &ptr); ix++)
913        continue;  */
914 
915 template<typename T, typename A>
916 inline bool
917 vec<T, A, vl_embed>::iterate (unsigned ix, T *ptr) const
918 {
919   if (ix < m_vecpfx.m_num)
920     {
921       *ptr = m_vecdata[ix];
922       return true;
923     }
924   else
925     {
926       *ptr = 0;
927       return false;
928     }
929 }
930 
931 
932 /* Return iteration condition and update *PTR to point to the
933    IX'th element of this vector.  Use this to iterate over the
934    elements of a vector as follows,
935 
936      for (ix = 0; v->iterate (ix, &ptr); ix++)
937        continue;
938 
939    This variant is for vectors of objects.  */
940 
941 template<typename T, typename A>
942 inline bool
943 vec<T, A, vl_embed>::iterate (unsigned ix, T **ptr) const
944 {
945   if (ix < m_vecpfx.m_num)
946     {
947       *ptr = CONST_CAST (T *, &m_vecdata[ix]);
948       return true;
949     }
950   else
951     {
952       *ptr = 0;
953       return false;
954     }
955 }
956 
957 
958 /* Return a pointer to a copy of this vector.  */
959 
960 template<typename T, typename A>
961 inline vec<T, A, vl_embed> *
962 vec<T, A, vl_embed>::copy (ALONE_MEM_STAT_DECL) const
963 {
964   vec<T, A, vl_embed> *new_vec = NULL;
965   unsigned len = length ();
966   if (len)
967     {
968       vec_alloc (new_vec, len PASS_MEM_STAT);
969       new_vec->embedded_init (len, len);
970       vec_copy_construct (new_vec->address (), m_vecdata, len);
971     }
972   return new_vec;
973 }
974 
975 
976 /* Copy the elements from SRC to the end of this vector as if by memcpy.
977    The vector must have sufficient headroom available.  */
978 
979 template<typename T, typename A>
980 inline void
981 vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> &src)
982 {
983   unsigned len = src.length ();
984   if (len)
985     {
986       gcc_checking_assert (space (len));
987       vec_copy_construct (end (), src.address (), len);
988       m_vecpfx.m_num += len;
989     }
990 }
991 
992 template<typename T, typename A>
993 inline void
994 vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> *src)
995 {
996   if (src)
997     splice (*src);
998 }
999 
1000 
1001 /* Push OBJ (a new element) onto the end of the vector.  There must be
1002    sufficient space in the vector.  Return a pointer to the slot
1003    where OBJ was inserted.  */
1004 
1005 template<typename T, typename A>
1006 inline T *
1007 vec<T, A, vl_embed>::quick_push (const T &obj)
1008 {
1009   gcc_checking_assert (space (1));
1010   T *slot = &m_vecdata[m_vecpfx.m_num++];
1011   *slot = obj;
1012   return slot;
1013 }
1014 
1015 
1016 /* Pop and return the last element off the end of the vector.  */
1017 
1018 template<typename T, typename A>
1019 inline T &
1020 vec<T, A, vl_embed>::pop (void)
1021 {
1022   gcc_checking_assert (length () > 0);
1023   return m_vecdata[--m_vecpfx.m_num];
1024 }
1025 
1026 
1027 /* Set the length of the vector to SIZE.  The new length must be less
1028    than or equal to the current length.  This is an O(1) operation.  */
1029 
1030 template<typename T, typename A>
1031 inline void
1032 vec<T, A, vl_embed>::truncate (unsigned size)
1033 {
1034   gcc_checking_assert (length () >= size);
1035   m_vecpfx.m_num = size;
1036 }
1037 
1038 
1039 /* Insert an element, OBJ, at the IXth position of this vector.  There
1040    must be sufficient space.  */
1041 
1042 template<typename T, typename A>
1043 inline void
1044 vec<T, A, vl_embed>::quick_insert (unsigned ix, const T &obj)
1045 {
1046   gcc_checking_assert (length () < allocated ());
1047   gcc_checking_assert (ix <= length ());
1048   T *slot = &m_vecdata[ix];
1049   memmove (slot + 1, slot, (m_vecpfx.m_num++ - ix) * sizeof (T));
1050   *slot = obj;
1051 }
1052 
1053 
1054 /* Remove an element from the IXth position of this vector.  Ordering of
1055    remaining elements is preserved.  This is an O(N) operation due to
1056    memmove.  */
1057 
1058 template<typename T, typename A>
1059 inline void
1060 vec<T, A, vl_embed>::ordered_remove (unsigned ix)
1061 {
1062   gcc_checking_assert (ix < length ());
1063   T *slot = &m_vecdata[ix];
1064   memmove (slot, slot + 1, (--m_vecpfx.m_num - ix) * sizeof (T));
1065 }
1066 
1067 
1068 /* Remove elements in [START, END) from VEC for which COND holds.  Ordering of
1069    remaining elements is preserved.  This is an O(N) operation.  */
1070 
1071 #define VEC_ORDERED_REMOVE_IF_FROM_TO(vec, read_index, write_index,	\
1072 				      elem_ptr, start, end, cond)	\
1073   {									\
1074     gcc_assert ((end) <= (vec).length ());				\
1075     for (read_index = write_index = (start); read_index < (end);	\
1076 	 ++read_index)							\
1077       {									\
1078 	elem_ptr = &(vec)[read_index];					\
1079 	bool remove_p = (cond);						\
1080 	if (remove_p)							\
1081 	  continue;							\
1082 									\
1083 	if (read_index != write_index)					\
1084 	  (vec)[write_index] = (vec)[read_index];			\
1085 									\
1086 	write_index++;							\
1087       }									\
1088 									\
1089     if (read_index - write_index > 0)					\
1090       (vec).block_remove (write_index, read_index - write_index);	\
1091   }
1092 
1093 
1094 /* Remove elements from VEC for which COND holds.  Ordering of remaining
1095    elements is preserved.  This is an O(N) operation.  */
1096 
1097 #define VEC_ORDERED_REMOVE_IF(vec, read_index, write_index, elem_ptr,	\
1098 			      cond)					\
1099   VEC_ORDERED_REMOVE_IF_FROM_TO ((vec), read_index, write_index,	\
1100 				 elem_ptr, 0, (vec).length (), (cond))
1101 
1102 /* Remove an element from the IXth position of this vector.  Ordering of
1103    remaining elements is destroyed.  This is an O(1) operation.  */
1104 
1105 template<typename T, typename A>
1106 inline void
1107 vec<T, A, vl_embed>::unordered_remove (unsigned ix)
1108 {
1109   gcc_checking_assert (ix < length ());
1110   m_vecdata[ix] = m_vecdata[--m_vecpfx.m_num];
1111 }
1112 
1113 
1114 /* Remove LEN elements starting at the IXth.  Ordering is retained.
1115    This is an O(N) operation due to memmove.  */
1116 
1117 template<typename T, typename A>
1118 inline void
1119 vec<T, A, vl_embed>::block_remove (unsigned ix, unsigned len)
1120 {
1121   gcc_checking_assert (ix + len <= length ());
1122   T *slot = &m_vecdata[ix];
1123   m_vecpfx.m_num -= len;
1124   memmove (slot, slot + len, (m_vecpfx.m_num - ix) * sizeof (T));
1125 }
1126 
1127 
1128 /* Sort the contents of this vector with qsort.  CMP is the comparison
1129    function to pass to qsort.  */
1130 
1131 template<typename T, typename A>
1132 inline void
1133 vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))
1134 {
1135   if (length () > 1)
1136     gcc_qsort (address (), length (), sizeof (T), cmp);
1137 }
1138 
1139 /* Sort the contents of this vector with qsort.  CMP is the comparison
1140    function to pass to qsort.  */
1141 
1142 template<typename T, typename A>
1143 inline void
1144 vec<T, A, vl_embed>::sort (int (*cmp) (const void *, const void *, void *),
1145 			   void *data)
1146 {
1147   if (length () > 1)
1148     gcc_sort_r (address (), length (), sizeof (T), cmp, data);
1149 }
1150 
1151 
1152 /* Search the contents of the sorted vector with a binary search.
1153    CMP is the comparison function to pass to bsearch.  */
1154 
1155 template<typename T, typename A>
1156 inline T *
1157 vec<T, A, vl_embed>::bsearch (const void *key,
1158 			      int (*compar) (const void *, const void *))
1159 {
1160   const void *base = this->address ();
1161   size_t nmemb = this->length ();
1162   size_t size = sizeof (T);
1163   /* The following is a copy of glibc stdlib-bsearch.h.  */
1164   size_t l, u, idx;
1165   const void *p;
1166   int comparison;
1167 
1168   l = 0;
1169   u = nmemb;
1170   while (l < u)
1171     {
1172       idx = (l + u) / 2;
1173       p = (const void *) (((const char *) base) + (idx * size));
1174       comparison = (*compar) (key, p);
1175       if (comparison < 0)
1176 	u = idx;
1177       else if (comparison > 0)
1178 	l = idx + 1;
1179       else
1180 	return (T *)const_cast<void *>(p);
1181     }
1182 
1183   return NULL;
1184 }
1185 
1186 /* Search the contents of the sorted vector with a binary search.
1187    CMP is the comparison function to pass to bsearch.  */
1188 
1189 template<typename T, typename A>
1190 inline T *
1191 vec<T, A, vl_embed>::bsearch (const void *key,
1192 			      int (*compar) (const void *, const void *,
1193 					     void *), void *data)
1194 {
1195   const void *base = this->address ();
1196   size_t nmemb = this->length ();
1197   size_t size = sizeof (T);
1198   /* The following is a copy of glibc stdlib-bsearch.h.  */
1199   size_t l, u, idx;
1200   const void *p;
1201   int comparison;
1202 
1203   l = 0;
1204   u = nmemb;
1205   while (l < u)
1206     {
1207       idx = (l + u) / 2;
1208       p = (const void *) (((const char *) base) + (idx * size));
1209       comparison = (*compar) (key, p, data);
1210       if (comparison < 0)
1211 	u = idx;
1212       else if (comparison > 0)
1213 	l = idx + 1;
1214       else
1215 	return (T *)const_cast<void *>(p);
1216     }
1217 
1218   return NULL;
1219 }
1220 
1221 /* Return true if SEARCH is an element of V.  Note that this is O(N) in the
1222    size of the vector and so should be used with care.  */
1223 
1224 template<typename T, typename A>
1225 inline bool
1226 vec<T, A, vl_embed>::contains (const T &search) const
1227 {
1228   unsigned int len = length ();
1229   for (unsigned int i = 0; i < len; i++)
1230     if ((*this)[i] == search)
1231       return true;
1232 
1233   return false;
1234 }
1235 
1236 /* Find and return the first position in which OBJ could be inserted
1237    without changing the ordering of this vector.  LESSTHAN is a
1238    function that returns true if the first argument is strictly less
1239    than the second.  */
1240 
1241 template<typename T, typename A>
1242 unsigned
1243 vec<T, A, vl_embed>::lower_bound (T obj, bool (*lessthan)(const T &, const T &))
1244   const
1245 {
1246   unsigned int len = length ();
1247   unsigned int half, middle;
1248   unsigned int first = 0;
1249   while (len > 0)
1250     {
1251       half = len / 2;
1252       middle = first;
1253       middle += half;
1254       T middle_elem = (*this)[middle];
1255       if (lessthan (middle_elem, obj))
1256 	{
1257 	  first = middle;
1258 	  ++first;
1259 	  len = len - half - 1;
1260 	}
1261       else
1262 	len = half;
1263     }
1264   return first;
1265 }
1266 
1267 
1268 /* Return the number of bytes needed to embed an instance of an
1269    embeddable vec inside another data structure.
1270 
1271    Use these methods to determine the required size and initialization
1272    of a vector V of type T embedded within another structure (as the
1273    final member):
1274 
1275    size_t vec<T, A, vl_embed>::embedded_size (unsigned alloc);
1276    void v->embedded_init (unsigned alloc, unsigned num);
1277 
1278    These allow the caller to perform the memory allocation.  */
1279 
1280 template<typename T, typename A>
1281 inline size_t
1282 vec<T, A, vl_embed>::embedded_size (unsigned alloc)
1283 {
1284   typedef vec<T, A, vl_embed> vec_embedded;
1285   return offsetof (vec_embedded, m_vecdata) + alloc * sizeof (T);
1286 }
1287 
1288 
1289 /* Initialize the vector to contain room for ALLOC elements and
1290    NUM active elements.  */
1291 
1292 template<typename T, typename A>
1293 inline void
1294 vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num, unsigned aut)
1295 {
1296   m_vecpfx.m_alloc = alloc;
1297   m_vecpfx.m_using_auto_storage = aut;
1298   m_vecpfx.m_num = num;
1299 }
1300 
1301 
1302 /* Grow the vector to a specific length.  LEN must be as long or longer than
1303    the current length.  The new elements are uninitialized.  */
1304 
1305 template<typename T, typename A>
1306 inline void
1307 vec<T, A, vl_embed>::quick_grow (unsigned len)
1308 {
1309   gcc_checking_assert (length () <= len && len <= m_vecpfx.m_alloc);
1310   m_vecpfx.m_num = len;
1311 }
1312 
1313 
1314 /* Grow the vector to a specific length.  LEN must be as long or longer than
1315    the current length.  The new elements are initialized to zero.  */
1316 
1317 template<typename T, typename A>
1318 inline void
1319 vec<T, A, vl_embed>::quick_grow_cleared (unsigned len)
1320 {
1321   unsigned oldlen = length ();
1322   size_t growby = len - oldlen;
1323   quick_grow (len);
1324   if (growby != 0)
1325     vec_default_construct (address () + oldlen, growby);
1326 }
1327 
1328 /* Garbage collection support for vec<T, A, vl_embed>.  */
1329 
1330 template<typename T>
1331 void
1332 gt_ggc_mx (vec<T, va_gc> *v)
1333 {
1334   extern void gt_ggc_mx (T &);
1335   for (unsigned i = 0; i < v->length (); i++)
1336     gt_ggc_mx ((*v)[i]);
1337 }
1338 
1339 template<typename T>
1340 void
1341 gt_ggc_mx (vec<T, va_gc_atomic, vl_embed> *v ATTRIBUTE_UNUSED)
1342 {
1343   /* Nothing to do.  Vectors of atomic types wrt GC do not need to
1344      be traversed.  */
1345 }
1346 
1347 
1348 /* PCH support for vec<T, A, vl_embed>.  */
1349 
1350 template<typename T, typename A>
1351 void
1352 gt_pch_nx (vec<T, A, vl_embed> *v)
1353 {
1354   extern void gt_pch_nx (T &);
1355   for (unsigned i = 0; i < v->length (); i++)
1356     gt_pch_nx ((*v)[i]);
1357 }
1358 
1359 template<typename T, typename A>
1360 void
1361 gt_pch_nx (vec<T *, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1362 {
1363   for (unsigned i = 0; i < v->length (); i++)
1364     op (&((*v)[i]), cookie);
1365 }
1366 
1367 template<typename T, typename A>
1368 void
1369 gt_pch_nx (vec<T, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1370 {
1371   extern void gt_pch_nx (T *, gt_pointer_operator, void *);
1372   for (unsigned i = 0; i < v->length (); i++)
1373     gt_pch_nx (&((*v)[i]), op, cookie);
1374 }
1375 
1376 
1377 /* Space efficient vector.  These vectors can grow dynamically and are
1378    allocated together with their control data.  They are suited to be
1379    included in data structures.  Prior to initial allocation, they
1380    only take a single word of storage.
1381 
1382    These vectors are implemented as a pointer to an embeddable vector.
1383    The semantics allow for this pointer to be NULL to represent empty
1384    vectors.  This way, empty vectors occupy minimal space in the
1385    structure containing them.
1386 
1387    Properties:
1388 
1389 	- The whole vector and control data are allocated in a single
1390 	  contiguous block.
1391   	- The whole vector may be re-allocated.
1392   	- Vector data may grow and shrink.
1393   	- Access and manipulation requires a pointer test and
1394 	  indirection.
1395 	- It requires 1 word of storage (prior to vector allocation).
1396 
1397 
1398    Limitations:
1399 
1400    These vectors must be PODs because they are stored in unions.
1401    (http://en.wikipedia.org/wiki/Plain_old_data_structures).
1402    As long as we use C++03, we cannot have constructors nor
1403    destructors in classes that are stored in unions.  */
1404 
1405 template<typename T>
1406 struct vec<T, va_heap, vl_ptr>
1407 {
1408 public:
1409   /* Memory allocation and deallocation for the embedded vector.
1410      Needed because we cannot have proper ctors/dtors defined.  */
1411   void create (unsigned nelems CXX_MEM_STAT_INFO);
1412   void release (void);
1413 
1414   /* Vector operations.  */
1415   bool exists (void) const
1416   { return m_vec != NULL; }
1417 
1418   bool is_empty (void) const
1419   { return m_vec ? m_vec->is_empty () : true; }
1420 
1421   unsigned length (void) const
1422   { return m_vec ? m_vec->length () : 0; }
1423 
1424   T *address (void)
1425   { return m_vec ? m_vec->m_vecdata : NULL; }
1426 
1427   const T *address (void) const
1428   { return m_vec ? m_vec->m_vecdata : NULL; }
1429 
1430   T *begin () { return address (); }
1431   const T *begin () const { return address (); }
1432   T *end () { return begin () + length (); }
1433   const T *end () const { return begin () + length (); }
1434   const T &operator[] (unsigned ix) const
1435   { return (*m_vec)[ix]; }
1436 
1437   bool operator!=(const vec &other) const
1438   { return !(*this == other); }
1439 
1440   bool operator==(const vec &other) const
1441   { return address () == other.address (); }
1442 
1443   T &operator[] (unsigned ix)
1444   { return (*m_vec)[ix]; }
1445 
1446   T &last (void)
1447   { return m_vec->last (); }
1448 
1449   bool space (int nelems) const
1450   { return m_vec ? m_vec->space (nelems) : nelems == 0; }
1451 
1452   bool iterate (unsigned ix, T *p) const;
1453   bool iterate (unsigned ix, T **p) const;
1454   vec copy (ALONE_CXX_MEM_STAT_INFO) const;
1455   bool reserve (unsigned, bool = false CXX_MEM_STAT_INFO);
1456   bool reserve_exact (unsigned CXX_MEM_STAT_INFO);
1457   void splice (const vec &);
1458   void safe_splice (const vec & CXX_MEM_STAT_INFO);
1459   T *quick_push (const T &);
1460   T *safe_push (const T &CXX_MEM_STAT_INFO);
1461   T &pop (void);
1462   void truncate (unsigned);
1463   void safe_grow (unsigned CXX_MEM_STAT_INFO);
1464   void safe_grow_cleared (unsigned CXX_MEM_STAT_INFO);
1465   void quick_grow (unsigned);
1466   void quick_grow_cleared (unsigned);
1467   void quick_insert (unsigned, const T &);
1468   void safe_insert (unsigned, const T & CXX_MEM_STAT_INFO);
1469   void ordered_remove (unsigned);
1470   void unordered_remove (unsigned);
1471   void block_remove (unsigned, unsigned);
1472   void qsort (int (*) (const void *, const void *));
1473   void sort (int (*) (const void *, const void *, void *), void *);
1474   T *bsearch (const void *key, int (*compar)(const void *, const void *));
1475   T *bsearch (const void *key,
1476 	      int (*compar)(const void *, const void *, void *), void *);
1477   unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
1478   bool contains (const T &search) const;
1479   void reverse (void);
1480 
1481   bool using_auto_storage () const;
1482 
1483   /* FIXME - This field should be private, but we need to cater to
1484 	     compilers that have stricter notions of PODness for types.  */
1485   vec<T, va_heap, vl_embed> *m_vec;
1486 };
1487 
1488 
1489 /* auto_vec is a subclass of vec that automatically manages creating and
1490    releasing the internal vector. If N is non zero then it has N elements of
1491    internal storage.  The default is no internal storage, and you probably only
1492    want to ask for internal storage for vectors on the stack because if the
1493    size of the vector is larger than the internal storage that space is wasted.
1494    */
1495 template<typename T, size_t N = 0>
1496 class auto_vec : public vec<T, va_heap>
1497 {
1498 public:
1499   auto_vec ()
1500   {
1501     m_auto.embedded_init (MAX (N, 2), 0, 1);
1502     this->m_vec = &m_auto;
1503   }
1504 
1505   auto_vec (size_t s)
1506   {
1507     if (s > N)
1508       {
1509 	this->create (s);
1510 	return;
1511       }
1512 
1513     m_auto.embedded_init (MAX (N, 2), 0, 1);
1514     this->m_vec = &m_auto;
1515   }
1516 
1517   ~auto_vec ()
1518   {
1519     this->release ();
1520   }
1521 
1522 private:
1523   vec<T, va_heap, vl_embed> m_auto;
1524   T m_data[MAX (N - 1, 1)];
1525 };
1526 
1527 /* auto_vec is a sub class of vec whose storage is released when it is
1528   destroyed. */
1529 template<typename T>
1530 class auto_vec<T, 0> : public vec<T, va_heap>
1531 {
1532 public:
1533   auto_vec () { this->m_vec = NULL; }
1534   auto_vec (size_t n) { this->create (n); }
1535   ~auto_vec () { this->release (); }
1536 };
1537 
1538 
1539 /* Allocate heap memory for pointer V and create the internal vector
1540    with space for NELEMS elements.  If NELEMS is 0, the internal
1541    vector is initialized to empty.  */
1542 
1543 template<typename T>
1544 inline void
1545 vec_alloc (vec<T> *&v, unsigned nelems CXX_MEM_STAT_INFO)
1546 {
1547   v = new vec<T>;
1548   v->create (nelems PASS_MEM_STAT);
1549 }
1550 
1551 
1552 /* A subclass of auto_vec <char *> that frees all of its elements on
1553    deletion.  */
1554 
1555 class auto_string_vec : public auto_vec <char *>
1556 {
1557  public:
1558   ~auto_string_vec ();
1559 };
1560 
1561 /* A subclass of auto_vec <T *> that deletes all of its elements on
1562    destruction.
1563 
1564    This is a crude way for a vec to "own" the objects it points to
1565    and clean up automatically.
1566 
1567    For example, no attempt is made to delete elements when an item
1568    within the vec is overwritten.
1569 
1570    We can't rely on gnu::unique_ptr within a container,
1571    since we can't rely on move semantics in C++98.  */
1572 
1573 template <typename T>
1574 class auto_delete_vec : public auto_vec <T *>
1575 {
1576  public:
1577   auto_delete_vec () {}
1578   auto_delete_vec (size_t s) : auto_vec <T *> (s) {}
1579 
1580   ~auto_delete_vec ();
1581 
1582 private:
1583   DISABLE_COPY_AND_ASSIGN(auto_delete_vec);
1584 };
1585 
1586 /* Conditionally allocate heap memory for VEC and its internal vector.  */
1587 
1588 template<typename T>
1589 inline void
1590 vec_check_alloc (vec<T, va_heap> *&vec, unsigned nelems CXX_MEM_STAT_INFO)
1591 {
1592   if (!vec)
1593     vec_alloc (vec, nelems PASS_MEM_STAT);
1594 }
1595 
1596 
1597 /* Free the heap memory allocated by vector V and set it to NULL.  */
1598 
1599 template<typename T>
1600 inline void
1601 vec_free (vec<T> *&v)
1602 {
1603   if (v == NULL)
1604     return;
1605 
1606   v->release ();
1607   delete v;
1608   v = NULL;
1609 }
1610 
1611 
1612 /* Return iteration condition and update PTR to point to the IX'th
1613    element of this vector.  Use this to iterate over the elements of a
1614    vector as follows,
1615 
1616      for (ix = 0; v.iterate (ix, &ptr); ix++)
1617        continue;  */
1618 
1619 template<typename T>
1620 inline bool
1621 vec<T, va_heap, vl_ptr>::iterate (unsigned ix, T *ptr) const
1622 {
1623   if (m_vec)
1624     return m_vec->iterate (ix, ptr);
1625   else
1626     {
1627       *ptr = 0;
1628       return false;
1629     }
1630 }
1631 
1632 
1633 /* Return iteration condition and update *PTR to point to the
1634    IX'th element of this vector.  Use this to iterate over the
1635    elements of a vector as follows,
1636 
1637      for (ix = 0; v->iterate (ix, &ptr); ix++)
1638        continue;
1639 
1640    This variant is for vectors of objects.  */
1641 
1642 template<typename T>
1643 inline bool
1644 vec<T, va_heap, vl_ptr>::iterate (unsigned ix, T **ptr) const
1645 {
1646   if (m_vec)
1647     return m_vec->iterate (ix, ptr);
1648   else
1649     {
1650       *ptr = 0;
1651       return false;
1652     }
1653 }
1654 
1655 
1656 /* Convenience macro for forward iteration.  */
1657 #define FOR_EACH_VEC_ELT(V, I, P)			\
1658   for (I = 0; (V).iterate ((I), &(P)); ++(I))
1659 
1660 #define FOR_EACH_VEC_SAFE_ELT(V, I, P)			\
1661   for (I = 0; vec_safe_iterate ((V), (I), &(P)); ++(I))
1662 
1663 /* Likewise, but start from FROM rather than 0.  */
1664 #define FOR_EACH_VEC_ELT_FROM(V, I, P, FROM)		\
1665   for (I = (FROM); (V).iterate ((I), &(P)); ++(I))
1666 
1667 /* Convenience macro for reverse iteration.  */
1668 #define FOR_EACH_VEC_ELT_REVERSE(V, I, P)		\
1669   for (I = (V).length () - 1;				\
1670        (V).iterate ((I), &(P));				\
1671        (I)--)
1672 
1673 #define FOR_EACH_VEC_SAFE_ELT_REVERSE(V, I, P)		\
1674   for (I = vec_safe_length (V) - 1;			\
1675        vec_safe_iterate ((V), (I), &(P));	\
1676        (I)--)
1677 
1678 /* auto_string_vec's dtor, freeing all contained strings, automatically
1679    chaining up to ~auto_vec <char *>, which frees the internal buffer.  */
1680 
1681 inline
1682 auto_string_vec::~auto_string_vec ()
1683 {
1684   int i;
1685   char *str;
1686   FOR_EACH_VEC_ELT (*this, i, str)
1687     free (str);
1688 }
1689 
1690 /* auto_delete_vec's dtor, deleting all contained items, automatically
1691    chaining up to ~auto_vec <T*>, which frees the internal buffer.  */
1692 
1693 template <typename T>
1694 inline
1695 auto_delete_vec<T>::~auto_delete_vec ()
1696 {
1697   int i;
1698   T *item;
1699   FOR_EACH_VEC_ELT (*this, i, item)
1700     delete item;
1701 }
1702 
1703 
1704 /* Return a copy of this vector.  */
1705 
1706 template<typename T>
1707 inline vec<T, va_heap, vl_ptr>
1708 vec<T, va_heap, vl_ptr>::copy (ALONE_MEM_STAT_DECL) const
1709 {
1710   vec<T, va_heap, vl_ptr> new_vec = vNULL;
1711   if (length ())
1712     new_vec.m_vec = m_vec->copy ();
1713   return new_vec;
1714 }
1715 
1716 
1717 /* Ensure that the vector has at least RESERVE slots available (if
1718    EXACT is false), or exactly RESERVE slots available (if EXACT is
1719    true).
1720 
1721    This may create additional headroom if EXACT is false.
1722 
1723    Note that this can cause the embedded vector to be reallocated.
1724    Returns true iff reallocation actually occurred.  */
1725 
1726 template<typename T>
1727 inline bool
1728 vec<T, va_heap, vl_ptr>::reserve (unsigned nelems, bool exact MEM_STAT_DECL)
1729 {
1730   if (space (nelems))
1731     return false;
1732 
1733   /* For now play a game with va_heap::reserve to hide our auto storage if any,
1734      this is necessary because it doesn't have enough information to know the
1735      embedded vector is in auto storage, and so should not be freed.  */
1736   vec<T, va_heap, vl_embed> *oldvec = m_vec;
1737   unsigned int oldsize = 0;
1738   bool handle_auto_vec = m_vec && using_auto_storage ();
1739   if (handle_auto_vec)
1740     {
1741       m_vec = NULL;
1742       oldsize = oldvec->length ();
1743       nelems += oldsize;
1744     }
1745 
1746   va_heap::reserve (m_vec, nelems, exact PASS_MEM_STAT);
1747   if (handle_auto_vec)
1748     {
1749       vec_copy_construct (m_vec->address (), oldvec->address (), oldsize);
1750       m_vec->m_vecpfx.m_num = oldsize;
1751     }
1752 
1753   return true;
1754 }
1755 
1756 
1757 /* Ensure that this vector has exactly NELEMS slots available.  This
1758    will not create additional headroom.  Note this can cause the
1759    embedded vector to be reallocated.  Returns true iff reallocation
1760    actually occurred.  */
1761 
1762 template<typename T>
1763 inline bool
1764 vec<T, va_heap, vl_ptr>::reserve_exact (unsigned nelems MEM_STAT_DECL)
1765 {
1766   return reserve (nelems, true PASS_MEM_STAT);
1767 }
1768 
1769 
1770 /* Create the internal vector and reserve NELEMS for it.  This is
1771    exactly like vec::reserve, but the internal vector is
1772    unconditionally allocated from scratch.  The old one, if it
1773    existed, is lost.  */
1774 
1775 template<typename T>
1776 inline void
1777 vec<T, va_heap, vl_ptr>::create (unsigned nelems MEM_STAT_DECL)
1778 {
1779   m_vec = NULL;
1780   if (nelems > 0)
1781     reserve_exact (nelems PASS_MEM_STAT);
1782 }
1783 
1784 
1785 /* Free the memory occupied by the embedded vector.  */
1786 
1787 template<typename T>
1788 inline void
1789 vec<T, va_heap, vl_ptr>::release (void)
1790 {
1791   if (!m_vec)
1792     return;
1793 
1794   if (using_auto_storage ())
1795     {
1796       m_vec->m_vecpfx.m_num = 0;
1797       return;
1798     }
1799 
1800   va_heap::release (m_vec);
1801 }
1802 
1803 /* Copy the elements from SRC to the end of this vector as if by memcpy.
1804    SRC and this vector must be allocated with the same memory
1805    allocation mechanism. This vector is assumed to have sufficient
1806    headroom available.  */
1807 
1808 template<typename T>
1809 inline void
1810 vec<T, va_heap, vl_ptr>::splice (const vec<T, va_heap, vl_ptr> &src)
1811 {
1812   if (src.length ())
1813     m_vec->splice (*(src.m_vec));
1814 }
1815 
1816 
1817 /* Copy the elements in SRC to the end of this vector as if by memcpy.
1818    SRC and this vector must be allocated with the same mechanism.
1819    If there is not enough headroom in this vector, it will be reallocated
1820    as needed.  */
1821 
1822 template<typename T>
1823 inline void
1824 vec<T, va_heap, vl_ptr>::safe_splice (const vec<T, va_heap, vl_ptr> &src
1825 				      MEM_STAT_DECL)
1826 {
1827   if (src.length ())
1828     {
1829       reserve_exact (src.length ());
1830       splice (src);
1831     }
1832 }
1833 
1834 
1835 /* Push OBJ (a new element) onto the end of the vector.  There must be
1836    sufficient space in the vector.  Return a pointer to the slot
1837    where OBJ was inserted.  */
1838 
1839 template<typename T>
1840 inline T *
1841 vec<T, va_heap, vl_ptr>::quick_push (const T &obj)
1842 {
1843   return m_vec->quick_push (obj);
1844 }
1845 
1846 
1847 /* Push a new element OBJ onto the end of this vector.  Reallocates
1848    the embedded vector, if needed.  Return a pointer to the slot where
1849    OBJ was inserted.  */
1850 
1851 template<typename T>
1852 inline T *
1853 vec<T, va_heap, vl_ptr>::safe_push (const T &obj MEM_STAT_DECL)
1854 {
1855   reserve (1, false PASS_MEM_STAT);
1856   return quick_push (obj);
1857 }
1858 
1859 
1860 /* Pop and return the last element off the end of the vector.  */
1861 
1862 template<typename T>
1863 inline T &
1864 vec<T, va_heap, vl_ptr>::pop (void)
1865 {
1866   return m_vec->pop ();
1867 }
1868 
1869 
1870 /* Set the length of the vector to LEN.  The new length must be less
1871    than or equal to the current length.  This is an O(1) operation.  */
1872 
1873 template<typename T>
1874 inline void
1875 vec<T, va_heap, vl_ptr>::truncate (unsigned size)
1876 {
1877   if (m_vec)
1878     m_vec->truncate (size);
1879   else
1880     gcc_checking_assert (size == 0);
1881 }
1882 
1883 
1884 /* Grow the vector to a specific length.  LEN must be as long or
1885    longer than the current length.  The new elements are
1886    uninitialized.  Reallocate the internal vector, if needed.  */
1887 
1888 template<typename T>
1889 inline void
1890 vec<T, va_heap, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
1891 {
1892   unsigned oldlen = length ();
1893   gcc_checking_assert (oldlen <= len);
1894   reserve_exact (len - oldlen PASS_MEM_STAT);
1895   if (m_vec)
1896     m_vec->quick_grow (len);
1897   else
1898     gcc_checking_assert (len == 0);
1899 }
1900 
1901 
1902 /* Grow the embedded vector to a specific length.  LEN must be as
1903    long or longer than the current length.  The new elements are
1904    initialized to zero.  Reallocate the internal vector, if needed.  */
1905 
1906 template<typename T>
1907 inline void
1908 vec<T, va_heap, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL)
1909 {
1910   unsigned oldlen = length ();
1911   size_t growby = len - oldlen;
1912   safe_grow (len PASS_MEM_STAT);
1913   if (growby != 0)
1914     vec_default_construct (address () + oldlen, growby);
1915 }
1916 
1917 
1918 /* Same as vec::safe_grow but without reallocation of the internal vector.
1919    If the vector cannot be extended, a runtime assertion will be triggered.  */
1920 
1921 template<typename T>
1922 inline void
1923 vec<T, va_heap, vl_ptr>::quick_grow (unsigned len)
1924 {
1925   gcc_checking_assert (m_vec);
1926   m_vec->quick_grow (len);
1927 }
1928 
1929 
1930 /* Same as vec::quick_grow_cleared but without reallocation of the
1931    internal vector. If the vector cannot be extended, a runtime
1932    assertion will be triggered.  */
1933 
1934 template<typename T>
1935 inline void
1936 vec<T, va_heap, vl_ptr>::quick_grow_cleared (unsigned len)
1937 {
1938   gcc_checking_assert (m_vec);
1939   m_vec->quick_grow_cleared (len);
1940 }
1941 
1942 
1943 /* Insert an element, OBJ, at the IXth position of this vector.  There
1944    must be sufficient space.  */
1945 
1946 template<typename T>
1947 inline void
1948 vec<T, va_heap, vl_ptr>::quick_insert (unsigned ix, const T &obj)
1949 {
1950   m_vec->quick_insert (ix, obj);
1951 }
1952 
1953 
1954 /* Insert an element, OBJ, at the IXth position of the vector.
1955    Reallocate the embedded vector, if necessary.  */
1956 
1957 template<typename T>
1958 inline void
1959 vec<T, va_heap, vl_ptr>::safe_insert (unsigned ix, const T &obj MEM_STAT_DECL)
1960 {
1961   reserve (1, false PASS_MEM_STAT);
1962   quick_insert (ix, obj);
1963 }
1964 
1965 
1966 /* Remove an element from the IXth position of this vector.  Ordering of
1967    remaining elements is preserved.  This is an O(N) operation due to
1968    a memmove.  */
1969 
1970 template<typename T>
1971 inline void
1972 vec<T, va_heap, vl_ptr>::ordered_remove (unsigned ix)
1973 {
1974   m_vec->ordered_remove (ix);
1975 }
1976 
1977 
1978 /* Remove an element from the IXth position of this vector.  Ordering
1979    of remaining elements is destroyed.  This is an O(1) operation.  */
1980 
1981 template<typename T>
1982 inline void
1983 vec<T, va_heap, vl_ptr>::unordered_remove (unsigned ix)
1984 {
1985   m_vec->unordered_remove (ix);
1986 }
1987 
1988 
1989 /* Remove LEN elements starting at the IXth.  Ordering is retained.
1990    This is an O(N) operation due to memmove.  */
1991 
1992 template<typename T>
1993 inline void
1994 vec<T, va_heap, vl_ptr>::block_remove (unsigned ix, unsigned len)
1995 {
1996   m_vec->block_remove (ix, len);
1997 }
1998 
1999 
2000 /* Sort the contents of this vector with qsort.  CMP is the comparison
2001    function to pass to qsort.  */
2002 
2003 template<typename T>
2004 inline void
2005 vec<T, va_heap, vl_ptr>::qsort (int (*cmp) (const void *, const void *))
2006 {
2007   if (m_vec)
2008     m_vec->qsort (cmp);
2009 }
2010 
2011 /* Sort the contents of this vector with qsort.  CMP is the comparison
2012    function to pass to qsort.  */
2013 
2014 template<typename T>
2015 inline void
2016 vec<T, va_heap, vl_ptr>::sort (int (*cmp) (const void *, const void *,
2017 					   void *), void *data)
2018 {
2019   if (m_vec)
2020     m_vec->sort (cmp, data);
2021 }
2022 
2023 
2024 /* Search the contents of the sorted vector with a binary search.
2025    CMP is the comparison function to pass to bsearch.  */
2026 
2027 template<typename T>
2028 inline T *
2029 vec<T, va_heap, vl_ptr>::bsearch (const void *key,
2030 				  int (*cmp) (const void *, const void *))
2031 {
2032   if (m_vec)
2033     return m_vec->bsearch (key, cmp);
2034   return NULL;
2035 }
2036 
2037 /* Search the contents of the sorted vector with a binary search.
2038    CMP is the comparison function to pass to bsearch.  */
2039 
2040 template<typename T>
2041 inline T *
2042 vec<T, va_heap, vl_ptr>::bsearch (const void *key,
2043 				  int (*cmp) (const void *, const void *,
2044 					      void *), void *data)
2045 {
2046   if (m_vec)
2047     return m_vec->bsearch (key, cmp, data);
2048   return NULL;
2049 }
2050 
2051 
2052 /* Find and return the first position in which OBJ could be inserted
2053    without changing the ordering of this vector.  LESSTHAN is a
2054    function that returns true if the first argument is strictly less
2055    than the second.  */
2056 
2057 template<typename T>
2058 inline unsigned
2059 vec<T, va_heap, vl_ptr>::lower_bound (T obj,
2060 				      bool (*lessthan)(const T &, const T &))
2061     const
2062 {
2063   return m_vec ? m_vec->lower_bound (obj, lessthan) : 0;
2064 }
2065 
2066 /* Return true if SEARCH is an element of V.  Note that this is O(N) in the
2067    size of the vector and so should be used with care.  */
2068 
2069 template<typename T>
2070 inline bool
2071 vec<T, va_heap, vl_ptr>::contains (const T &search) const
2072 {
2073   return m_vec ? m_vec->contains (search) : false;
2074 }
2075 
2076 /* Reverse content of the vector.  */
2077 
2078 template<typename T>
2079 inline void
2080 vec<T, va_heap, vl_ptr>::reverse (void)
2081 {
2082   unsigned l = length ();
2083   T *ptr = address ();
2084 
2085   for (unsigned i = 0; i < l / 2; i++)
2086     std::swap (ptr[i], ptr[l - i - 1]);
2087 }
2088 
2089 template<typename T>
2090 inline bool
2091 vec<T, va_heap, vl_ptr>::using_auto_storage () const
2092 {
2093   return m_vec->m_vecpfx.m_using_auto_storage;
2094 }
2095 
2096 /* Release VEC and call release of all element vectors.  */
2097 
2098 template<typename T>
2099 inline void
2100 release_vec_vec (vec<vec<T> > &vec)
2101 {
2102   for (unsigned i = 0; i < vec.length (); i++)
2103     vec[i].release ();
2104 
2105   vec.release ();
2106 }
2107 
2108 #if (GCC_VERSION >= 3000)
2109 # pragma GCC poison m_vec m_vecpfx m_vecdata
2110 #endif
2111 
2112 #endif // GCC_VEC_H
2113