OSDN Git Service

2012-10-08 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / vec.h
1 /* Vector API for GNU compiler.
2    Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
3    Free Software Foundation, Inc.
4    Contributed by Nathan Sidwell <nathan@codesourcery.com>
5    Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 #ifndef GCC_VEC_H
24 #define GCC_VEC_H
25
26 #include "statistics.h"         /* For MEM_STAT_DECL.  */
27
28 /* Templated vector type and associated interfaces.
29
30    The interface functions are typesafe and use inline functions,
31    sometimes backed by out-of-line generic functions.  The vectors are
32    designed to interoperate with the GTY machinery.
33
34    There are both 'index' and 'iterate' accessors.  The index accessor
35    is implemented by operator[].  The iterator returns a boolean
36    iteration condition and updates the iteration variable passed by
37    reference.  Because the iterator will be inlined, the address-of
38    can be optimized away.
39
40    The vectors are implemented using the trailing array idiom, thus
41    they are not resizeable without changing the address of the vector
42    object itself.  This means you cannot have variables or fields of
43    vector type -- always use a pointer to a vector.  The one exception
44    is the final field of a structure, which could be a vector type.
45    You will have to use the embedded_size & embedded_init calls to
46    create such objects, and they will probably not be resizeable (so
47    don't use the 'safe' allocation variants).  The trailing array
48    idiom is used (rather than a pointer to an array of data), because,
49    if we allow NULL to also represent an empty vector, empty vectors
50    occupy minimal space in the structure containing them.
51
52    Each operation that increases the number of active elements is
53    available in 'quick' and 'safe' variants.  The former presumes that
54    there is sufficient allocated space for the operation to succeed
55    (it dies if there is not).  The latter will reallocate the
56    vector, if needed.  Reallocation causes an exponential increase in
57    vector size.  If you know you will be adding N elements, it would
58    be more efficient to use the reserve operation before adding the
59    elements with the 'quick' operation.  This will ensure there are at
60    least as many elements as you ask for, it will exponentially
61    increase if there are too few spare slots.  If you want reserve a
62    specific number of slots, but do not want the exponential increase
63    (for instance, you know this is the last allocation), use the
64    reserve_exact operation.  You can also create a vector of a
65    specific size from the get go.
66
67    You should prefer the push and pop operations, as they append and
68    remove from the end of the vector. If you need to remove several
69    items in one go, use the truncate operation.  The insert and remove
70    operations allow you to change elements in the middle of the
71    vector.  There are two remove operations, one which preserves the
72    element ordering 'ordered_remove', and one which does not
73    'unordered_remove'.  The latter function copies the end element
74    into the removed slot, rather than invoke a memmove operation.  The
75    'lower_bound' function will determine where to place an item in the
76    array using insert that will maintain sorted order.
77
78    When a vector type is defined, first a non-memory managed version
79    is created.  You can then define either or both garbage collected
80    and heap allocated versions.  The allocation mechanism is specified
81    when the vector is allocated.  This can occur via the VEC_alloc
82    call or one of the VEC_safe_* functions that add elements to a
83    vector.  If the vector is NULL, it will be allocated using the
84    allocation strategy selected in the call.  The valid allocations
85    are defined in enum vec_allocation_t.
86
87    If you need to directly manipulate a vector, then the 'address'
88    accessor will return the address of the start of the vector.  Also
89    the 'space' predicate will tell you whether there is spare capacity
90    in the vector.  You will not normally need to use these two functions.
91
92    Variables of vector type are of type vec_t<ETYPE> where ETYPE is
93    the type of the elements of the vector. Due to the way GTY works,
94    you must annotate any structures you wish to insert or reference
95    from a vector with a GTY(()) tag.  You need to do this even if you
96    never use the GC allocated variants.
97
98    An example of their use would be,
99
100    struct my_struct {
101      vec_t<tree> *v;      // A (pointer to) a vector of tree pointers.
102    };
103
104    struct my_struct *s;
105
106    if (VEC_length(tree,s->v)) { we have some contents }
107    VEC_safe_push(tree,gc,s->v,decl); // append some decl onto the end
108    for (ix = 0; VEC_iterate(tree,s->v,ix,elt); ix++)
109      { do something with elt }
110 */
111
112 #if ENABLE_CHECKING
113 #define ALONE_VEC_CHECK_INFO __FILE__, __LINE__, __FUNCTION__
114 #define VEC_CHECK_INFO , ALONE_VEC_CHECK_INFO
115 #define ALONE_VEC_CHECK_DECL const char *file_, unsigned line_, const char *function_
116 #define VEC_CHECK_DECL , ALONE_VEC_CHECK_DECL
117 #define ALONE_VEC_CHECK_PASS file_, line_, function_
118 #define VEC_CHECK_PASS , ALONE_VEC_CHECK_PASS
119
120 #define VEC_ASSERT(EXPR,OP,T,A) \
121   (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0))
122
123 extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL)
124      ATTRIBUTE_NORETURN;
125 #define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS)
126 #else
127 #define ALONE_VEC_CHECK_INFO
128 #define VEC_CHECK_INFO
129 #define ALONE_VEC_CHECK_DECL void
130 #define VEC_CHECK_DECL
131 #define ALONE_VEC_CHECK_PASS
132 #define VEC_CHECK_PASS
133 #define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR)
134 #endif
135
136 #define VEC(T,A) vec_t<T>
137
138 enum vec_allocation_t { heap, gc, stack };
139
140 struct vec_prefix
141 {
142   unsigned num_;
143   unsigned alloc_;
144 };
145
146 /* Vector type, user visible.  */
147 template<typename T>
148 struct GTY(()) vec_t
149 {
150   unsigned length (void) const;
151   bool empty (void) const;
152   T *address (void);
153   T &last (ALONE_VEC_CHECK_DECL);
154   const T &operator[] (unsigned) const;
155   T &operator[] (unsigned);
156   void embedded_init (int, int = 0);
157
158   template<enum vec_allocation_t A>
159   vec_t<T> *copy (ALONE_MEM_STAT_DECL);
160
161   bool space (int VEC_CHECK_DECL);
162   void splice (vec_t<T> * VEC_CHECK_DECL);
163   T *quick_push (const T & VEC_CHECK_DECL);
164   T &pop (ALONE_VEC_CHECK_DECL);
165   void truncate (unsigned VEC_CHECK_DECL);
166   void replace (unsigned, const T & VEC_CHECK_DECL);
167   void quick_insert (unsigned, const T & VEC_CHECK_DECL);
168   void ordered_remove (unsigned VEC_CHECK_DECL);
169   void unordered_remove (unsigned VEC_CHECK_DECL);
170   void block_remove (unsigned, unsigned VEC_CHECK_DECL);
171   unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
172
173   /* Class-static member functions.  Some of these will become member
174      functions of a future handler class wrapping vec_t.  */
175   static size_t embedded_size (int);
176
177   template<enum vec_allocation_t A>
178   static vec_t<T> *alloc (int MEM_STAT_DECL);
179
180   static vec_t<T> *alloc (int, vec_t<T> *);
181
182   template<enum vec_allocation_t A>
183   static void free (vec_t<T> **);
184
185   template<enum vec_allocation_t A>
186   static vec_t<T> *reserve_exact (vec_t<T> *, int MEM_STAT_DECL);
187
188   template<enum vec_allocation_t A>
189   static bool reserve_exact (vec_t<T> **, int VEC_CHECK_DECL MEM_STAT_DECL);
190
191   template<enum vec_allocation_t A>
192   static vec_t<T> *reserve (vec_t<T> *, int MEM_STAT_DECL);
193
194   template<enum vec_allocation_t A>
195   static bool reserve (vec_t<T> **, int VEC_CHECK_DECL MEM_STAT_DECL);
196
197   template<enum vec_allocation_t A>
198   static void safe_splice (vec_t<T> **, vec_t<T> * VEC_CHECK_DECL
199                            MEM_STAT_DECL);
200
201   template<enum vec_allocation_t A>
202   static T *safe_push (vec_t<T> **, const T & VEC_CHECK_DECL MEM_STAT_DECL);
203
204   template<enum vec_allocation_t A>
205   static void safe_grow (vec_t<T> **, int VEC_CHECK_DECL MEM_STAT_DECL);
206
207   template<enum vec_allocation_t A>
208   static void safe_grow_cleared (vec_t<T> **, int VEC_CHECK_DECL MEM_STAT_DECL);
209
210   template<enum vec_allocation_t A>
211   static void safe_insert (vec_t<T> **, unsigned, const T & VEC_CHECK_DECL
212                            MEM_STAT_DECL);
213
214   static bool iterate (const vec_t<T> *, unsigned, T *);
215   static bool iterate (const vec_t<T> *, unsigned, T **);
216
217   vec_prefix prefix_;
218   T vec_[1];
219 };
220
221
222 /* Garbage collection support for vec_t.  */
223
224 template<typename T>
225 void
226 gt_ggc_mx (vec_t<T> *v)
227 {
228   extern void gt_ggc_mx (T &);
229   for (unsigned i = 0; i < v->length (); i++)
230     gt_ggc_mx ((*v)[i]);
231 }
232
233
234 /* PCH support for vec_t.  */
235
236 template<typename T>
237 void
238 gt_pch_nx (vec_t<T> *v)
239 {
240   extern void gt_pch_nx (T &);
241   for (unsigned i = 0; i < v->length (); i++)
242     gt_pch_nx ((*v)[i]);
243 }
244
245 template<typename T>
246 void
247 gt_pch_nx (vec_t<T *> *v, gt_pointer_operator op, void *cookie)
248 {
249   for (unsigned i = 0; i < v->length (); i++)
250     op (&((*v)[i]), cookie);
251 }
252
253 template<typename T>
254 void
255 gt_pch_nx (vec_t<T> *v, gt_pointer_operator op, void *cookie)
256 {
257   extern void gt_pch_nx (T *, gt_pointer_operator, void *);
258   for (unsigned i = 0; i < v->length (); i++)
259     gt_pch_nx (&((*v)[i]), op, cookie);
260 }
261
262
263 /* FIXME.  Remove these definitions and update all calling sites after
264    the handler class for vec_t is implemented.  */
265
266 /* Vector of integer-like object.  */
267 #define DEF_VEC_I(T)                    struct vec_swallow_trailing_semi
268 #define DEF_VEC_ALLOC_I(T,A)            struct vec_swallow_trailing_semi
269
270 /* Vector of pointer to object.  */
271 #define DEF_VEC_P(T)                    struct vec_swallow_trailing_semi
272 #define DEF_VEC_ALLOC_P(T,A)            struct vec_swallow_trailing_semi
273
274 /* Vector of object.  */
275 #define DEF_VEC_O(T)                    struct vec_swallow_trailing_semi
276 #define DEF_VEC_ALLOC_O(T,A)            struct vec_swallow_trailing_semi
277
278 /* Vectors on the stack.  */
279 #define DEF_VEC_ALLOC_P_STACK(T)        struct vec_swallow_trailing_semi
280 #define DEF_VEC_ALLOC_O_STACK(T)        struct vec_swallow_trailing_semi
281 #define DEF_VEC_ALLOC_I_STACK(T)        struct vec_swallow_trailing_semi
282
283 /* Vectors of atomic types.  Atomic types do not need to have its
284    elements marked for GC and PCH.  To avoid unnecessary traversals,
285    we provide template instantiations for the GC/PCH functions that
286    do not traverse the vector.
287
288    FIXME cxx-conversion - Once vec_t users are converted this can
289    be provided in some other way (e.g., adding an additional template
290    parameter to the vec_t class).  */
291 #define DEF_VEC_A(TYPE)                                         \
292 template<typename T>                                            \
293 void                                                            \
294 gt_ggc_mx (vec_t<TYPE> *v ATTRIBUTE_UNUSED)                     \
295 {                                                               \
296 }                                                               \
297                                                                 \
298 template<typename T>                                            \
299 void                                                            \
300 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED)                     \
301 {                                                               \
302 }                                                               \
303                                                                 \
304 template<typename T>                                            \
305 void                                                            \
306 gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED,                     \
307            gt_pointer_operator op ATTRIBUTE_UNUSED,             \
308            void *cookie ATTRIBUTE_UNUSED)                       \
309 {                                                               \
310 }                                                               \
311 struct vec_swallow_trailing_semi
312
313 #define DEF_VEC_ALLOC_A(T,A)            struct vec_swallow_trailing_semi
314
315 /* Support functions for stack vectors.  */
316 extern void *vec_stack_p_reserve_exact_1 (int, void *);
317 extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
318 extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
319                                          MEM_STAT_DECL);
320 extern void vec_stack_free (void *);
321
322 extern void dump_vec_loc_statistics (void);
323 extern void ggc_free (void *);
324 extern void vec_heap_free (void *);
325
326
327 /* API compatibility macros (to be removed).  */
328 #define VEC_length(T,V)                                                 \
329         ((V) ? (V)->length () : 0)
330
331 #define VEC_empty(T,V)                                                  \
332         ((V) ? (V)->empty () : true)
333
334 #define VEC_address(T,V)                                                \
335         vec_address<T> (V)
336
337 /* FIXME.  For now, we need to continue expanding VEC_address into a
338    function call.  Otherwise, the warning machinery for -Wnonnull gets
339    confused thinking that VEC_address may return null in calls to
340    memcpy and qsort.  This will disappear once vec_address becomes
341    a member function for a handler class wrapping vec_t.  */
342
343 template<typename T>
344 static inline T *
345 vec_address (vec_t<T> *vec)
346 {
347   return vec ? vec->address() : NULL;
348 }
349
350 #define VEC_last(T,V)                                                   \
351         ((V)->last (ALONE_VEC_CHECK_INFO))
352
353 #define VEC_index(T,V,I)                                                \
354         ((*(V))[I])
355
356 #define VEC_iterate(T,V,I,P)                                            \
357         (vec_t<T>::iterate(V, I, &(P)))
358
359 #define VEC_embedded_size(T,N)                                          \
360         (vec_t<T>::embedded_size (N))
361
362 #define VEC_embedded_init(T,V,N)                                        \
363         ((V)->embedded_init (N))
364
365 #define VEC_free(T,A,V)                                                 \
366         (vec_t<T>::free<A> (&(V)))
367
368 #define VEC_copy(T,A,V)                                                 \
369         ((V)->copy<A> (ALONE_MEM_STAT_INFO))
370
371 #define VEC_space(T,V,R)                                                \
372         ((V) ? (V)->space (R VEC_CHECK_INFO) : (R) == 0)
373
374 #define VEC_reserve(T,A,V,R)                                            \
375         (vec_t<T>::reserve<A> (&(V), (int)(R) VEC_CHECK_INFO MEM_STAT_INFO))
376
377 #define VEC_reserve_exact(T,A,V,R)                                      \
378         (vec_t<T>::reserve_exact<A> (&(V), R VEC_CHECK_INFO MEM_STAT_INFO))
379
380 #define VEC_splice(T,DST,SRC)                                           \
381         (DST)->splice (SRC VEC_CHECK_INFO)
382
383 #define VEC_safe_splice(T,A,DST,SRC)                                    \
384          vec_t<T>::safe_splice<A> (&(DST), SRC VEC_CHECK_INFO MEM_STAT_INFO)
385
386 #define VEC_quick_push(T,V,O)                                           \
387         ((V)->quick_push (O VEC_CHECK_INFO))
388
389 #define VEC_safe_push(T,A,V,O)                                          \
390         (vec_t<T>::safe_push<A> (&(V), O VEC_CHECK_INFO MEM_STAT_INFO))
391
392 #define VEC_pop(T,V)                                                    \
393         ((V)->pop (ALONE_VEC_CHECK_INFO))
394
395 #define VEC_truncate(T,V,I)                                             \
396         (V                                                              \
397          ? (V)->truncate ((unsigned)(I) VEC_CHECK_INFO)                 \
398          : gcc_assert ((I) == 0))
399
400 #define VEC_safe_grow(T,A,V,I)                                          \
401         (vec_t<T>::safe_grow<A> (&(V), (int)(I) VEC_CHECK_INFO MEM_STAT_INFO))
402
403 #define VEC_safe_grow_cleared(T,A,V,I)                                  \
404         (vec_t<T>::safe_grow_cleared<A> (&(V), (int)(I)                 \
405                                          VEC_CHECK_INFO MEM_STAT_INFO))
406
407 #define VEC_replace(T,V,I,O)                                            \
408         ((V)->replace ((unsigned)(I), O VEC_CHECK_INFO))
409
410 #define VEC_quick_insert(T,V,I,O)                                       \
411         ((V)->quick_insert (I,O VEC_CHECK_INFO))
412
413 #define VEC_safe_insert(T,A,V,I,O)                                      \
414         (vec_t<T>::safe_insert<A> (&(V), I, O VEC_CHECK_INFO MEM_STAT_INFO))
415
416 #define VEC_ordered_remove(T,V,I)                                       \
417         ((V)->ordered_remove (I VEC_CHECK_INFO))
418
419 #define VEC_unordered_remove(T,V,I)                                     \
420         ((V)->unordered_remove (I VEC_CHECK_INFO))
421
422 #define VEC_block_remove(T,V,I,L)                                       \
423         ((V)->block_remove (I, L VEC_CHECK_INFO))
424
425 #define VEC_lower_bound(T,V,O,LT)                                       \
426         ((V)->lower_bound (O, LT))
427
428
429 /* Return the number of active elements in this vector.  */
430
431 template<typename T>
432 inline unsigned
433 vec_t<T>::length (void) const
434 {
435   return prefix_.num_;
436 }
437
438
439 /* Return true if this vector has no active elements.  */
440
441 template<typename T>
442 inline bool
443 vec_t<T>::empty (void) const
444 {
445   return length () == 0;
446 }
447
448
449 /* Return the address of the array of elements.  If you need to
450    directly manipulate the array (for instance, you want to feed it
451    to qsort), use this accessor.  */
452
453 template<typename T>
454 inline T *
455 vec_t<T>::address (void)
456 {
457   return vec_;
458 }
459
460
461 /* Get the final element of the vector, which must not be empty.  */
462
463 template<typename T>
464 T &
465 vec_t<T>::last (ALONE_VEC_CHECK_DECL)
466 {
467   VEC_ASSERT (prefix_.num_, "last", T, base);
468   return (*this)[prefix_.num_ - 1];
469 }
470
471
472 /* Index into vector.  Return the IX'th element.  IX must be in the
473    domain of the vector.  */
474
475 template<typename T>
476 const T &
477 vec_t<T>::operator[] (unsigned ix) const
478 {
479   gcc_assert (ix < prefix_.num_);
480   return vec_[ix];
481 }
482
483 template<typename T>
484 T &
485 vec_t<T>::operator[] (unsigned ix)
486 {
487   gcc_assert (ix < prefix_.num_);
488   return vec_[ix];
489 }
490
491
492 /* Return iteration condition and update PTR to point to the IX'th
493    element of VEC.  Use this to iterate over the elements of a vector
494    as follows,
495
496      for (ix = 0; vec_t<T>::iterate(v, ix, &ptr); ix++)
497        continue;
498    
499    FIXME.  This is a static member function because if VEC is NULL,
500    PTR should be initialized to NULL.  This will become a regular
501    member function of the handler class.  */
502
503 template<typename T>
504 bool
505 vec_t<T>::iterate (const vec_t<T> *vec, unsigned ix, T *ptr)
506 {
507   if (vec && ix < vec->prefix_.num_)
508     {
509       *ptr = vec->vec_[ix];
510       return true;
511     }
512   else
513     {
514       *ptr = 0;
515       return false;
516     }
517 }
518
519
520 /* Return iteration condition and update *PTR to point to the
521    IX'th element of VEC.  Use this to iterate over the elements of a
522    vector as follows,
523
524      for (ix = 0; v->iterate(ix, &ptr); ix++)
525        continue;
526
527    This variant is for vectors of objects.  FIXME, to be removed
528    once the distinction between vec_t<T> and vec_t<T *> disappears.  */
529
530 template<typename T>
531 bool
532 vec_t<T>::iterate (const vec_t<T> *vec, unsigned ix, T **ptr)
533 {
534   if (vec && ix < vec->prefix_.num_)
535     {
536       *ptr = CONST_CAST (T *, &vec->vec_[ix]);
537       return true;
538     }
539   else
540     {
541       *ptr = 0;
542       return false;
543     }
544 }
545
546
547 /* Convenience macro for forward iteration.  */
548
549 #define FOR_EACH_VEC_ELT(T, V, I, P)                    \
550   for (I = 0; VEC_iterate (T, (V), (I), (P)); ++(I))
551
552 /* Likewise, but start from FROM rather than 0.  */
553
554 #define FOR_EACH_VEC_ELT_FROM(T, V, I, P, FROM)         \
555   for (I = (FROM); VEC_iterate (T, (V), (I), (P)); ++(I))
556
557 /* Convenience macro for reverse iteration.  */
558
559 #define FOR_EACH_VEC_ELT_REVERSE(T, V, I, P)            \
560   for (I = VEC_length (T, (V)) - 1;                     \
561        VEC_iterate (T, (V), (I), (P));                  \
562        (I)--)
563
564
565 /* Return the number of bytes needed to embed an instance of vec_t inside
566    another data structure.
567
568    Use these methods to determine the required size and initialization
569    of a vector V of type T embedded within another structure (as the
570    final member):
571
572    size_t vec_t<T>::embedded_size<T> (int reserve);
573    void v->embedded_init(int reserve, int active);
574
575    These allow the caller to perform the memory allocation.  */
576
577 template<typename T>
578 size_t
579 vec_t<T>::embedded_size (int nelems)
580 {
581   return offsetof (vec_t<T>, vec_) + nelems * sizeof (T);
582 }
583
584
585 /* Initialize the vector to contain room for NELEMS elements and
586    ACTIVE active elements.  */
587
588 template<typename T>
589 void
590 vec_t<T>::embedded_init (int nelems, int active)
591 {
592   prefix_.num_ = active;
593   prefix_.alloc_ = nelems;
594 }
595
596
597 /* Allocate a new vector with space for RESERVE objects.  If RESERVE
598    is zero, NO vector is created.
599
600    Note that this allocator must always be a macro:
601
602    We support a vector which starts out with space on the stack and
603    switches to heap space when forced to reallocate.  This works a
604    little differently.  In the case of stack vectors, vec_alloc will
605    expand to a call to vec_alloc_1 that calls XALLOCAVAR to request the
606    initial allocation.  This uses alloca to get the initial space.
607    Since alloca can not be usefully called in an inline function,
608    vec_alloc must always be a macro.
609
610    Important limitations of stack vectors:
611
612    - Only the initial allocation will be made using alloca, so pass a
613      reasonable estimate that doesn't use too much stack space; don't
614      pass zero.
615
616    - Don't return a stack-allocated vector from the function which
617      allocated it.  */
618
619 #define VEC_alloc(T,A,N)                                                \
620   ((A == stack)                                                         \
621     ? vec_t<T>::alloc (N, XALLOCAVAR (vec_t<T>, vec_t<T>::embedded_size (N)))\
622     : vec_t<T>::alloc<A> (N MEM_STAT_INFO))
623
624 template<typename T>
625 template<enum vec_allocation_t A>
626 vec_t<T> *
627 vec_t<T>::alloc (int nelems MEM_STAT_DECL)
628 {
629   return reserve_exact<A> ((vec_t<T> *) NULL, nelems PASS_MEM_STAT);
630 }
631
632 template<typename T>
633 vec_t<T> *
634 vec_t<T>::alloc (int nelems, vec_t<T> *space)
635 {
636   return static_cast <vec_t<T> *> (vec_stack_p_reserve_exact_1 (nelems, space));
637 }
638
639
640 /* Free vector *V and set it to NULL.  */
641
642 template<typename T>
643 template<enum vec_allocation_t A>
644 void
645 vec_t<T>::free (vec_t<T> **v)
646 {
647   if (*v)
648     {
649       if (A == heap)
650         vec_heap_free (*v);
651       else if (A == gc)
652         ggc_free (*v);
653       else if (A == stack)
654         vec_stack_free (*v);
655     }
656   *v = NULL;
657 }
658
659
660 /* Return a copy of this vector.  The new and old vectors need not be
661    allocated by the same mechanism.  */
662
663 template<typename T>
664 template<enum vec_allocation_t A>
665 vec_t<T> *
666 vec_t<T>::copy (ALONE_MEM_STAT_DECL)
667 {
668   unsigned len = VEC_length (T, this);
669   vec_t<T> *new_vec = NULL;
670
671   if (len)
672     {
673       new_vec = reserve_exact<A> (static_cast<vec_t<T> *> (NULL),
674                                   len PASS_MEM_STAT);
675       new_vec->embedded_init (len, len);
676       memcpy (new_vec->address (), vec_, sizeof (T) * len);
677     }
678
679   return new_vec;
680 }
681
682
683 /* If this vector has space for RESERVE additional entries, return
684    true.  You usually only need to use this if you are doing your
685    own vector reallocation, for instance on an embedded vector.  This
686    returns true in exactly the same circumstances that vec_reserve
687    will.  */
688
689 template<typename T>
690 bool
691 vec_t<T>::space (int nelems VEC_CHECK_DECL)
692 {
693   VEC_ASSERT (nelems >= 0, "space", T, base);
694   return prefix_.alloc_ - prefix_.num_ >= static_cast <unsigned> (nelems);
695 }
696
697
698 /* Ensure that the vector **VEC has at least RESERVE slots available.  This
699    will create additional headroom.  Note this can cause **VEC to
700    be reallocated.  Returns true iff reallocation actually occurred.  */
701
702 template<typename T>
703 template<enum vec_allocation_t A>
704 bool
705 vec_t<T>::reserve (vec_t<T> **vec, int nelems VEC_CHECK_DECL MEM_STAT_DECL)
706 {
707   bool extend = (*vec) ? !(*vec)->space (nelems VEC_CHECK_PASS) : nelems != 0;
708
709   if (extend)
710     *vec = reserve<A> (*vec, nelems PASS_MEM_STAT);
711
712   return extend;
713 }
714
715
716 /* Ensure that **VEC has at least NELEMS slots available.  This will not
717    create additional headroom.  Note this can cause VEC to be
718    reallocated.  Returns true iff reallocation actually occurred.  */
719
720 template<typename T>
721 template<enum vec_allocation_t A>
722 bool
723 vec_t<T>::reserve_exact (vec_t<T> **vec, int nelems VEC_CHECK_DECL
724                          MEM_STAT_DECL)
725 {
726   bool extend = (*vec) ? !(*vec)->space (nelems VEC_CHECK_PASS) : nelems != 0;
727
728   if (extend)
729     *vec = reserve_exact<A> (*vec, nelems PASS_MEM_STAT);
730
731   return extend;
732 }
733
734
735 /* Copy the elements from SRC to the end of this vector as if by memcpy.
736    SRC and this vector need not be allocated with the same mechanism,
737    although they most often will be.  This vector is assumed to have
738    sufficient headroom available.  */
739
740 template<typename T>
741 void
742 vec_t<T>::splice (vec_t<T> *src VEC_CHECK_DECL)
743 {
744   if (src)
745     {
746       unsigned len = VEC_length (T, src);
747       VEC_ASSERT (VEC_length (T, this) + len <= prefix_.alloc_, "splice", T,
748                   base);
749       memcpy (address () + VEC_length (T, this),
750               src->address (),
751               len * sizeof (T));
752       prefix_.num_ += len;
753     }
754 }
755
756
757 /* Copy the elements in SRC to the end of DST as if by memcpy.  DST and
758    SRC need not be allocated with the same mechanism, although they most
759    often will be.  DST need not have sufficient headroom and will be
760    reallocated if needed.  */
761
762 template<typename T>
763 template<enum vec_allocation_t A>
764 void
765 vec_t<T>::safe_splice (vec_t<T> **dst, vec_t<T> *src VEC_CHECK_DECL
766                        MEM_STAT_DECL)
767 {
768   if (src)
769     {
770       reserve_exact<A> (dst, VEC_length (T, src) VEC_CHECK_PASS MEM_STAT_INFO);
771       (*dst)->splice (src VEC_CHECK_PASS);
772     }
773 }
774
775   
776 /* Push OBJ (a new element) onto the end of the vector.  There must be
777    sufficient space in the vector.  Return a pointer to the slot
778    where OBJ was inserted.  */
779
780
781 template<typename T>
782 T *
783 vec_t<T>::quick_push (const T &obj VEC_CHECK_DECL)
784 {
785   VEC_ASSERT (prefix_.num_ < prefix_.alloc_, "push", T, base);
786   T *slot = &vec_[prefix_.num_++];
787   *slot = obj;
788   return slot;
789 }
790
791
792 /* Push a new element OBJ onto the end of VEC.  Reallocates VEC, if
793    needed.  Return a pointer to the slot where OBJ was inserted.  */
794
795 template<typename T>
796 template<enum vec_allocation_t A>
797 T *
798 vec_t<T>::safe_push (vec_t<T> **vec, const T &obj VEC_CHECK_DECL MEM_STAT_DECL)
799 {
800   reserve<A> (vec, 1 VEC_CHECK_PASS PASS_MEM_STAT);
801   return (*vec)->quick_push (obj VEC_CHECK_PASS);
802 }
803
804
805 /* Pop and return the last element off the end of the vector.  */
806
807
808 template<typename T>
809 T &
810 vec_t<T>::pop (ALONE_VEC_CHECK_DECL)
811 {
812   VEC_ASSERT (prefix_.num_, "pop", T, base);
813   return vec_[--prefix_.num_];
814 }
815
816
817 /* Set the length of the vector to LEN.  The new length must be less
818    than or equal to the current length.  This is an O(1) operation.  */
819
820 template<typename T>
821 void
822 vec_t<T>::truncate (unsigned size VEC_CHECK_DECL)
823 {
824   VEC_ASSERT (prefix_.num_ >= size, "truncate", T, base);
825   prefix_.num_ = size;
826 }
827
828
829 /* Grow the vector VEC to a specific length.  The LEN must be as
830    long or longer than the current length.  The new elements are
831    uninitialized.  */
832
833 template<typename T>
834 template<enum vec_allocation_t A>
835 void
836 vec_t<T>::safe_grow (vec_t<T> **vec, int size VEC_CHECK_DECL MEM_STAT_DECL)
837 {
838   VEC_ASSERT (size >= 0 && VEC_length (T, *vec) <= (unsigned)size,
839               "grow", T, A);
840   reserve_exact<A> (vec, size - (int)VEC_length (T, *vec)
841                     VEC_CHECK_PASS PASS_MEM_STAT);
842   (*vec)->prefix_.num_ = size;
843 }
844
845
846 /* Grow the vector *VEC to a specific length.  The LEN must be as
847    long or longer than the current length.  The new elements are
848    initialized to zero.  */
849
850 template<typename T>
851 template<enum vec_allocation_t A>
852 void
853 vec_t<T>::safe_grow_cleared (vec_t<T> **vec, int size VEC_CHECK_DECL
854                              MEM_STAT_DECL)
855 {
856   int oldsize = VEC_length (T, *vec);
857   safe_grow<A> (vec, size VEC_CHECK_PASS PASS_MEM_STAT);
858   memset (&((*vec)->address ()[oldsize]), 0, sizeof (T) * (size - oldsize));
859 }
860
861
862 /* Replace the IXth element of this vector with a new value, VAL.  */
863
864 template<typename T>
865 void
866 vec_t<T>::replace (unsigned ix, const T &obj VEC_CHECK_DECL)
867 {
868   VEC_ASSERT (ix < prefix_.num_, "replace", T, base);
869   vec_[ix] = obj;
870 }
871
872
873 /* Insert an element, OBJ, at the IXth position of VEC.  There must be
874    sufficient space.  */
875
876 template<typename T>
877 void
878 vec_t<T>::quick_insert (unsigned ix, const T &obj VEC_CHECK_DECL)
879 {
880   VEC_ASSERT (prefix_.num_ < prefix_.alloc_, "insert", T, base);
881   VEC_ASSERT (ix <= prefix_.num_, "insert", T, base);
882   T *slot = &vec_[ix];
883   memmove (slot + 1, slot, (prefix_.num_++ - ix) * sizeof (T));
884   *slot = obj;
885 }
886
887
888 /* Insert an element, OBJ, at the IXth position of VEC. Reallocate
889    VEC, if necessary.  */
890
891 template<typename T>
892 template<enum vec_allocation_t A>
893 void
894 vec_t<T>::safe_insert (vec_t<T> **vec, unsigned ix, const T &obj VEC_CHECK_DECL
895                        MEM_STAT_DECL)
896 {
897   reserve<A> (vec, 1 VEC_CHECK_PASS PASS_MEM_STAT);
898   (*vec)->quick_insert (ix, obj VEC_CHECK_PASS);
899 }
900
901
902 /* Remove an element from the IXth position of this vector.  Ordering of
903    remaining elements is preserved.  This is an O(N) operation due to
904    a memmove.  */
905
906 template<typename T>
907 void
908 vec_t<T>::ordered_remove (unsigned ix VEC_CHECK_DECL)
909 {
910   VEC_ASSERT (ix < prefix_.num_, "remove", T, base);
911   T *slot = &vec_[ix];
912   memmove (slot, slot + 1, (--prefix_.num_ - ix) * sizeof (T));
913 }
914
915
916 /* Remove an element from the IXth position of VEC.  Ordering of
917    remaining elements is destroyed.  This is an O(1) operation.  */
918
919 template<typename T>
920 void
921 vec_t<T>::unordered_remove (unsigned ix VEC_CHECK_DECL)
922 {
923   VEC_ASSERT (ix < prefix_.num_, "remove", T, base);
924   vec_[ix] = vec_[--prefix_.num_];
925 }
926
927
928 /* Remove LEN elements starting at the IXth.  Ordering is retained.
929    This is an O(N) operation due to memmove.  */
930
931 template<typename T>
932 void
933 vec_t<T>::block_remove (unsigned ix, unsigned len VEC_CHECK_DECL)
934 {
935   VEC_ASSERT (ix + len <= prefix_.num_, "block_remove", T, base);
936   T *slot = &vec_[ix];
937   prefix_.num_ -= len;
938   memmove (slot, slot + len, (prefix_.num_ - ix) * sizeof (T));
939 }
940
941 /* Sort the contents of V with qsort.  Use CMP as the comparison function.  */
942 #define VEC_qsort(T,V,CMP)                                              \
943         qsort (VEC_address (T, V), VEC_length (T, V), sizeof (T), CMP)
944
945
946 /* Find and return the first position in which OBJ could be inserted
947    without changing the ordering of this vector.  LESSTHAN is a
948    function that returns true if the first argument is strictly less
949    than the second.  */
950
951 template<typename T>
952 unsigned
953 vec_t<T>::lower_bound (T obj, bool (*lessthan)(const T &, const T &)) const
954 {
955   unsigned int len = VEC_length (T, this);
956   unsigned int half, middle;
957   unsigned int first = 0;
958   while (len > 0)
959     {
960       half = len / 2;
961       middle = first;
962       middle += half;
963       T middle_elem = (*this)[middle];
964       if (lessthan (middle_elem, obj))
965         {
966           first = middle;
967           ++first;
968           len = len - half - 1;
969         }
970       else
971         len = half;
972     }
973   return first;
974 }
975
976
977 void *vec_heap_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL);
978 void *vec_gc_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL);
979
980 /* Ensure there are at least RESERVE free slots in VEC_, growing
981    exponentially.  If RESERVE < 0 grow exactly, else grow
982    exponentially.  As a special case, if VEC_ is NULL, and RESERVE is
983    0, no vector will be created. */
984
985 template<typename T>
986 template<enum vec_allocation_t A>
987 vec_t<T> *
988 vec_t<T>::reserve (vec_t<T> *vec, int reserve MEM_STAT_DECL)
989 {
990   void *res = NULL;
991   size_t off = offsetof (vec_t<T>, vec_);
992   size_t sz = sizeof (T);
993
994   switch (A)
995     {
996       case gc:
997         res = vec_gc_o_reserve_1 (vec, reserve, off, sz, false PASS_MEM_STAT);
998         break;
999       case heap:
1000         res = vec_heap_o_reserve_1 (vec, reserve, off, sz, false PASS_MEM_STAT);
1001         break;
1002       case stack:
1003         res = vec_stack_o_reserve (vec, reserve, off, sz PASS_MEM_STAT);
1004         break;
1005     }
1006
1007   return static_cast <vec_t<T> *> (res);
1008 }
1009
1010
1011 /* Ensure there are at least RESERVE free slots in VEC, growing
1012    exactly.  If RESERVE < 0 grow exactly, else grow exponentially.  As
1013    a special case, if VEC is NULL, and RESERVE is 0, no vector will be
1014    created. */
1015
1016 template<typename T>
1017 template<enum vec_allocation_t A>
1018 vec_t<T> *
1019 vec_t<T>::reserve_exact (vec_t<T> *vec, int reserve MEM_STAT_DECL)
1020 {
1021   void *res = NULL;
1022   size_t off = sizeof (struct vec_prefix);
1023   size_t sz = sizeof (T);
1024
1025   gcc_assert (offsetof (vec_t<T>, vec_) == sizeof (struct vec_prefix));
1026
1027   switch (A)
1028     {
1029       case gc:
1030         res = vec_gc_o_reserve_1 (vec, reserve, off, sz, true PASS_MEM_STAT);
1031         break;
1032       case heap:
1033         res = vec_heap_o_reserve_1 (vec, reserve, off, sz, true PASS_MEM_STAT);
1034         break;
1035       case stack:
1036         res = vec_stack_o_reserve_exact (vec, reserve, off, sz PASS_MEM_STAT);
1037         break;
1038     }
1039
1040   return static_cast <vec_t<T> *> (res);
1041 }
1042
1043 #endif /* GCC_VEC_H */