comparison gcc/vec.h @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
1 /* Vector API for GNU compiler. 1 /* Vector API for GNU compiler.
2 Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. 2 Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
3 Contributed by Nathan Sidwell <nathan@codesourcery.com> 3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
84 is created. You can then define either or both garbage collected 84 is created. You can then define either or both garbage collected
85 and heap allocated versions. The allocation mechanism is specified 85 and heap allocated versions. The allocation mechanism is specified
86 when the type is defined, and is therefore part of the type. If 86 when the type is defined, and is therefore part of the type. If
87 you need both gc'd and heap allocated versions, you still must have 87 you need both gc'd and heap allocated versions, you still must have
88 *exactly* one definition of the common non-memory managed base vector. 88 *exactly* one definition of the common non-memory managed base vector.
89 89
90 If you need to directly manipulate a vector, then the 'address' 90 If you need to directly manipulate a vector, then the 'address'
91 accessor will return the address of the start of the vector. Also 91 accessor will return the address of the start of the vector. Also
92 the 'space' predicate will tell you whether there is spare capacity 92 the 'space' predicate will tell you whether there is spare capacity
93 in the vector. You will not normally need to use these two functions. 93 in the vector. You will not normally need to use these two functions.
94 94
95 Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro, to 95 Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro, to
96 get the non-memory allocation version, and then a 96 get the non-memory allocation version, and then a
97 DEF_VEC_ALLOC_{O,P,I}(TYPEDEF,ALLOC) macro to get memory managed 97 DEF_VEC_ALLOC_{O,P,I}(TYPEDEF,ALLOC) macro to get memory managed
98 vectors. Variables of vector type are declared using a 98 vectors. Variables of vector type are declared using a
99 VEC(TYPEDEF,ALLOC) macro. The ALLOC argument specifies the 99 VEC(TYPEDEF,ALLOC) macro. The ALLOC argument specifies the
202 202
203 #define VEC_free(T,A,V) (VEC_OP(T,A,free)(&V)) 203 #define VEC_free(T,A,V) (VEC_OP(T,A,free)(&V))
204 204
205 /* Use these to determine the required size and initialization of a 205 /* Use these to determine the required size and initialization of a
206 vector embedded within another structure (as the final member). 206 vector embedded within another structure (as the final member).
207 207
208 size_t VEC_T_embedded_size(int reserve); 208 size_t VEC_T_embedded_size(int reserve);
209 void VEC_T_embedded_init(VEC(T) *v, int reserve); 209 void VEC_T_embedded_init(VEC(T) *v, int reserve);
210 210
211 These allow the caller to perform the memory allocation. */ 211 These allow the caller to perform the memory allocation. */
212 212
213 #define VEC_embedded_size(T,N) (VEC_OP(T,base,embedded_size)(N)) 213 #define VEC_embedded_size(T,N) (VEC_OP(T,base,embedded_size)(N))
214 #define VEC_embedded_init(T,O,N) (VEC_OP(T,base,embedded_init)(VEC_BASE(O),N)) 214 #define VEC_embedded_init(T,O,N) (VEC_OP(T,base,embedded_init)(VEC_BASE(O),N))
215 215
220 old vectors need not be allocated by the same mechanism. */ 220 old vectors need not be allocated by the same mechanism. */
221 221
222 #define VEC_copy(T,A,V) (VEC_OP(T,A,copy)(VEC_BASE(V) MEM_STAT_INFO)) 222 #define VEC_copy(T,A,V) (VEC_OP(T,A,copy)(VEC_BASE(V) MEM_STAT_INFO))
223 223
224 /* Determine if a vector has additional capacity. 224 /* Determine if a vector has additional capacity.
225 225
226 int VEC_T_space (VEC(T) *v,int reserve) 226 int VEC_T_space (VEC(T) *v,int reserve)
227 227
228 If V has space for RESERVE additional entries, return nonzero. You 228 If V has space for RESERVE additional entries, return nonzero. You
229 usually only need to use this if you are doing your own vector 229 usually only need to use this if you are doing your own vector
230 reallocation, for instance on an embedded vector. This returns 230 reallocation, for instance on an embedded vector. This returns
258 258
259 /* Push object with no reallocation 259 /* Push object with no reallocation
260 T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer 260 T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
261 T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer 261 T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
262 T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object 262 T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
263 263
264 Push a new element onto the end, returns a pointer to the slot 264 Push a new element onto the end, returns a pointer to the slot
265 filled in. For object vectors, the new value can be NULL, in which 265 filled in. For object vectors, the new value can be NULL, in which
266 case NO initialization is performed. There must 266 case NO initialization is performed. There must
267 be sufficient space in the vector. */ 267 be sufficient space in the vector. */
268 268
271 271
272 /* Push object with reallocation 272 /* Push object with reallocation
273 T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Integer 273 T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Integer
274 T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Pointer 274 T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Pointer
275 T *VEC_T_A_safe_push (VEC(T,A) *&v, T *obj); // Object 275 T *VEC_T_A_safe_push (VEC(T,A) *&v, T *obj); // Object
276 276
277 Push a new element onto the end, returns a pointer to the slot 277 Push a new element onto the end, returns a pointer to the slot
278 filled in. For object vectors, the new value can be NULL, in which 278 filled in. For object vectors, the new value can be NULL, in which
279 case NO initialization is performed. Reallocates V, if needed. */ 279 case NO initialization is performed. Reallocates V, if needed. */
280 280
281 #define VEC_safe_push(T,A,V,O) \ 281 #define VEC_safe_push(T,A,V,O) \
291 291
292 #define VEC_pop(T,V) (VEC_OP(T,base,pop)(VEC_BASE(V) VEC_CHECK_INFO)) 292 #define VEC_pop(T,V) (VEC_OP(T,base,pop)(VEC_BASE(V) VEC_CHECK_INFO))
293 293
294 /* Truncate to specific length 294 /* Truncate to specific length
295 void VEC_T_truncate (VEC(T) *v, unsigned len); 295 void VEC_T_truncate (VEC(T) *v, unsigned len);
296 296
297 Set the length as specified. The new length must be less than or 297 Set the length as specified. The new length must be less than or
298 equal to the current length. This is an O(1) operation. */ 298 equal to the current length. This is an O(1) operation. */
299 299
300 #define VEC_truncate(T,V,I) \ 300 #define VEC_truncate(T,V,I) \
301 (VEC_OP(T,base,truncate)(VEC_BASE(V),I VEC_CHECK_INFO)) 301 (VEC_OP(T,base,truncate)(VEC_BASE(V),I VEC_CHECK_INFO))
322 322
323 /* Replace element 323 /* Replace element
324 T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer 324 T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
325 T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer 325 T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
326 T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val); // Object 326 T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val); // Object
327 327
328 Replace the IXth element of V with a new value, VAL. For pointer 328 Replace the IXth element of V with a new value, VAL. For pointer
329 vectors returns the original value. For object vectors returns a 329 vectors returns the original value. For object vectors returns a
330 pointer to the new value. For object vectors the new value can be 330 pointer to the new value. For object vectors the new value can be
331 NULL, in which case no overwriting of the slot is actually 331 NULL, in which case no overwriting of the slot is actually
332 performed. */ 332 performed. */
336 336
337 /* Insert object with no reallocation 337 /* Insert object with no reallocation
338 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer 338 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
339 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer 339 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
340 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object 340 T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
341 341
342 Insert an element, VAL, at the IXth position of V. Return a pointer 342 Insert an element, VAL, at the IXth position of V. Return a pointer
343 to the slot created. For vectors of object, the new value can be 343 to the slot created. For vectors of object, the new value can be
344 NULL, in which case no initialization of the inserted slot takes 344 NULL, in which case no initialization of the inserted slot takes
345 place. There must be sufficient space. */ 345 place. There must be sufficient space. */
346 346
349 349
350 /* Insert object with reallocation 350 /* Insert object with reallocation
351 T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer 351 T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
352 T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer 352 T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
353 T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object 353 T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
354 354
355 Insert an element, VAL, at the IXth position of V. Return a pointer 355 Insert an element, VAL, at the IXth position of V. Return a pointer
356 to the slot created. For vectors of object, the new value can be 356 to the slot created. For vectors of object, the new value can be
357 NULL, in which case no initialization of the inserted slot takes 357 NULL, in which case no initialization of the inserted slot takes
358 place. Reallocate V, if necessary. */ 358 place. Reallocate V, if necessary. */
359 359
360 #define VEC_safe_insert(T,A,V,I,O) \ 360 #define VEC_safe_insert(T,A,V,I,O) \
361 (VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO)) 361 (VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO))
362 362
363 /* Remove element retaining order 363 /* Remove element retaining order
364 T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer 364 T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
365 T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer 365 T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
366 void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object 366 void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
367 367
368 Remove an element from the IXth position of V. Ordering of 368 Remove an element from the IXth position of V. Ordering of
369 remaining elements is preserved. For pointer vectors returns the 369 remaining elements is preserved. For pointer vectors returns the
370 removed object. This is an O(N) operation due to a memmove. */ 370 removed object. This is an O(N) operation due to a memmove. */
371 371
372 #define VEC_ordered_remove(T,V,I) \ 372 #define VEC_ordered_remove(T,V,I) \
374 374
375 /* Remove element destroying order 375 /* Remove element destroying order
376 T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer 376 T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
377 T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer 377 T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
378 void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object 378 void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
379 379
380 Remove an element from the IXth position of V. Ordering of 380 Remove an element from the IXth position of V. Ordering of
381 remaining elements is destroyed. For pointer vectors returns the 381 remaining elements is destroyed. For pointer vectors returns the
382 removed object. This is an O(1) operation. */ 382 removed object. This is an O(1) operation. */
383 383
384 #define VEC_unordered_remove(T,V,I) \ 384 #define VEC_unordered_remove(T,V,I) \
385 (VEC_OP(T,base,unordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO)) 385 (VEC_OP(T,base,unordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
386 386
387 /* Remove a block of elements 387 /* Remove a block of elements
388 void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len); 388 void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len);
389 389
390 Remove LEN elements starting at the IXth. Ordering is retained. 390 Remove LEN elements starting at the IXth. Ordering is retained.
391 This is an O(1) operation. */ 391 This is an O(1) operation. */
392 392
393 #define VEC_block_remove(T,V,I,L) \ 393 #define VEC_block_remove(T,V,I,L) \
394 (VEC_OP(T,base,block_remove)(VEC_BASE(V),I,L VEC_CHECK_INFO)) 394 (VEC_OP(T,base,block_remove)(VEC_BASE(V),I,L VEC_CHECK_INFO))
400 want to feed it to qsort), use this accessor. */ 400 want to feed it to qsort), use this accessor. */
401 401
402 #define VEC_address(T,V) (VEC_OP(T,base,address)(VEC_BASE(V))) 402 #define VEC_address(T,V) (VEC_OP(T,base,address)(VEC_BASE(V)))
403 403
404 /* Find the first index in the vector not less than the object. 404 /* Find the first index in the vector not less than the object.
405 unsigned VEC_T_lower_bound (VEC(T) *v, const T val, 405 unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
406 bool (*lessthan) (const T, const T)); // Integer 406 bool (*lessthan) (const T, const T)); // Integer
407 unsigned VEC_T_lower_bound (VEC(T) *v, const T val, 407 unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
408 bool (*lessthan) (const T, const T)); // Pointer 408 bool (*lessthan) (const T, const T)); // Pointer
409 unsigned VEC_T_lower_bound (VEC(T) *v, const T *val, 409 unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
410 bool (*lessthan) (const T*, const T*)); // Object 410 bool (*lessthan) (const T*, const T*)); // Object
411 411
412 Find the first position in which VAL could be inserted without 412 Find the first position in which VAL could be inserted without
413 changing the ordering of V. LESSTHAN is a function that returns 413 changing the ordering of V. LESSTHAN is a function that returns
414 true if the first argument is strictly less than the second. */ 414 true if the first argument is strictly less than the second. */
415 415
416 #define VEC_lower_bound(T,V,O,LT) \ 416 #define VEC_lower_bound(T,V,O,LT) \
417 (VEC_OP(T,base,lower_bound)(VEC_BASE(V),O,LT VEC_CHECK_INFO)) 417 (VEC_OP(T,base,lower_bound)(VEC_BASE(V),O,LT VEC_CHECK_INFO))
418 418
419 /* Reallocate an array of elements with prefix. */ 419 /* Reallocate an array of elements with prefix. */
420 extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL); 420 extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
438 438
439 #if ENABLE_CHECKING 439 #if ENABLE_CHECKING
440 #define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__ 440 #define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__
441 #define VEC_CHECK_DECL ,const char *file_,unsigned line_,const char *function_ 441 #define VEC_CHECK_DECL ,const char *file_,unsigned line_,const char *function_
442 #define VEC_CHECK_PASS ,file_,line_,function_ 442 #define VEC_CHECK_PASS ,file_,line_,function_
443 443
444 #define VEC_ASSERT(EXPR,OP,T,A) \ 444 #define VEC_ASSERT(EXPR,OP,T,A) \
445 (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0)) 445 (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0))
446 446
447 extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL) 447 extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL)
448 ATTRIBUTE_NORETURN; 448 ATTRIBUTE_NORETURN;
459 expansions of these macros you may need to change gengtype too. */ 459 expansions of these macros you may need to change gengtype too. */
460 460
461 #define VEC(T,A) VEC_##T##_##A 461 #define VEC(T,A) VEC_##T##_##A
462 #define VEC_OP(T,A,OP) VEC_##T##_##A##_##OP 462 #define VEC_OP(T,A,OP) VEC_##T##_##A##_##OP
463 463
464 /* Base of vector type, not user visible. */ 464 /* Base of vector type, not user visible. */
465 #define VEC_T(T,B) \ 465 #define VEC_T(T,B) \
466 typedef struct VEC(T,B) \ 466 typedef struct VEC(T,B) \
467 { \ 467 { \
468 unsigned num; \ 468 unsigned num; \
469 unsigned alloc; \ 469 unsigned alloc; \
470 T vec[1]; \ 470 T vec[1]; \
471 } VEC(T,B) 471 } VEC(T,B)
472 472
473 #define VEC_T_GTY(T,B) \ 473 #define VEC_T_GTY(T,B) \
474 typedef struct VEC(T,B) GTY(()) \ 474 typedef struct GTY(()) VEC(T,B) \
475 { \ 475 { \
476 unsigned num; \ 476 unsigned num; \
477 unsigned alloc; \ 477 unsigned alloc; \
478 T GTY ((length ("%h.num"))) vec[1]; \ 478 T GTY ((length ("%h.num"))) vec[1]; \
479 } VEC(T,B) 479 } VEC(T,B)
480 480
481 /* Derived vector type, user visible. */ 481 /* Derived vector type, user visible. */
482 #define VEC_TA_GTY(T,B,A,GTY) \ 482 #define VEC_TA_GTY(T,B,A,GTY) \
483 typedef struct VEC(T,A) GTY \ 483 typedef struct GTY VEC(T,A) \
484 { \ 484 { \
485 VEC(T,B) base; \ 485 VEC(T,B) base; \
486 } VEC(T,A) 486 } VEC(T,A)
487 487
488 #define VEC_TA(T,B,A) \ 488 #define VEC_TA(T,B,A) \
506 DEF_VEC_FUNC_P(T) \ 506 DEF_VEC_FUNC_P(T) \
507 struct vec_swallow_trailing_semi 507 struct vec_swallow_trailing_semi
508 #define DEF_VEC_ALLOC_I(T,A) \ 508 #define DEF_VEC_ALLOC_I(T,A) \
509 VEC_TA(T,base,A); \ 509 VEC_TA(T,base,A); \
510 DEF_VEC_ALLOC_FUNC_I(T,A) \ 510 DEF_VEC_ALLOC_FUNC_I(T,A) \
511 DEF_VEC_NONALLOC_FUNCS_I(T,A) \
511 struct vec_swallow_trailing_semi 512 struct vec_swallow_trailing_semi
512 513
513 /* Vector of pointer to object. */ 514 /* Vector of pointer to object. */
514 #define DEF_VEC_P(T) \ 515 #define DEF_VEC_P(T) \
515 static inline void VEC_OP (T,must_be,pointer_type) (void) \ 516 static inline void VEC_OP (T,must_be,pointer_type) (void) \
522 DEF_VEC_FUNC_P(T) \ 523 DEF_VEC_FUNC_P(T) \
523 struct vec_swallow_trailing_semi 524 struct vec_swallow_trailing_semi
524 #define DEF_VEC_ALLOC_P(T,A) \ 525 #define DEF_VEC_ALLOC_P(T,A) \
525 VEC_TA(T,base,A); \ 526 VEC_TA(T,base,A); \
526 DEF_VEC_ALLOC_FUNC_P(T,A) \ 527 DEF_VEC_ALLOC_FUNC_P(T,A) \
528 DEF_VEC_NONALLOC_FUNCS_P(T,A) \
527 struct vec_swallow_trailing_semi 529 struct vec_swallow_trailing_semi
528 530
529 #define DEF_VEC_FUNC_P(T) \ 531 #define DEF_VEC_FUNC_P(T) \
530 static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \ 532 static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
531 { \ 533 { \
556 *ptr = vec_->vec[ix_]; \ 558 *ptr = vec_->vec[ix_]; \
557 return 1; \ 559 return 1; \
558 } \ 560 } \
559 else \ 561 else \
560 { \ 562 { \
561 *ptr = 0; \ 563 *ptr = (T) 0; \
562 return 0; \ 564 return 0; \
563 } \ 565 } \
564 } \ 566 } \
565 \ 567 \
566 static inline size_t VEC_OP (T,base,embedded_size) \ 568 static inline size_t VEC_OP (T,base,embedded_size) \
714 static inline VEC(T,A) *VEC_OP (T,A,alloc) \ 716 static inline VEC(T,A) *VEC_OP (T,A,alloc) \
715 (int alloc_ MEM_STAT_DECL) \ 717 (int alloc_ MEM_STAT_DECL) \
716 { \ 718 { \
717 return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \ 719 return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \
718 PASS_MEM_STAT); \ 720 PASS_MEM_STAT); \
719 } \ 721 }
720 \ 722
723
724 #define DEF_VEC_NONALLOC_FUNCS_P(T,A) \
721 static inline void VEC_OP (T,A,free) \ 725 static inline void VEC_OP (T,A,free) \
722 (VEC(T,A) **vec_) \ 726 (VEC(T,A) **vec_) \
723 { \ 727 { \
724 if (*vec_) \ 728 if (*vec_) \
725 vec_##A##_free (*vec_); \ 729 vec_##A##_free (*vec_); \
812 DEF_VEC_FUNC_O(T) \ 816 DEF_VEC_FUNC_O(T) \
813 struct vec_swallow_trailing_semi 817 struct vec_swallow_trailing_semi
814 #define DEF_VEC_ALLOC_O(T,A) \ 818 #define DEF_VEC_ALLOC_O(T,A) \
815 VEC_TA(T,base,A); \ 819 VEC_TA(T,base,A); \
816 DEF_VEC_ALLOC_FUNC_O(T,A) \ 820 DEF_VEC_ALLOC_FUNC_O(T,A) \
821 DEF_VEC_NONALLOC_FUNCS_O(T,A) \
817 struct vec_swallow_trailing_semi 822 struct vec_swallow_trailing_semi
818 823
819 #define DEF_VEC_FUNC_O(T) \ 824 #define DEF_VEC_FUNC_O(T) \
820 static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \ 825 static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
821 { \ 826 { \
993 { \ 998 { \
994 return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_, \ 999 return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_, \
995 offsetof (VEC(T,A),base.vec), \ 1000 offsetof (VEC(T,A),base.vec), \
996 sizeof (T) \ 1001 sizeof (T) \
997 PASS_MEM_STAT); \ 1002 PASS_MEM_STAT); \
998 } \ 1003 }
999 \ 1004
1005 #define DEF_VEC_NONALLOC_FUNCS_O(T,A) \
1000 static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ 1006 static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
1001 { \ 1007 { \
1002 size_t len_ = vec_ ? vec_->num : 0; \ 1008 size_t len_ = vec_ ? vec_->num : 0; \
1003 VEC (T,A) *new_vec_ = NULL; \ 1009 VEC (T,A) *new_vec_ = NULL; \
1004 \ 1010 \
1097 (int alloc_ MEM_STAT_DECL) \ 1103 (int alloc_ MEM_STAT_DECL) \
1098 { \ 1104 { \
1099 return (VEC(T,A) *) vec_##A##_o_reserve_exact \ 1105 return (VEC(T,A) *) vec_##A##_o_reserve_exact \
1100 (NULL, alloc_, offsetof (VEC(T,A),base.vec), \ 1106 (NULL, alloc_, offsetof (VEC(T,A),base.vec), \
1101 sizeof (T) PASS_MEM_STAT); \ 1107 sizeof (T) PASS_MEM_STAT); \
1102 } \ 1108 }
1103 \ 1109
1110 #define DEF_VEC_NONALLOC_FUNCS_I(T,A) \
1104 static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ 1111 static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
1105 { \ 1112 { \
1106 size_t len_ = vec_ ? vec_->num : 0; \ 1113 size_t len_ = vec_ ? vec_->num : 0; \
1107 VEC (T,A) *new_vec_ = NULL; \ 1114 VEC (T,A) *new_vec_ = NULL; \
1108 \ 1115 \
1193 \ 1200 \
1194 return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \ 1201 return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
1195 VEC_CHECK_PASS); \ 1202 VEC_CHECK_PASS); \
1196 } 1203 }
1197 1204
1205 /* We support a vector which starts out with space on the stack and
1206 switches to heap space when forced to reallocate. This works a
1207 little differently. Instead of DEF_VEC_ALLOC_P(TYPE, heap|gc), use
1208 DEF_VEC_ALLOC_P_STACK(TYPE). This uses alloca to get the initial
1209 space; because alloca can not be usefully called in an inline
1210 function, and because a macro can not define a macro, you must then
1211 write a #define for each type:
1212
1213 #define VEC_{TYPE}_stack_alloc(alloc) \
1214 VEC_stack_alloc({TYPE}, alloc)
1215
1216 This is really a hack and perhaps can be made better. Note that
1217 this macro will wind up evaluating the ALLOC parameter twice.
1218
1219 Only the initial allocation will be made using alloca, so pass a
1220 reasonable estimate that doesn't use too much stack space; don't
1221 pass zero. Don't return a VEC(TYPE,stack) vector from the function
1222 which allocated it. */
1223
1224 extern void *vec_stack_p_reserve (void *, int MEM_STAT_DECL);
1225 extern void *vec_stack_p_reserve_exact (void *, int MEM_STAT_DECL);
1226 extern void *vec_stack_p_reserve_exact_1 (int, void *);
1227 extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
1228 extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
1229 MEM_STAT_DECL);
1230 extern void vec_stack_free (void *);
1231
1232 #ifdef GATHER_STATISTICS
1233 #define VEC_stack_alloc(T,alloc,name,line,function) \
1234 (VEC_OP (T,stack,alloc1) \
1235 (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
1236 #else
1237 #define VEC_stack_alloc(T,alloc) \
1238 (VEC_OP (T,stack,alloc1) \
1239 (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
1240 #endif
1241
1242 #define DEF_VEC_ALLOC_P_STACK(T) \
1243 VEC_TA(T,base,stack); \
1244 DEF_VEC_ALLOC_FUNC_P_STACK(T) \
1245 DEF_VEC_NONALLOC_FUNCS_P(T,stack) \
1246 struct vec_swallow_trailing_semi
1247
1248 #define DEF_VEC_ALLOC_FUNC_P_STACK(T) \
1249 static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
1250 (int alloc_, VEC(T,stack)* space) \
1251 { \
1252 return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
1253 }
1254
1255 #define DEF_VEC_ALLOC_O_STACK(T) \
1256 VEC_TA(T,base,stack); \
1257 DEF_VEC_ALLOC_FUNC_O_STACK(T) \
1258 DEF_VEC_NONALLOC_FUNCS_O(T,stack) \
1259 struct vec_swallow_trailing_semi
1260
1261 #define DEF_VEC_ALLOC_FUNC_O_STACK(T) \
1262 static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
1263 (int alloc_, VEC(T,stack)* space) \
1264 { \
1265 return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
1266 }
1267
1268 #define DEF_VEC_ALLOC_I_STACK(T) \
1269 VEC_TA(T,base,stack); \
1270 DEF_VEC_ALLOC_FUNC_I_STACK(T) \
1271 DEF_VEC_NONALLOC_FUNCS_I(T,stack) \
1272 struct vec_swallow_trailing_semi
1273
1274 #define DEF_VEC_ALLOC_FUNC_I_STACK(T) \
1275 static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
1276 (int alloc_, VEC(T,stack)* space) \
1277 { \
1278 return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
1279 }
1280
1198 #endif /* GCC_VEC_H */ 1281 #endif /* GCC_VEC_H */