Mercurial > hg > CbC > CbC_gcc
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 */ |