SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+ THREADCFLAGS = @THREADCFLAGS@
THREADLIBS = @THREADLIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = foreign
+AUTOMAKE_OPTIONS = foreign no-dist
noinst_HEADERS = gc.h gc_backptr.h gc_local_alloc.h \
gc_pthread_redirects.h gc_cpp.h
/* Names to predefine in the preprocessor for this target machine. */
- struct base_arch_s {
+ struct base_arch_s
+ {
/* Assembler only. */
int asm_only;
/* Core have 'EICALL' and 'EIJMP' instructions. */
int have_eijmp_eicall;
- /* Reserved for xmega architecture. */
- int reserved;
+ /* This is an XMEGA core. */
+ int xmega_p;
- /* Reserved for xmega architecture. */
- int reserved2;
+ /* This core has the RAMPD special function register
+ and thus also the RAMPX, RAMPY and RAMPZ registers. */
+ int have_rampd;
/* Default start of data section address for architecture. */
int default_data_section_start;
+ /* Offset between SFR address and RAM address:
+ SFR-address = RAM-address - sfr_offset */
+ int sfr_offset;
+
+ /* Architecture id to built-in define __AVR_ARCH__ (NULL -> no macro) */
const char *const macro;
/* Architecture name. */
ARCH_AVR4,
ARCH_AVR5,
ARCH_AVR51,
- ARCH_AVR6
+ ARCH_AVR6,
+ ARCH_AVRXMEGA2,
+ ARCH_AVRXMEGA4,
+ ARCH_AVRXMEGA5,
+ ARCH_AVRXMEGA6,
+ ARCH_AVRXMEGA7
};
struct mcu_type_s {
/* Stack pointer have 8 bits width. */
int short_sp;
+ /* Some AVR devices have a core erratum when skipping a 2-word instruction.
+ Skip instructions are: SBRC, SBRS, SBIC, SBIS, CPSE.
+ Problems will occur with return address is IRQ executes during the
+ skip sequence.
+
+ A support ticket from Atmel returned the following information:
+
+ Subject: (ATTicket:644469) On AVR skip-bug core Erratum
+ From: avr@atmel.com Date: 2011-07-27
+ (Please keep the subject when replying to this mail)
+
+ This errata exists only in AT90S8515 and ATmega103 devices.
+
+ For information please refer the following respective errata links
+ http://www.atmel.com/dyn/resources/prod_documents/doc2494.pdf
+ http://www.atmel.com/dyn/resources/prod_documents/doc1436.pdf */
+
+ /* Core Erratum: Must not skip 2-word instruction. */
+ int errata_skip;
+
/* Start of data section. */
int data_section_start;
+ /* Number of 64k segments in the flash. */
+ int n_flash;
+
/* Name of device library. */
const char *const library_name;
};
extern const struct mcu_type_s avr_mcu_types[];
extern const struct base_arch_s avr_arch_types[];
- #define TARGET_CPU_CPP_BUILTINS() avr_cpu_cpp_builtins (pfile)
+ typedef struct
+ {
+ /* Id of the address space as used in c_register_addr_space */
+ unsigned char id;
- #if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)
- extern GTY(()) section *progmem_section;
- #endif
+ /* Flavour of memory: 0 = RAM, 1 = Flash */
+ int memory_class;
+
+ /* Width of pointer (in bytes) */
+ int pointer_size;
+
+ /* Name of the address space as visible to the user */
+ const char *name;
+
+ /* Segment (i.e. 64k memory chunk) number. */
+ int segment;
+
+ /* Section prefix, e.g. ".progmem1.data" */
+ const char *section_name;
+ } avr_addrspace_t;
+
+ extern const avr_addrspace_t avr_addrspace[];
+
+ /* Known address spaces */
+
+ enum
+ {
+ ADDR_SPACE_RAM, /* ADDR_SPACE_GENERIC */
+ ADDR_SPACE_FLASH,
+ ADDR_SPACE_FLASH1,
+ ADDR_SPACE_FLASH2,
+ ADDR_SPACE_FLASH3,
+ ADDR_SPACE_FLASH4,
+ ADDR_SPACE_FLASH5,
+ ADDR_SPACE_MEMX,
+ /* Sentinel */
+ ADDR_SPACE_COUNT
+ };
+
+ #define TARGET_CPU_CPP_BUILTINS() avr_cpu_cpp_builtins (pfile)
#define AVR_HAVE_JMP_CALL (avr_current_arch->have_jmp_call && !TARGET_SHORT_CALLS)
#define AVR_HAVE_MUL (avr_current_arch->have_mul)
#define AVR_HAVE_MOVW (avr_current_arch->have_movw_lpmx)
#define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx)
- #define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm)
+ #define AVR_HAVE_ELPM (avr_current_arch->have_elpm)
+ #define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx)
+ #define AVR_HAVE_RAMPD (avr_current_arch->have_rampd)
+ #define AVR_HAVE_RAMPX (avr_current_arch->have_rampd)
+ #define AVR_HAVE_RAMPY (avr_current_arch->have_rampd)
+ #define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm \
+ || avr_current_arch->have_rampd)
#define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall)
- #define AVR_HAVE_8BIT_SP (avr_current_device->short_sp || TARGET_TINY_STACK)
+
+ /* Handling of 8-bit SP versus 16-bit SP is as follows:
+
+ -msp8 is used internally to select the right multilib for targets with
+ 8-bit SP. -msp8 is set automatically by DRIVER_SELF_SPECS for devices
+ with 8-bit SP or by multilib generation machinery. If a frame pointer is
+ needed and SP is only 8 bits wide, SP is zero-extended to get FP.
+
+ TARGET_TINY_STACK is triggered by -mtiny-stack which is a user option.
+ This option has no effect on multilib selection. It serves to save some
+ bytes on 16-bit SP devices by only changing SP_L and leaving SP_H alone.
+
+ These two properties are reflected by built-in macros __AVR_SP8__ resp.
+ __AVR_HAVE_8BIT_SP__ and __AVR_HAVE_16BIT_SP__. During multilib generation
+ there is always __AVR_SP8__ == __AVR_HAVE_8BIT_SP__. */
+
+ #define AVR_HAVE_8BIT_SP \
+ (avr_current_device->short_sp || TARGET_TINY_STACK || avr_sp8)
+
+ #define AVR_HAVE_SPH (!avr_sp8)
#define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL)
#define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
- #define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)");
+ #define AVR_XMEGA (avr_current_arch->xmega_p)
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0
/* No data type wants to be aligned rounder than this. */
#define BIGGEST_ALIGNMENT 8
- #define MAX_OFILE_ALIGNMENT (32768 * 8)
-
#define TARGET_VTABLE_ENTRY_ALIGN 8
#define STRICT_ALIGNMENT 0
#define REGNO_REG_CLASS(R) avr_regno_reg_class(R)
- /* The following macro defines cover classes for Integrated Register
- Allocator. Cover classes is a set of non-intersected register
- classes covering all hard registers used for register allocation
- purpose. Any move between two registers of a cover class should be
- cheaper than load or store of the registers. The macro value is
- array of register classes with LIM_REG_CLASSES used as the end
- marker. */
-
- #define IRA_COVER_CLASSES \
- { \
- GENERAL_REGS, LIM_REG_CLASSES \
- }
-
- #define BASE_REG_CLASS (reload_completed ? BASE_POINTER_REGS : POINTER_REGS)
+ #define MODE_CODE_BASE_REG_CLASS(mode, as, outer_code, index_code) \
+ avr_mode_code_base_reg_class (mode, as, outer_code, index_code)
#define INDEX_REG_CLASS NO_REGS
- #define REGNO_OK_FOR_BASE_P(r) (((r) < FIRST_PSEUDO_REGISTER \
- && ((r) == REG_X \
- || (r) == REG_Y \
- || (r) == REG_Z \
- || (r) == ARG_POINTER_REGNUM)) \
- || (reg_renumber \
- && (reg_renumber[r] == REG_X \
- || reg_renumber[r] == REG_Y \
- || reg_renumber[r] == REG_Z \
- || (reg_renumber[r] \
- == ARG_POINTER_REGNUM))))
+ #define REGNO_MODE_CODE_OK_FOR_BASE_P(num, mode, as, outer_code, index_code) \
+ avr_regno_mode_code_ok_for_base_p (num, mode, as, outer_code, index_code)
#define REGNO_OK_FOR_INDEX_P(NUM) 0
- #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
+ #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
+ avr_hard_regno_call_part_clobbered (REGNO, MODE)
- #define CLASS_MAX_NREGS(CLASS, MODE) class_max_nregs (CLASS, MODE)
+ #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
#define STACK_PUSH_CODE POST_DEC
#define STACK_GROWS_DOWNWARD
- #define STARTING_FRAME_OFFSET 1
+ #define STARTING_FRAME_OFFSET avr_starting_frame_offset()
#define STACK_POINTER_OFFSET 1
#define FUNCTION_ARG_REGNO_P(r) function_arg_regno_p(r)
- extern int avr_reg_order[];
-
- #define RET_REGISTER avr_ret_register ()
-
- #define LIBCALL_VALUE(MODE) avr_libcall_value (MODE)
-
- #define FUNCTION_VALUE_REGNO_P(N) ((int) (N) == RET_REGISTER)
-
#define DEFAULT_PCC_STRUCT_RETURN 0
#define EPILOGUE_USES(REGNO) avr_epilogue_uses(REGNO)
#define MAX_REGS_PER_ADDRESS 1
- #define REG_OK_FOR_BASE_NOSTRICT_P(X) \
- (REGNO (X) >= FIRST_PSEUDO_REGISTER || REG_OK_FOR_BASE_STRICT_P(X))
-
- #define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-
- /* LEGITIMIZE_RELOAD_ADDRESS will allow register R26/27 to be used, where it
- is no worse than normal base pointers R28/29 and R30/31. For example:
- If base offset is greater than 63 bytes or for R++ or --R addressing. */
-
- #define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \
- do { \
- if (1&&(GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC)) \
- { \
- push_reload (XEXP (X,0), XEXP (X,0), &XEXP (X,0), &XEXP (X,0), \
- POINTER_REGS, GET_MODE (X),GET_MODE (X) , 0, 0, \
- OPNUM, RELOAD_OTHER); \
- goto WIN; \
- } \
- if (GET_CODE (X) == PLUS \
- && REG_P (XEXP (X, 0)) \
- && reg_equiv_constant[REGNO (XEXP (X, 0))] == 0 \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && INTVAL (XEXP (X, 1)) >= 1) \
- { \
- int fit = INTVAL (XEXP (X, 1)) <= (64 - GET_MODE_SIZE (MODE)); \
- if (fit) \
- { \
- if (reg_equiv_address[REGNO (XEXP (X, 0))] != 0) \
- { \
- int regno = REGNO (XEXP (X, 0)); \
- rtx mem = make_memloc (X, regno); \
- push_reload (XEXP (mem,0), NULL, &XEXP (mem,0), NULL, \
- POINTER_REGS, Pmode, VOIDmode, 0, 0, \
- 1, ADDR_TYPE (TYPE)); \
- push_reload (mem, NULL_RTX, &XEXP (X, 0), NULL, \
- BASE_POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \
- OPNUM, TYPE); \
- goto WIN; \
- } \
- } \
- else if (! (frame_pointer_needed && XEXP (X,0) == frame_pointer_rtx)) \
- { \
- push_reload (X, NULL_RTX, &X, NULL, \
- POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \
- OPNUM, TYPE); \
- goto WIN; \
- } \
- } \
- } while(0)
-
- #define LEGITIMATE_CONSTANT_P(X) 1
-
- #define BRANCH_COST(speed_p, predictable_p) 0
+ #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_L,WIN) \
+ do { \
+ rtx new_x = avr_legitimize_reload_address (&(X), MODE, OPNUM, TYPE, \
+ ADDR_TYPE (TYPE), \
+ IND_L, make_memloc); \
+ if (new_x) \
+ { \
+ X = new_x; \
+ goto WIN; \
+ } \
+ } while (0)
+
+ #define BRANCH_COST(speed_p, predictable_p) avr_branch_cost
#define SLOW_BYTE_ACCESS 0
#define NO_FUNCTION_CSE
+ #define REGISTER_TARGET_PRAGMAS() \
+ do { \
+ avr_register_target_pragmas(); \
+ } while (0)
+
#define TEXT_SECTION_ASM_OP "\t.text"
#define DATA_SECTION_ASM_OP "\t.data"
#define ASM_APP_OFF "/* #NOAPP */\n"
- /* Switch into a generic section. */
- #define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
- #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
-
- #define ASM_OUTPUT_ASCII(FILE, P, SIZE) gas_output_ascii (FILE,P,SIZE)
-
#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == '\n' || ((C) == '$'))
- #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
- do { \
- fputs ("\t.comm ", (STREAM)); \
- assemble_name ((STREAM), (NAME)); \
- fprintf ((STREAM), ",%lu,1\n", (unsigned long)(SIZE)); \
- } while (0)
-
- #define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ROUNDED) \
- asm_output_bss ((FILE), (DECL), (NAME), (SIZE), (ROUNDED))
-
- #define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \
- do { \
- fputs ("\t.lcomm ", (STREAM)); \
- assemble_name ((STREAM), (NAME)); \
- fprintf ((STREAM), ",%d\n", (int)(SIZE)); \
- } while (0)
-
- #undef TYPE_ASM_OP
- #undef SIZE_ASM_OP
- #undef WEAK_ASM_OP
- #define TYPE_ASM_OP "\t.type\t"
- #define SIZE_ASM_OP "\t.size\t"
- #define WEAK_ASM_OP "\t.weak\t"
- /* Define the strings used for the special svr4 .type and .size directives.
- These strings generally do not vary from one system running svr4 to
- another, but if a given system (e.g. m88k running svr) needs to use
- different pseudo-op names for these, they may be overridden in the
- file which includes this one. */
-
-
- #undef TYPE_OPERAND_FMT
- #define TYPE_OPERAND_FMT "@%s"
- /* The following macro defines the format used to output the second
- operand of the .type assembler directive. Different svr4 assemblers
- expect various different forms for this operand. The one given here
- is just a default. You may need to override it in your machine-
- specific tm.h file (depending upon the particulars of your assembler). */
-
- #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- avr_asm_declare_function_name ((FILE), (NAME), (DECL))
-
- #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
- do { \
- if (!flag_inhibit_size_directive) \
- ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
- } while (0)
+ #define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN) \
+ avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, false)
- #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
- do { \
- ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
- size_directive_output = 0; \
- if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \
- { \
- size_directive_output = 1; \
- ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, \
- int_size_in_bytes (TREE_TYPE (DECL))); \
- } \
- ASM_OUTPUT_LABEL(FILE, NAME); \
- } while (0)
-
- #undef ASM_FINISH_DECLARE_OBJECT
- #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
- do { \
- const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
- HOST_WIDE_INT size; \
- if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
- && ! AT_END && TOP_LEVEL \
- && DECL_INITIAL (DECL) == error_mark_node \
- && !size_directive_output) \
- { \
- size_directive_output = 1; \
- size = int_size_in_bytes (TREE_TYPE (DECL)); \
- ASM_OUTPUT_SIZE_DIRECTIVE (FILE, name, size); \
- } \
- } while (0)
-
-
- #define ESCAPES \
- "\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
- \0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
- \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
- \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
- \1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
- \1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
- \1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
- \1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
- /* A table of bytes codes used by the ASM_OUTPUT_ASCII and
- ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
- corresponds to a particular byte value [0..255]. For any
- given byte value, if the value in the corresponding table
- position is zero, the given character can be output directly.
- If the table value is 1, the byte must be output as a \ooo
- octal escape. If the tables value is anything else, then the
- byte value should be output as a \ followed by the value
- in the table. Note that we can use standard UN*X escape
- sequences for many control characters, but we don't use
- \a to represent BEL because some svr4 assemblers (e.g. on
- the i386) don't know about that. Also, we don't use \v
- since some versions of gas, such as 2.2 did not accept it. */
-
- #define STRING_LIMIT ((unsigned) 64)
- #define STRING_ASM_OP "\t.string\t"
- /* Some svr4 assemblers have a limit on the number of characters which
- can appear in the operand of a .string directive. If your assembler
- has such a limitation, you should define STRING_LIMIT to reflect that
- limit. Note that at least some svr4 assemblers have a limit on the
- actual number of bytes in the double-quoted string, and that they
- count each character in an escape sequence as one byte. Thus, an
- escape sequence like \377 would count as four bytes.
-
- If your target assembler doesn't support the .string directive, you
- should define this to zero. */
+ #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+ #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \
+ avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, true)
/* Globalizing directive for a label. */
#define GLOBAL_ASM_OP ".global\t"
- #define SET_ASM_OP "\t.set\t"
-
- #define ASM_WEAKEN_LABEL(FILE, NAME) \
- do \
- { \
- fputs ("\t.weak\t", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputc ('\n', (FILE)); \
- } \
- while (0)
-
#define SUPPORTS_WEAK 1
- #define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
- sprintf (STRING, "*.%s%lu", PREFIX, (unsigned long)(NUM))
-
#define HAS_INIT_SECTION 1
#define REGISTER_NAMES { \
#define FINAL_PRESCAN_INSN(insn, operand, nop) final_prescan_insn (insn, operand,nop)
- #define PRINT_OPERAND(STREAM, X, CODE) print_operand (STREAM, X, CODE)
-
- #define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '~' || (CODE) == '!')
-
- #define PRINT_OPERAND_ADDRESS(STREAM, X) print_operand_address(STREAM, X)
-
- #define USER_LABEL_PREFIX ""
-
- #define ASSEMBLER_DIALECT AVR_HAVE_MOVW
-
#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \
{ \
gcc_assert (REGNO < 32); \
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
avr_output_addr_vec_elt(STREAM, VALUE)
- #define ASM_OUTPUT_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) \
- (switch_to_section (progmem_section), \
- (*targetm.asm_out.internal_label) (STREAM, PREFIX, NUM))
-
- #define ASM_OUTPUT_SKIP(STREAM, N) \
- fprintf (STREAM, "\t.skip %lu,0\n", (unsigned long)(N))
-
- #define ASM_OUTPUT_ALIGN(STREAM, POWER) \
- do { \
- if ((POWER) > 1) \
- fprintf (STREAM, "\t.p2align\t%d\n", POWER); \
+ #define ASM_OUTPUT_ALIGN(STREAM, POWER) \
+ do { \
+ if ((POWER) > 0) \
+ fprintf (STREAM, "\t.p2align\t%d\n", POWER); \
} while (0)
- #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
- default_elf_asm_output_external (FILE, DECL, NAME)
-
#define CASE_VECTOR_MODE HImode
#undef WORD_REGISTER_OPERATIONS
#define DOLLARS_IN_IDENTIFIERS 0
- #define NO_DOLLAR_IN_LABEL 1
-
#define TRAMPOLINE_SIZE 4
/* Store in cc_status the expressions
extern const char *avr_device_to_data_start (int argc, const char **argv);
extern const char *avr_device_to_startfiles (int argc, const char **argv);
extern const char *avr_device_to_devicelib (int argc, const char **argv);
+ extern const char *avr_device_to_sp8 (int argc, const char **argv);
- #define EXTRA_SPEC_FUNCTIONS \
- { "device_to_arch", avr_device_to_arch }, \
+ #define EXTRA_SPEC_FUNCTIONS \
+ { "device_to_arch", avr_device_to_arch }, \
{ "device_to_data_start", avr_device_to_data_start }, \
- { "device_to_startfile", avr_device_to_startfiles }, \
- { "device_to_devicelib", avr_device_to_devicelib },
+ { "device_to_startfile", avr_device_to_startfiles }, \
+ { "device_to_devicelib", avr_device_to_devicelib }, \
+ { "device_to_sp8", avr_device_to_sp8 },
+ #define DRIVER_SELF_SPECS " %:device_to_sp8(%{mmcu=*:%*}) "
#define CPP_SPEC ""
#define CC1_SPEC ""
pass to `cc1plus'. */
#define ASM_SPEC "%{mmcu=avr25:-mmcu=avr2;mmcu=avr35:-mmcu=avr3;mmcu=avr31:-mmcu=avr3;mmcu=avr51:-mmcu=avr5;\
- mmcu=*:-mmcu=%*}"
+ mmcu=*:-mmcu=%*} \
+ %{mmcu=*:%{!mmcu=avr2:%{!mmcu=at90s8515:%{!mmcu=avr31:%{!mmcu=atmega103:\
+ -mno-skip-bug}}}}}"
#define LINK_SPEC "\
%{mrelax:--relax\
#define TEST_HARD_REG_CLASS(CLASS, REGNO) \
TEST_HARD_REG_BIT (reg_class_contents[ (int) (CLASS)], REGNO)
- /* Note that the other files fail to use these
- in some of the places where they should. */
-
- #if defined(__STDC__) || defined(ALMOST_STDC)
- #define AS2(a,b,c) #a " " #b "," #c
- #define AS2C(b,c) " " #b "," #c
- #define AS3(a,b,c,d) #a " " #b "," #c "," #d
- #define AS1(a,b) #a " " #b
- #else
- #define AS1(a,b) "a b"
- #define AS2(a,b,c) "a b,c"
- #define AS2C(b,c) " b,c"
- #define AS3(a,b,c,d) "a b,c,d"
- #endif
- #define OUT_AS1(a,b) output_asm_insn (AS1(a,b), operands)
- #define OUT_AS2(a,b,c) output_asm_insn (AS2(a,b,c), operands)
#define CR_TAB "\n\t"
- #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
- #define DWARF2_DEBUGGING_INFO 1
-
#define DWARF2_ADDR_SIZE 4
- #define OBJECT_FORMAT_ELF
+ #define INCOMING_RETURN_ADDR_RTX avr_incoming_return_addr_rtx ()
+ #define INCOMING_FRAME_SP_OFFSET (AVR_3_BYTE_PC ? 3 : 2)
+
+ /* The caller's stack pointer value immediately before the call
+ is one byte below the first argument. */
+ #define ARG_POINTER_CFA_OFFSET(FNDECL) -1
+#define INCOMING_RETURN_ADDR_RTX avr_incoming_return_addr_rtx ()
+#define INCOMING_FRAME_SP_OFFSET (AVR_3_BYTE_PC ? 3 : 2)
+
+/* The caller's stack pointer value immediately before the call
+ is one byte below the first argument. */
+#define ARG_POINTER_CFA_OFFSET(FNDECL) -1
+
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
avr_hard_regno_rename_ok (OLD_REG, NEW_REG)
/* Current function stack size. */
int stack_usage;
+
+ /* 'true' if a callee might be tail called */
+ int sibcall_fails;
+
+ /* 'true' if the above is_foo predicates are sanity-checked to avoid
+ multiple diagnose for the same function. */
+ int attributes_checked_p;
};
+
+ /* AVR does not round pushes, but the existance of this macro is
+ required in order for pushes to be generated. */
+ #define PUSH_ROUNDING(X) (X)
+
+ /* Define prototype here to avoid build warning. Some files using
+ ACCUMULATE_OUTGOING_ARGS (directly or indirectly) include
+ tm.h but not tm_p.h. */
+ extern int avr_accumulate_outgoing_args (void);
+ #define ACCUMULATE_OUTGOING_ARGS avr_accumulate_outgoing_args()
+
+ #define INIT_EXPANDERS avr_init_expanders()
- # Copyright (C) 2008, 2010 Free Software Foundation, Inc.
+ # Copyright (C) 2008, 2010, 2011, 2012 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
- EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
+ # Only include multilibs for 680x0 and ColdFire CPUs with an MMU.
+ M68K_MLIB_CPU += && ((CPU ~ "^m680") || (CPU ~ "^mcf")) && (FLAGS ~ "FL_MMU")
- # Only include multilibs for 680x0 CPUs with an MMU.
- M68K_MLIB_CPU += && (CPU ~ "^m680") && (FLAGS ~ "FL_MMU")
+ ifeq ($(M68K_ARCH),m68k)
+ MULTIARCH_DIRNAME = $(call if_multiarch,m68k-linux-gnu)
+ endif
+ifeq ($(M68K_ARCH),m68k)
+MULTIARCH_DIRNAME = $(call if_multiarch,m68k-linux-gnu)
+endif
+
# This rule uses MULTILIB_MATCHES to generate a definition of
# SYSROOT_SUFFIX_SPEC.
sysroot-suffix.h: $(srcdir)/config/m68k/print-sysroot-suffix.sh
#include "target.h"
#include "target-def.h"
#include "df.h"
+ #include "opts.h"
+ #include "cfgloop.h"
/* This is used in the am33_2.0-linux-gnu port, in which global symbol
names are not prefixed by underscores, to tell whether to prefix a
symbol names from register names. */
int mn10300_protect_label;
- /* The selected processor. */
- enum processor_type mn10300_processor = PROCESSOR_DEFAULT;
-
- /* Processor type to select for tuning. */
- static const char * mn10300_tune_string = NULL;
-
/* Selected processor type for tuning. */
enum processor_type mn10300_tune_cpu = PROCESSOR_DEFAULT;
|| df_regs_ever_live_p (16) \
|| df_regs_ever_live_p (17)))
- /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
- static const struct default_options mn10300_option_optimization_table[] =
- {
- { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
- { OPT_LEVELS_NONE, 0, NULL, 0 }
- };
-
#define CC_FLAG_Z 1
#define CC_FLAG_N 2
#define CC_FLAG_C 4
static int cc_flags_for_mode(enum machine_mode);
static int cc_flags_for_code(enum rtx_code);
\f
- /* Implement TARGET_HANDLE_OPTION. */
-
- static bool
- mn10300_handle_option (size_t code,
- const char *arg ATTRIBUTE_UNUSED,
- int value)
- {
- switch (code)
- {
- case OPT_mam33:
- mn10300_processor = value ? PROCESSOR_AM33 : PROCESSOR_MN10300;
- return true;
-
- case OPT_mam33_2:
- mn10300_processor = (value
- ? PROCESSOR_AM33_2
- : MIN (PROCESSOR_AM33, PROCESSOR_DEFAULT));
- return true;
-
- case OPT_mam34:
- mn10300_processor = (value ? PROCESSOR_AM34 : PROCESSOR_DEFAULT);
- return true;
-
- case OPT_mtune_:
- mn10300_tune_string = arg;
- return true;
-
- default:
- return true;
- }
- }
-
/* Implement TARGET_OPTION_OVERRIDE. */
static void
/* Adjust the stack and restore callee-saved registers, if any. */
if (mn10300_can_use_rets_insn ())
- emit_jump_insn (gen_rtx_RETURN (VOIDmode));
+ emit_jump_insn (ret_rtx);
else
emit_jump_insn (gen_return_ret (GEN_INT (size + REG_SAVE_BYTES)));
}
if (xregno >= FIRST_PSEUDO_REGISTER && xregno != INVALID_REGNUM)
{
- addr = reg_equiv_mem [xregno];
+ addr = reg_equiv_mem (xregno);
if (addr)
addr = XEXP (addr, 0);
}
/* Return true when a parameter should be passed by reference. */
static bool
- mn10300_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ mn10300_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
enum machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{
from a function. If the result is NULL_RTX, the argument is pushed. */
static rtx
- mn10300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ mn10300_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
const_tree type, bool named ATTRIBUTE_UNUSED)
{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
rtx result = NULL_RTX;
int size;
(TYPE is null for libcalls where that information may not be available.) */
static void
- mn10300_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ mn10300_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
const_tree type, bool named ATTRIBUTE_UNUSED)
{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+
cum->nbytes += (mode != BLKmode
? (GET_MODE_SIZE (mode) + 3) & ~3
: (int_size_in_bytes (type) + 3) & ~3);
partially in registers and partially in memory. */
static int
- mn10300_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ mn10300_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int size;
/* We only support using 2 data registers as argument registers. */
return any_change ? x : NULL_RTX;
}
- /* Used by LEGITIMATE_CONSTANT_P(). Returns TRUE if X is a valid
+ /* Implement TARGET_LEGITIMATE_CONSTANT_P. Returns TRUE if X is a valid
constant. Note that some "constants" aren't valid, such as TLS
symbols and unconverted GOT-based references, so we eliminate
those here. */
- bool
- mn10300_legitimate_constant_p (rtx x)
+ static bool
+ mn10300_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
switch (GET_CODE (x))
{
return speed ? 2 : 6;
default:
- return rtx_cost (x, MEM, speed);
+ return rtx_cost (x, MEM, 0, speed);
}
}
to represent cycles. Size-relative costs are in bytes. */
static bool
- mn10300_rtx_costs (rtx x, int code, int outer_code, int *ptotal, bool speed)
+ mn10300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+ int *ptotal, bool speed)
{
/* This value is used for SYMBOL_REF etc where we want to pretend
we have a full 32-bit constant. */
i = INTVAL (XEXP (x, 1));
if (i == 1 || i == 4)
{
- total = 1 + rtx_cost (XEXP (x, 0), PLUS, speed);
+ total = 1 + rtx_cost (XEXP (x, 0), PLUS, 0, speed);
goto alldone;
}
}
if (! MEM_P (rtl))
return;
+
symbol = XEXP (rtl, 0);
if (GET_CODE (symbol) != SYMBOL_REF)
return;
return true;
}
+ /* This function is used to help split:
+
+ (set (reg) (and (reg) (int)))
+
+ into:
+
+ (set (reg) (shift (reg) (int))
+ (set (reg) (shift (reg) (int))
+
+ where the shitfs will be shorter than the "and" insn.
+
+ It returns the number of bits that should be shifted. A positive
+ values means that the low bits are to be cleared (and hence the
+ shifts should be right followed by left) whereas a negative value
+ means that the high bits are to be cleared (left followed by right).
+ Zero is returned when it would not be economical to split the AND. */
+
int
mn10300_split_and_operand_count (rtx op)
{
would be replacing 1 6-byte insn with 2 3-byte insns. */
if (count > (optimize_insn_for_speed_p () ? 2 : 4))
return 0;
- return -count;
+ return count;
}
else
{
extract_bundle (rtx insn, struct liw_data * pdata)
{
bool allow_consts = true;
- rtx p,s;
+ rtx p;
gcc_assert (pdata != NULL);
pdata->op = get_attr_liw_op (insn);
- s = SET_SRC (p);
-
switch (pdata->op)
{
case LIW_OP_MOV:
}
}
+ #define DUMP(reason, insn) \
+ do \
+ { \
+ if (dump_file) \
+ { \
+ fprintf (dump_file, reason "\n"); \
+ if (insn != NULL_RTX) \
+ print_rtl_single (dump_file, insn); \
+ fprintf(dump_file, "\n"); \
+ } \
+ } \
+ while (0)
+
+ /* Replace the BRANCH insn with a Lcc insn that goes to LABEL.
+ Insert a SETLB insn just before LABEL. */
+
+ static void
+ mn10300_insert_setlb_lcc (rtx label, rtx branch)
+ {
+ rtx lcc, comparison, cmp_reg;
+
+ if (LABEL_NUSES (label) > 1)
+ {
+ rtx insn;
+
+ /* This label is used both as an entry point to the loop
+ and as a loop-back point for the loop. We need to separate
+ these two functions so that the SETLB happens upon entry,
+ but the loop-back does not go to the SETLB instruction. */
+ DUMP ("Inserting SETLB insn after:", label);
+ insn = emit_insn_after (gen_setlb (), label);
+ label = gen_label_rtx ();
+ emit_label_after (label, insn);
+ DUMP ("Created new loop-back label:", label);
+ }
+ else
+ {
+ DUMP ("Inserting SETLB insn before:", label);
+ emit_insn_before (gen_setlb (), label);
+ }
+
+ comparison = XEXP (SET_SRC (PATTERN (branch)), 0);
+ cmp_reg = XEXP (comparison, 0);
+ gcc_assert (REG_P (cmp_reg));
+
+ /* If the comparison has not already been split out of the branch
+ then do so now. */
+ gcc_assert (REGNO (cmp_reg) == CC_REG);
+
+ if (GET_MODE (cmp_reg) == CC_FLOATmode)
+ lcc = gen_FLcc (comparison, label);
+ else
+ lcc = gen_Lcc (comparison, label);
+
+ lcc = emit_jump_insn_before (lcc, branch);
+ mark_jump_label (XVECEXP (PATTERN (lcc), 0, 0), lcc, 0);
+ JUMP_LABEL (lcc) = label;
+ DUMP ("Replacing branch insn...", branch);
+ DUMP ("... with Lcc insn:", lcc);
+ delete_insn (branch);
+ }
+
+ static bool
+ mn10300_block_contains_call (struct basic_block_def * block)
+ {
+ rtx insn;
+
+ FOR_BB_INSNS (block, insn)
+ if (CALL_P (insn))
+ return true;
+
+ return false;
+ }
+
+ static bool
+ mn10300_loop_contains_call_insn (loop_p loop)
+ {
+ basic_block * bbs;
+ bool result = false;
+ unsigned int i;
+
+ bbs = get_loop_body (loop);
+
+ for (i = 0; i < loop->num_nodes; i++)
+ if (mn10300_block_contains_call (bbs[i]))
+ {
+ result = true;
+ break;
+ }
+
+ free (bbs);
+ return result;
+ }
+
+ static void
+ mn10300_scan_for_setlb_lcc (void)
+ {
+ struct loops loops;
+ loop_iterator liter;
+ loop_p loop;
+
+ DUMP ("Looking for loops that can use the SETLB insn", NULL_RTX);
+
+ df_analyze ();
+ compute_bb_for_insn ();
+
+ /* Find the loops. */
+ if (flow_loops_find (& loops) < 1)
+ DUMP ("No loops found", NULL_RTX);
+ current_loops = & loops;
+
+ /* FIXME: For now we only investigate innermost loops. In practice however
+ if an inner loop is not suitable for use with the SETLB/Lcc insns, it may
+ be the case that its parent loop is suitable. Thus we should check all
+ loops, but work from the innermost outwards. */
+ FOR_EACH_LOOP (liter, loop, LI_ONLY_INNERMOST)
+ {
+ const char * reason = NULL;
+
+ /* Check to see if we can modify this loop. If we cannot
+ then set 'reason' to describe why it could not be done. */
+ if (loop->latch == NULL)
+ reason = "it contains multiple latches";
+ else if (loop->header != loop->latch)
+ /* FIXME: We could handle loops that span multiple blocks,
+ but this requires a lot more work tracking down the branches
+ that need altering, so for now keep things simple. */
+ reason = "the loop spans multiple blocks";
+ else if (mn10300_loop_contains_call_insn (loop))
+ reason = "it contains CALL insns";
+ else
+ {
+ rtx branch = BB_END (loop->latch);
+
+ gcc_assert (JUMP_P (branch));
+ if (single_set (branch) == NULL_RTX || ! any_condjump_p (branch))
+ /* We cannot optimize tablejumps and the like. */
+ /* FIXME: We could handle unconditional jumps. */
+ reason = "it is not a simple loop";
+ else
+ {
+ rtx label;
+
+ if (dump_file)
+ flow_loop_dump (loop, dump_file, NULL, 0);
+
+ label = BB_HEAD (loop->header);
+ gcc_assert (LABEL_P (label));
+
+ mn10300_insert_setlb_lcc (label, branch);
+ }
+ }
+
+ if (dump_file && reason != NULL)
+ fprintf (dump_file, "Loop starting with insn %d is not suitable because %s\n",
+ INSN_UID (BB_HEAD (loop->header)),
+ reason);
+ }
+
+ #if 0 /* FIXME: We should free the storage we allocated, but
+ for some unknown reason this leads to seg-faults. */
+ FOR_EACH_LOOP (liter, loop, 0)
+ free_simple_loop_desc (loop);
+
+ flow_loops_free (current_loops);
+ #endif
+
+ current_loops = NULL;
+
+ df_finish_pass (false);
+
+ DUMP ("SETLB scan complete", NULL_RTX);
+ }
+
static void
mn10300_reorg (void)
{
- if (TARGET_AM33)
+ /* These are optimizations, so only run them if optimizing. */
+ if (TARGET_AM33 && (optimize > 0 || optimize_size))
{
+ if (TARGET_ALLOW_SETLB)
+ mn10300_scan_for_setlb_lcc ();
+
if (TARGET_ALLOW_LIW)
mn10300_bundle_liw ();
}
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG mn10300_reorg
- #undef TARGET_EXCEPT_UNWIND_INFO
- #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
-
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA mn10300_asm_output_addr_const_extra
- #undef TARGET_DEFAULT_TARGET_FLAGS
- #define TARGET_DEFAULT_TARGET_FLAGS MASK_MULT_BUG | MASK_PTR_A0D0 | MASK_ALLOW_LIW
- #undef TARGET_HANDLE_OPTION
- #define TARGET_HANDLE_OPTION mn10300_handle_option
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE mn10300_option_override
- #undef TARGET_OPTION_OPTIMIZATION_TABLE
- #define TARGET_OPTION_OPTIMIZATION_TABLE mn10300_option_optimization_table
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO mn10300_encode_section_info
#define TARGET_LEGITIMATE_ADDRESS_P mn10300_legitimate_address_p
#undef TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS mn10300_delegitimize_address
+ #undef TARGET_LEGITIMATE_CONSTANT_P
+ #define TARGET_LEGITIMATE_CONSTANT_P mn10300_legitimate_constant_p
#undef TARGET_PREFERRED_RELOAD_CLASS
#define TARGET_PREFERRED_RELOAD_CLASS mn10300_preferred_reload_class
/* Subroutines used for code generation on picoChip processors.
- Copyright (C) 2001, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Contributed by Picochip Ltd. (http://www.picochip.com)
Maintained by Daniel Towner (daniel.towner@picochip.com) and
Hariharan Sandanagobalane (hariharan@picochip.com)
void picochip_init_libfuncs (void);
void picochip_reorg (void);
- int picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum,
+ int picochip_arg_partial_bytes (cumulative_args_t p_cum,
enum machine_mode mode,
tree type, bool named);
- rtx picochip_function_arg (CUMULATIVE_ARGS * p_cum,
+ rtx picochip_function_arg (cumulative_args_t p_cum,
enum machine_mode mode,
const_tree type, bool named);
- rtx picochip_incoming_function_arg (CUMULATIVE_ARGS * p_cum,
+ rtx picochip_incoming_function_arg (cumulative_args_t p_cum,
enum machine_mode mode,
const_tree type, bool named);
- void picochip_arg_advance (CUMULATIVE_ARGS * p_cum, enum machine_mode mode,
+ void picochip_arg_advance (cumulative_args_t p_cum, enum machine_mode mode,
const_tree type, bool named);
unsigned int picochip_function_arg_boundary (enum machine_mode mode,
const_tree type);
void picochip_init_builtins (void);
rtx picochip_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
- bool picochip_rtx_costs (rtx x, int code, int outer_code, int* total, bool speed);
+ bool picochip_rtx_costs (rtx x, int code, int outer_code, int opno,
+ int* total, bool speed);
bool picochip_return_in_memory(const_tree type,
const_tree fntype ATTRIBUTE_UNUSED);
bool picochip_legitimate_address_p (enum machine_mode, rtx, bool);
/* Determine which ALU to use for the instruction in
picochip_current_prescan_insn. */
static char picochip_get_vliw_alu_id (void);
-
- /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
- static const struct default_options picochip_option_optimization_table[] =
- {
- { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
- { OPT_LEVELS_NONE, 0, NULL, 0 }
- };
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION picochip_asm_named_section
- #undef TARGET_HAVE_NAMED_SECTIONS
- #define TARGET_HAVE_NAMED_SECTIONS 1
-
#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS 1
#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_option_override
- #undef TARGET_OPTION_OPTIMIZATION_TABLE
- #define TARGET_OPTION_OPTIMIZATION_TABLE picochip_option_optimization_table
+ /* The 2nd scheduling pass option is switched off, and a machine
+ dependent reorganisation ensures that it is run later on, after the
+ second jump optimisation. */
+ #undef TARGET_DELAY_SCHED2
+ #define TARGET_DELAY_SCHED2 true
- #undef TARGET_EXCEPT_UNWIND_INFO
- #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
+ /* Variable tracking should be run after all optimizations which
+ change order of insns. It also needs a valid CFG. */
+ #undef TARGET_DELAY_VARTRACK
+ #define TARGET_DELAY_VARTRACK true
+/* The 2nd scheduling pass option is switched off, and a machine
+ dependent reorganisation ensures that it is run later on, after the
+ second jump optimisation. */
+#undef TARGET_DELAY_SCHED2
+#define TARGET_DELAY_SCHED2 true
+
+/* Variable tracking should be run after all optimizations which
+ change order of insns. It also needs a valid CFG. */
+#undef TARGET_DELAY_VARTRACK
+#define TARGET_DELAY_VARTRACK true
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Determine where the next outgoing arg should be placed. */
rtx
- picochip_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ picochip_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
const_tree type, bool named ATTRIBUTE_UNUSED)
{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int reg = 0;
int type_align_in_units = 0;
int type_size_in_units;
passed in registers, which are then pushed onto the stack by the
function prologue). */
rtx
- picochip_incoming_function_arg (CUMULATIVE_ARGS *cum,
+ picochip_incoming_function_arg (cumulative_args_t cum,
enum machine_mode mode,
const_tree type, bool named)
{
/* Compute partial registers. */
int
- picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode,
+ picochip_arg_partial_bytes (cumulative_args_t p_cum, enum machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
{
int type_align_in_units = 0;
int new_offset = 0;
int offset_overflow = 0;
- unsigned cum = *((unsigned *) p_cum);
+ unsigned cum = *get_cumulative_args (p_cum);
/* VOIDmode is passed when computing the second argument to a `call'
pattern. This can be ignored. */
/* Advance the cumulative args counter CUM. */
void
- picochip_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ picochip_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
const_tree type, bool named ATTRIBUTE_UNUSED)
{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int type_align_in_units = 0;
int type_size_in_units;
int new_offset = 0;
rtvec p;
p = rtvec_alloc (2);
- RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
+ RTVEC_ELT (p, 0) = ret_rtx;
RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
gen_rtx_REG (Pmode, LINK_REGNUM));
emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
}
}
}
- else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
+ else if (NOTE_P (insn))
{
rtx prev = PREV_INSN (insn);
PREV_INSN (next) = prev;
NEXT_INSN (prev) = next;
- PREV_INSN (insn) = queue;
- queue = insn;
+ /* Ignore call_arg notes. They are expected to be just after the
+ call insn. If the call is start of a long VLIW, labels are
+ emitted in the middle of a VLIW, which our assembler can not
+ handle. */
+ if (NOTE_KIND (insn) != NOTE_INSN_CALL_ARG_LOCATION)
+ {
+ PREV_INSN (insn) = queue;
+ queue = insn;
+ }
}
}
/* Make sure we are not dropping debug instructions.*/
}
bool
- picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int* total, bool speed)
+ picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+ int opno ATTRIBUTE_UNUSED, int* total, bool speed)
{
int localTotal = 0;
picochip_init_builtins (void)
{
tree noreturn;
- tree endlink = void_list_node;
- tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
- tree unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink);
- tree long_endlink = tree_cons (NULL_TREE, long_integer_type_node, endlink);
- tree int_int_endlink =
- tree_cons (NULL_TREE, integer_type_node, int_endlink);
- tree int_int_int_endlink =
- tree_cons (NULL_TREE, integer_type_node, int_int_endlink);
- tree int_long_endlink =
- tree_cons (NULL_TREE, integer_type_node, long_endlink);
- tree long_int_int_int_endlink =
- tree_cons (NULL_TREE, long_integer_type_node, int_int_int_endlink);
tree int_ftype_int, int_ftype_int_int;
tree long_ftype_int, long_ftype_int_int_int;
tree void_ftype_void, unsigned_ftype_unsigned;
/* void func (void) */
- void_ftype_void = build_function_type (void_type_node, endlink);
+ void_ftype_void = build_function_type_list (void_type_node, NULL_TREE);
/* int func (int) */
- int_ftype_int = build_function_type (integer_type_node, int_endlink);
+ int_ftype_int = build_function_type_list (integer_type_node,
+ integer_type_node, NULL_TREE);
/* unsigned int func (unsigned int) */
- unsigned_ftype_unsigned = build_function_type (unsigned_type_node, unsigned_endlink);
+ unsigned_ftype_unsigned
+ = build_function_type_list (unsigned_type_node,
+ unsigned_type_node, NULL_TREE);
/* int func(int, int) */
int_ftype_int_int
- = build_function_type (integer_type_node, int_int_endlink);
+ = build_function_type_list (integer_type_node,
+ integer_type_node, integer_type_node,
+ NULL_TREE);
/* long func(int) */
- long_ftype_int = build_function_type (long_integer_type_node, int_endlink);
+ long_ftype_int = build_function_type_list (long_integer_type_node,
+ integer_type_node, NULL_TREE);
/* long func(int, int, int) */
long_ftype_int_int_int
- = build_function_type (long_integer_type_node, int_int_int_endlink);
+ = build_function_type_list (long_integer_type_node,
+ integer_type_node, integer_type_node,
+ integer_type_node, NULL_TREE);
/* int func(int, int, int) */
int_ftype_int_int_int
- = build_function_type (integer_type_node, int_int_int_endlink);
+ = build_function_type_list (integer_type_node,
+ integer_type_node, integer_type_node,
+ integer_type_node, NULL_TREE);
/* void func(int, long) */
void_ftype_int_long
- = build_function_type (void_type_node, int_long_endlink);
+ = build_function_type_list (void_type_node,
+ integer_type_node, long_integer_type_node,
+ NULL_TREE);
/* void func(long, int, int, int) */
void_ftype_long_int_int_int
- = build_function_type (void_type_node, long_int_int_int_endlink);
+ = build_function_type_list (void_type_node,
+ long_integer_type_node, integer_type_node,
+ integer_type_node, integer_type_node,
+ NULL_TREE);
/* Initialise the sign-bit-count function. */
add_builtin_function ("__builtin_sbc", int_ftype_int,
(match_operand 0 "rx_restricted_mem_operand"))
)
+ ;; Check that the operand is suitable as the source operand
+ ;; for a min/max instruction. This is the same as
+ ;; rx_source_operand except that CONST_INTs are allowed but
+ ;; REGs and SUBREGs are not.
+
+ (define_predicate "rx_minmaxex_operand"
+ (ior (match_operand 0 "immediate_operand")
+ (match_operand 0 "rx_restricted_mem_operand"))
+ )
+
;; Return true if OP is a store multiple operation. This looks like:
;;
;; [(set (SP) (MINUS (SP) (INT)))
)
(define_predicate "rx_zs_comparison_operator"
- (match_code "eq,ne,lt,ge")
+ (match_code "eq,ne")
)
;; GT and LE omitted due to operand swap required.
/* Standard problems for dataflow support routines.
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010 Free Software Foundation, Inc.
+ 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
Originally contributed by Michael P. Hayes
(m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
blocks within infinite loops. */
if (!reload_completed)
{
+ unsigned int pic_offset_table_regnum = PIC_OFFSET_TABLE_REGNUM;
/* Any reference to any pseudo before reload is a potential
reference of the frame pointer. */
bitmap_set_bit (&df->hardware_regs_used, FRAME_POINTER_REGNUM);
/* Any constant, or pseudo with constant equivalences, may
require reloading from memory using the pic register. */
- if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
- && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
- bitmap_set_bit (&df->hardware_regs_used, PIC_OFFSET_TABLE_REGNUM);
+ if (pic_offset_table_regnum != INVALID_REGNUM
+ && fixed_regs[pic_offset_table_regnum])
+ bitmap_set_bit (&df->hardware_regs_used, pic_offset_table_regnum);
}
EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi)
/* Remove all of the REG_DEAD or REG_UNUSED notes from INSN and add
- them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES. */
+ them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES. Remove also
+ REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE
+ as the bitmap of currently live registers. */
static void
- df_kill_notes (rtx insn)
+ df_kill_notes (rtx insn, bitmap live)
{
rtx *pprev = ®_NOTES (insn);
rtx link = *pprev;
}
break;
+ case REG_EQUAL:
+ case REG_EQUIV:
+ {
+ /* Remove the notes that refer to dead registers. As we have at most
+ one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note
+ so we need to purge the complete EQ_USES vector when removing
+ the note using df_notes_rescan. */
+ df_ref *use_rec;
+ bool deleted = false;
+
+ for (use_rec = DF_INSN_EQ_USES (insn); *use_rec; use_rec++)
+ {
+ df_ref use = *use_rec;
+ if (DF_REF_REGNO (use) > FIRST_PSEUDO_REGISTER
+ && DF_REF_LOC (use)
+ && (DF_REF_FLAGS (use) & DF_REF_IN_NOTE)
+ && ! bitmap_bit_p (live, DF_REF_REGNO (use))
+ && loc_mentioned_in_p (DF_REF_LOC (use), XEXP (link, 0)))
+ {
+ deleted = true;
+ break;
+ }
+ }
+ if (deleted)
+ {
+ rtx next;
+ #ifdef REG_DEAD_DEBUGGING
+ df_print_note ("deleting: ", insn, link);
+ #endif
+ next = XEXP (link, 1);
+ free_EXPR_LIST_node (link);
+ *pprev = link = next;
+ df_notes_rescan (insn);
+ }
+ else
+ {
+ pprev = &XEXP (link, 1);
+ link = *pprev;
+ }
+ break;
+ }
default:
pprev = &XEXP (link, 1);
link = *pprev;
debug_insn = DEBUG_INSN_P (insn);
bitmap_clear (do_not_gen);
- df_kill_notes (insn);
+ df_kill_notes (insn, live);
/* Process the defs. */
if (CALL_P (insn))
while (*mws_rec)
{
struct df_mw_hardreg *mws = *mws_rec;
- if ((DF_MWS_REG_DEF_P (mws))
+ if (DF_MWS_REG_USE_P (mws)
&& !df_ignore_stack_reg (mws->start_regno))
{
bool really_add_notes = debug_insn != 0;
{
rtx reg = XEXP (link, 0);
int regno = REGNO (reg);
- if (regno < FIRST_PSEUDO_REGISTER)
- {
- int n = hard_regno_nregs[regno][GET_MODE (reg)];
- while (--n >= 0)
- bitmap_clear_bit (live, regno + n);
- }
+ if (HARD_REGISTER_NUM_P (regno))
+ bitmap_clear_range (live, regno,
+ hard_regno_nregs[regno][GET_MODE (reg)]);
else
bitmap_clear_bit (live, regno);
}
for (insn = across_to; ; insn = next)
{
+ if (CALL_P (insn))
+ {
+ if (RTL_CONST_OR_PURE_CALL_P (insn))
+ /* Pure functions can read from memory. Const functions can
+ read from arguments that the ABI has forced onto the stack.
+ Neither sort of read can be volatile. */
+ memrefs_in_across |= MEMREF_NORMAL;
+ else
+ {
+ memrefs_in_across |= MEMREF_VOLATILE;
+ mem_sets_in_across |= MEMREF_VOLATILE;
+ }
+ }
if (NONDEBUG_INSN_P (insn))
{
memrefs_in_across |= for_each_rtx (&PATTERN (insn), find_memory,
df_simulate_initialize_backwards (merge_bb, test_use);
for (insn = across_to; ; insn = next)
{
+ if (CALL_P (insn))
+ {
+ if (RTL_CONST_OR_PURE_CALL_P (insn))
+ /* Pure functions can read from memory. Const functions can
+ read from arguments that the ABI has forced onto the stack.
+ Neither sort of read can be volatile. */
+ memrefs_in_across |= MEMREF_NORMAL;
+ else
+ {
+ memrefs_in_across |= MEMREF_VOLATILE;
+ mem_sets_in_across |= MEMREF_VOLATILE;
+ }
+ }
if (NONDEBUG_INSN_P (insn))
{
df_simulate_find_defs (insn, test_set);
if (bitmap_intersect_p (merge_set, test_use)
|| bitmap_intersect_p (merge_use, test_set))
break;
- max_to = insn;
+ #ifdef HAVE_cc0
+ if (!sets_cc0_p (insn))
+ #endif
+ max_to = insn;
}
next = NEXT_INSN (insn);
if (insn == to)
{
if (NONDEBUG_INSN_P (insn))
{
- if (!bitmap_intersect_p (test_set, local_merge_live))
+ if (!bitmap_intersect_p (test_set, local_merge_live)
+ #ifdef HAVE_cc0
+ && !sets_cc0_p (insn)
+ #endif
+ )
{
max_to = insn;
break;
/* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
#include "ggc.h"
#include "cfgloop.h"
#include "params.h"
+ #include "tree-pretty-print.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
#define CC_STATUS_INIT
#endif
- /* How to start an assembler comment. */
- #ifndef ASM_COMMENT_START
- #define ASM_COMMENT_START ";#"
- #endif
-
/* Is the given character a logical line separator for the assembler? */
#ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';')
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func | TODO_verify_rtl_sharing
+ TODO_verify_rtl_sharing
| TODO_ggc_collect /* todo_flags_finish */
}
};
if (targetm.profile_before_prologue () && crtl->profile)
profile_function (file);
- #if defined (HAVE_prologue)
- if (dwarf2out_do_frame ())
- dwarf2out_frame_debug (NULL_RTX, false);
- #endif
-
/* If debugging, assign block numbers to all of the blocks in this
function. */
if (write_symbols)
dwarf2out_end_epilogue (last_linenum, last_filename);
}
\f
+
+ /* Dumper helper for basic block information. FILE is the assembly
+ output file, and INSN is the instruction being emitted. */
+
+ static void
+ dump_basic_block_info (FILE *file, rtx insn, basic_block *start_to_bb,
+ basic_block *end_to_bb, int bb_map_size, int *bb_seqn)
+ {
+ basic_block bb;
+
+ if (!flag_debug_asm)
+ return;
+
+ if (INSN_UID (insn) < bb_map_size
+ && (bb = start_to_bb[INSN_UID (insn)]) != NULL)
+ {
+ edge e;
+ edge_iterator ei;
+
+ fprintf (file, "%s BLOCK %d", ASM_COMMENT_START, bb->index);
+ if (bb->frequency)
+ fprintf (file, " freq:%d", bb->frequency);
+ if (bb->count)
+ fprintf (file, " count:" HOST_WIDEST_INT_PRINT_DEC,
+ bb->count);
+ fprintf (file, " seq:%d", (*bb_seqn)++);
+ fprintf (file, "\n%s PRED:", ASM_COMMENT_START);
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ dump_edge_info (file, e, 0);
+ }
+ fprintf (file, "\n");
+ }
+ if (INSN_UID (insn) < bb_map_size
+ && (bb = end_to_bb[INSN_UID (insn)]) != NULL)
+ {
+ edge e;
+ edge_iterator ei;
+
+ fprintf (asm_out_file, "%s SUCC:", ASM_COMMENT_START);
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ dump_edge_info (asm_out_file, e, 1);
+ }
+ fprintf (file, "\n");
+ }
+ }
+
/* Output assembler code for some insns: all or part of a function.
For description of args, see `final_start_function', above. */
void
final (rtx first, FILE *file, int optimize_p)
{
- rtx insn;
+ rtx insn, next;
int max_uid = 0;
int seen = 0;
+ /* Used for -dA dump. */
+ basic_block *start_to_bb = NULL;
+ basic_block *end_to_bb = NULL;
+ int bb_map_size = 0;
+ int bb_seqn = 0;
+
last_ignored_compare = 0;
for (insn = first; insn; insn = NEXT_INSN (insn))
if (optimize_p && JUMP_P (insn))
{
rtx lab = JUMP_LABEL (insn);
- if (lab && LABEL_NUSES (lab) == 1)
+ if (lab && LABEL_P (lab) && LABEL_NUSES (lab) == 1)
{
LABEL_REFS (lab) = insn;
}
CC_STATUS_INIT;
+ if (flag_debug_asm)
+ {
+ basic_block bb;
+
+ bb_map_size = get_max_uid () + 1;
+ start_to_bb = XCNEWVEC (basic_block, bb_map_size);
+ end_to_bb = XCNEWVEC (basic_block, bb_map_size);
+
+ FOR_EACH_BB_REVERSE (bb)
+ {
+ start_to_bb[INSN_UID (BB_HEAD (bb))] = bb;
+ end_to_bb[INSN_UID (BB_END (bb))] = bb;
+ }
+ }
+
/* Output the insns. */
for (insn = first; insn;)
{
insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
#endif /* HAVE_ATTR_length */
+ dump_basic_block_info (file, insn, start_to_bb, end_to_bb,
+ bb_map_size, &bb_seqn);
insn = final_scan_insn (insn, file, optimize_p, 0, &seen);
}
+
+ if (flag_debug_asm)
+ {
+ free (start_to_bb);
+ free (end_to_bb);
+ }
+
+ /* Remove CFI notes, to avoid compare-debug failures. */
+ for (insn = first; insn; insn = next)
+ {
+ next = NEXT_INSN (insn);
+ if (NOTE_P (insn)
+ && (NOTE_KIND (insn) == NOTE_INSN_CFI
+ || NOTE_KIND (insn) == NOTE_INSN_CFI_LABEL))
+ delete_insn (insn);
+ }
}
\f
const char *
if (targetm.asm_out.unwind_emit)
targetm.asm_out.unwind_emit (asm_out_file, insn);
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t%s basic block %d\n",
- ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index);
-
if ((*seen & (SEEN_EMITTED | SEEN_BB)) == SEEN_BB)
{
*seen |= SEEN_EMITTED;
break;
case NOTE_INSN_EPILOGUE_BEG:
- #if defined (HAVE_epilogue)
- if (dwarf2out_do_frame ())
- dwarf2out_cfi_begin_epilogue (insn);
- #endif
- (*debug_hooks->begin_epilogue) (last_linenum, last_filename);
+ if (!DECL_IGNORED_P (current_function_decl))
+ (*debug_hooks->begin_epilogue) (last_linenum, last_filename);
targetm.asm_out.function_begin_epilogue (file);
break;
- case NOTE_INSN_CFA_RESTORE_STATE:
- dwarf2out_frame_debug_restore_state ();
+ case NOTE_INSN_CFI:
+ dwarf2out_emit_cfi (NOTE_CFI (insn));
+ break;
+
+ case NOTE_INSN_CFI_LABEL:
+ ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LCFI",
+ NOTE_LABEL_NUMBER (insn));
break;
case NOTE_INSN_FUNCTION_BEG:
ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
break;
+ case NOTE_INSN_DELETED_DEBUG_LABEL:
+ /* Similarly, but need to use different namespace for it. */
+ if (CODE_LABEL_NUMBER (insn) != -1)
+ ASM_OUTPUT_DEBUG_LABEL (file, "LDL", CODE_LABEL_NUMBER (insn));
+ break;
+
case NOTE_INSN_VAR_LOCATION:
+ case NOTE_INSN_CALL_ARG_LOCATION:
if (!DECL_IGNORED_P (current_function_decl))
debug_hooks->var_location (insn);
break;
break;
case BARRIER:
- if (dwarf2out_do_frame ())
- dwarf2out_frame_debug (insn, false);
break;
case CODE_LABEL:
location_t loc;
expanded_location expanded;
+ /* Make sure we flush any queued register saves in case this
+ clobbers affected registers. */
+ if (dwarf2out_do_frame ())
+ dwarf2out_frame_debug (insn, false);
+
/* There's no telling what that did to the condition codes. */
CC_STATUS_INIT;
final_sequence = body;
- /* Record the delay slots' frame information before the branch.
- This is needed for delayed calls: see execute_cfa_program(). */
- if (dwarf2out_do_frame ())
- for (i = 1; i < XVECLEN (body, 0); i++)
- dwarf2out_frame_debug (XVECEXP (body, 0, i), false);
-
/* The first insn in this SEQUENCE might be a JUMP_INSN that will
force the restoration of a comparison that was previously
thought unnecessary. If that happens, cancel this sequence
delete_insn (insn);
break;
}
- else if (GET_CODE (SET_SRC (body)) == RETURN)
+ else if (ANY_RETURN_P (SET_SRC (body)))
/* Replace (set (pc) (return)) with (return). */
PATTERN (insn) = body = SET_SRC (body);
current_output_insn = debug_insn = insn;
- if (CALL_P (insn) && dwarf2out_do_frame ())
- dwarf2out_frame_debug (insn, false);
-
/* Find the proper template for this insn. */
templ = get_insn_template (insn_code_number, insn);
if (t)
assemble_external (t);
}
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->var_location (insn);
}
/* Output assembler code from the template. */
output_asm_insn (templ, recog_data.operand);
- /* Record point-of-call information for ICF debugging. */
- if (flag_enable_icf_debug && CALL_P (insn))
- {
- rtx x = call_from_call_insn (insn);
- x = XEXP (x, 0);
- if (x && MEM_P (x))
- {
- if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
- {
- tree t;
- x = XEXP (x, 0);
- t = SYMBOL_REF_DECL (x);
- if (t)
- (*debug_hooks->direct_call) (t);
- }
- else
- (*debug_hooks->virtual_call) (INSN_UID (insn));
- }
- }
-
/* Some target machines need to postscan each insn after
it is output. */
if (targetm.asm_out.final_postscan_insn)
targetm.asm_out.final_postscan_insn (file, insn, recog_data.operand,
recog_data.n_operands);
- /* If necessary, report the effect that the instruction has on
- the unwind info. We've already done this for delay slots
- and call instructions. */
- if (final_sequence == 0
- #if !defined (HAVE_prologue)
- && !ACCUMULATE_OUTGOING_ARGS
- #endif
- && dwarf2out_do_frame ())
- dwarf2out_frame_debug (insn, true);
-
if (!targetm.asm_out.unwind_emit_before_insn
&& targetm.asm_out.unwind_emit)
targetm.asm_out.unwind_emit (asm_out_file, insn);
break;
case CONST_FIXED:
- fprintf (file, HOST_WIDE_INT_PRINT_HEX,
- (unsigned HOST_WIDE_INT) CONST_FIXED_VALUE_LOW (x));
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x));
break;
case PLUS:
#endif
}
\f
+ /* Write a HOST_WIDE_INT number in hex form 0x1234, fast. */
+
+ void
+ fprint_whex (FILE *f, unsigned HOST_WIDE_INT value)
+ {
+ char buf[2 + CHAR_BIT * sizeof (value) / 4];
+ if (value == 0)
+ putc ('0', f);
+ else
+ {
+ char *p = buf + sizeof (buf);
+ do
+ *--p = "0123456789abcdef"[value % 16];
+ while ((value /= 16) != 0);
+ *--p = 'x';
+ *--p = '0';
+ fwrite (p, 1, buf + sizeof (buf) - p, f);
+ }
+ }
+
+ /* Internal function that prints an unsigned long in decimal in reverse.
+ The output string IS NOT null-terminated. */
+
+ static int
+ sprint_ul_rev (char *s, unsigned long value)
+ {
+ int i = 0;
+ do
+ {
+ s[i] = "0123456789"[value % 10];
+ value /= 10;
+ i++;
+ /* alternate version, without modulo */
+ /* oldval = value; */
+ /* value /= 10; */
+ /* s[i] = "0123456789" [oldval - 10*value]; */
+ /* i++ */
+ }
+ while (value != 0);
+ return i;
+ }
+
+ /* Write an unsigned long as decimal to a file, fast. */
+
+ void
+ fprint_ul (FILE *f, unsigned long value)
+ {
+ /* python says: len(str(2**64)) == 20 */
+ char s[20];
+ int i;
+
+ i = sprint_ul_rev (s, value);
+
+ /* It's probably too small to bother with string reversal and fputs. */
+ do
+ {
+ i--;
+ putc (s[i], f);
+ }
+ while (i != 0);
+ }
+
+ /* Write an unsigned long as decimal to a string, fast.
+ s must be wide enough to not overflow, at least 21 chars.
+ Returns the length of the string (without terminating '\0'). */
+
+ int
+ sprint_ul (char *s, unsigned long value)
+ {
+ int len;
+ char tmp_c;
+ int i;
+ int j;
+
+ len = sprint_ul_rev (s, value);
+ s[len] = '\0';
+
+ /* Reverse the string. */
+ i = 0;
+ j = len - 1;
+ while (i < j)
+ {
+ tmp_c = s[i];
+ s[i] = s[j];
+ s[j] = tmp_c;
+ i++; j--;
+ }
+
+ return len;
+ }
+
/* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
%R prints the value of REGISTER_PREFIX.
%L prints the value of LOCAL_LABEL_PREFIX.
}
}
#endif
-
-
- /* When -gused is used, emit debug info for only used symbols. But in
- addition to the standard intercepted debug_hooks there are some direct
- calls into this file, i.e., dbxout_symbol, dbxout_parms, and dbxout_reg_params.
- Those routines may also be called from a higher level intercepted routine. So
- to prevent recording data for an inner call to one of these for an intercept,
- we maintain an intercept nesting counter (debug_nesting). We only save the
- intercepted arguments if the nesting is 1. */
- int debug_nesting = 0;
-
- static tree *symbol_queue;
- int symbol_queue_index = 0;
- static int symbol_queue_size = 0;
-
- /* Generate the symbols for any queued up type symbols we encountered
- while generating the type info for some originally used symbol.
- This might generate additional entries in the queue. Only when
- the nesting depth goes to 0 is this routine called. */
-
- void
- debug_flush_symbol_queue (void)
- {
- int i;
-
- /* Make sure that additionally queued items are not flushed
- prematurely. */
-
- ++debug_nesting;
-
- for (i = 0; i < symbol_queue_index; ++i)
- {
- /* If we pushed queued symbols then such symbols must be
- output no matter what anyone else says. Specifically,
- we need to make sure dbxout_symbol() thinks the symbol was
- used and also we need to override TYPE_DECL_SUPPRESS_DEBUG
- which may be set for outside reasons. */
- int saved_tree_used = TREE_USED (symbol_queue[i]);
- int saved_suppress_debug = TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]);
- TREE_USED (symbol_queue[i]) = 1;
- TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = 0;
-
- #ifdef DBX_DEBUGGING_INFO
- dbxout_symbol (symbol_queue[i], 0);
- #endif
-
- TREE_USED (symbol_queue[i]) = saved_tree_used;
- TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = saved_suppress_debug;
- }
-
- symbol_queue_index = 0;
- --debug_nesting;
- }
-
- /* Queue a type symbol needed as part of the definition of a decl
- symbol. These symbols are generated when debug_flush_symbol_queue()
- is called. */
-
- void
- debug_queue_symbol (tree decl)
- {
- if (symbol_queue_index >= symbol_queue_size)
- {
- symbol_queue_size += 10;
- symbol_queue = XRESIZEVEC (tree, symbol_queue, symbol_queue_size);
- }
-
- symbol_queue[symbol_queue_index++] = decl;
- }
-
- /* Free symbol queue. */
- void
- debug_free_queue (void)
- {
- if (symbol_queue)
- {
- free (symbol_queue);
- symbol_queue = NULL;
- symbol_queue_size = 0;
- }
- }
\f
/* Turn the RTL into assembly. */
static unsigned int
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func /* todo_flags_finish */
+ 0 /* todo_flags_finish */
}
};
}
else
{
- const char *aname;
- struct cgraph_node *node = cgraph_node (current_function_decl);
-
- aname = (IDENTIFIER_POINTER
- (DECL_ASSEMBLER_NAME (current_function_decl)));
- fprintf (final_output, "\n;; Function (%s) %s\n\n", aname,
- node->frequency == NODE_FREQUENCY_HOT
- ? " (hot)"
- : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
- ? " (unlikely executed)"
- : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
- ? " (executed once)"
- : "");
-
flag_dump_noaddr = flag_dump_unnumbered = 1;
if (flag_compare_debug_opt || flag_compare_debug)
dump_flags |= TDF_NOUID;
+ dump_function_header (final_output, current_function_decl,
+ dump_flags);
final_insns_dump_p = true;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (final_output
&& (!NOTE_P (insn) ||
(NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION
+ && NOTE_KIND (insn) != NOTE_INSN_CALL_ARG_LOCATION
&& NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG
&& NOTE_KIND (insn) != NOTE_INSN_BLOCK_END
- && NOTE_KIND (insn) != NOTE_INSN_CFA_RESTORE_STATE)))
+ && NOTE_KIND (insn) != NOTE_INSN_DELETED_DEBUG_LABEL)))
print_rtl_single (final_output, insn);
}
/* Branch prediction routines for the GNU compiler.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ 2011, 2012, 2013 Free Software Foundation, Inc.
This file is part of GCC.
static inline bool
maybe_hot_frequency_p (int freq)
{
- struct cgraph_node *node = cgraph_node (current_function_decl);
+ struct cgraph_node *node = cgraph_get_node (current_function_decl);
if (!profile_info || !flag_branch_probabilities)
{
if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
if (profile_status == PROFILE_ABSENT)
return true;
if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
- && freq <= (ENTRY_BLOCK_PTR->frequency * 2 / 3))
+ && freq < (ENTRY_BLOCK_PTR->frequency * 2 / 3))
return false;
if (freq < ENTRY_BLOCK_PTR->frequency / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))
return false;
return maybe_hot_frequency_p (EDGE_FREQUENCY (e));
}
+
/* Return true in case BB is probably never executed. */
+
bool
probably_never_executed_bb_p (const_basic_block bb)
{
if (profile_info && flag_branch_probabilities)
return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0;
if ((!profile_info || !flag_branch_probabilities)
- && cgraph_node (current_function_decl)->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
+ && (cgraph_get_node (current_function_decl)->frequency
+ == NODE_FREQUENCY_UNLIKELY_EXECUTED))
return true;
return false;
}
+ /* Return true if NODE should be optimized for size. */
+
+ bool
+ cgraph_optimize_for_size_p (struct cgraph_node *node)
+ {
+ if (optimize_size)
+ return true;
+ if (node && (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
+ return true;
+ else
+ return false;
+ }
+
/* Return true when current function should always be optimized for size. */
bool
optimize_function_for_size_p (struct function *fun)
{
- return (optimize_size
- || (fun && fun->decl
- && (cgraph_node (fun->decl)->frequency
- == NODE_FREQUENCY_UNLIKELY_EXECUTED)));
+ if (optimize_size)
+ return true;
+ if (!fun || !fun->decl)
+ return false;
+ return cgraph_optimize_for_size_p (cgraph_get_node (fun->decl));
}
/* Return true when current function should always be optimized for speed. */
the loop, use it to predict this exit. */
else if (n_exits == 1)
{
- nitercst = estimated_loop_iterations_int (loop, false);
+ nitercst = max_stmt_executions_int (loop, false);
if (nitercst < 0)
continue;
if (nitercst > max)
/* Helper function for expr_expected_value. */
static tree
- expr_expected_value_1 (tree type, tree op0, enum tree_code code, tree op1, bitmap visited)
+ expr_expected_value_1 (tree type, tree op0, enum tree_code code,
+ tree op1, bitmap visited)
{
gimple def;
tree decl = gimple_call_fndecl (def);
if (!decl)
return NULL;
- if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl) == BUILT_IN_EXPECT)
- {
- tree val;
+ if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (decl))
+ {
+ case BUILT_IN_EXPECT:
+ {
+ tree val;
+ if (gimple_call_num_args (def) != 2)
+ return NULL;
+ val = gimple_call_arg (def, 0);
+ if (TREE_CONSTANT (val))
+ return val;
+ return gimple_call_arg (def, 1);
+ }
- if (gimple_call_num_args (def) != 2)
- return NULL;
- val = gimple_call_arg (def, 0);
- if (TREE_CONSTANT (val))
- return val;
- return gimple_call_arg (def, 1);
+ case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N:
+ case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
+ case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
+ case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
+ case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
+ case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
+ /* Assume that any given atomic operation has low contention,
+ and thus the compare-and-swap operation succeeds. */
+ return boolean_true_node;
}
}
compute_function_frequency (void)
{
basic_block bb;
- struct cgraph_node *node = cgraph_node (current_function_decl);
+ struct cgraph_node *node = cgraph_get_node (current_function_decl);
if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
|| MAIN_NAME_P (DECL_NAME (current_function_decl)))
node->only_called_at_startup = true;
build_predict_expr (enum br_predictor predictor, enum prediction taken)
{
tree t = build1 (PREDICT_EXPR, void_type_node,
- build_int_cst (NULL, predictor));
+ build_int_cst (integer_type_node, predictor));
SET_PREDICT_EXPR_OUTCOME (t, taken);
return t;
}
{
{
GIMPLE_PASS,
- "profile", /* name */
+ "profile_estimate", /* name */
gate_estimate_probability, /* gate */
tree_estimate_probability_driver, /* execute */
NULL, /* sub */
+2013-04-12 Release Manager
+
+ * GCC 4.6.4 released.
+
+2012-03-01 Release Manager
+
+ * GCC 4.6.3 released.
+
+2011-10-26 Release Manager
+
+ * GCC 4.6.2 released.
+
+2011-06-27 Release Manager
+
+ * GCC 4.6.1 released.
+
+2011-03-25 Release Manager
+
+ * GCC 4.6.0 released.
+
2005-04-03 Alexandre Oliva <aoliva@redhat.com>
PR c++/19199
+++ /dev/null
--/* { dg-options "-g" } */
--
--extern int a;
--extern char b;
--extern int foo (void);
--
--void
--test (void)
--{
-- int c;
-- b = foo () ? '~' : '\0';
-- while ((c = foo ()))
-- if (c == '7')
-- a = 0;
--}
+++ /dev/null
--void bar (unsigned char *q, unsigned short *data16s, int len)
--{
-- int i;
--
-- for (i = 0; i < len; i++)
-- {
-- q[2 * i] =
-- (((data16s[i] & 0xFF) << 8) | ((data16s[i] >> 8) & 0xFF)) & 0xFF;
-- q[2 * i + 1] =
-- ((unsigned short)
-- (((data16s[i] & 0xFF) << 8) | ((data16s[i] >> 8) & 0xFF))) >> 8;
-- }
--}
procedure(logical),pointer :: pp1
procedure(complex),pointer :: pp2
- pp1 => pp2 ! { dg-error "Type/kind mismatch" }
- pp2 => o2%ppc ! { dg-error "Type/kind mismatch" }
+ pp1 => pp2 ! { dg-error "Type/rank mismatch" }
+ pp2 => o2%ppc ! { dg-error "Type/rank mismatch" }
- o1%ppc => pp1 ! { dg-error "Type/kind mismatch" }
- o1%ppc => o2%ppc ! { dg-error "Type/kind mismatch" }
+ o1%ppc => pp1 ! { dg-error "Type/rank mismatch" }
+ o1%ppc => o2%ppc ! { dg-error "Type/rank mismatch" }
contains
- real function f1(a,b)
+ real function f1(a,b) ! { dg-warning "Extension: Internal procedure" }
real,intent(in) :: a,b
f1 = a + b
end function
- integer function f2(a,b)
+ integer function f2(a,b) ! { dg-warning "Extension: Internal procedure" }
real,intent(in) :: a,b
f2 = a - b
end function
- # Copyright (C) 1997, 1999, 2000, 2002, 2004, 2007, 2008, 2010
+ # Copyright (C) 1997, 1999, 2000, 2002, 2004, 2007, 2008, 2010, 2011
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
proc prune_gcc_output { text } {
#send_user "Before:$text\n"
- regsub -all "(^|\n)(\[^\n\]*: )?In ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|program|subroutine|block-data)\[^\n\]*" $text "" text
+ regsub -all "(^|\n)(\[^\n\]*: )?In ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|substitution|program|subroutine|block-data)\[^\n\]*" $text "" text
regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text
- regsub -all "(^|\n)\[^\n\]*: (recursively )?instantiated from \[^\n\]*" $text "" text
+ regsub -all "(^|\n)\[^\n\]*: (recursively )?required \[^\n\]*" $text "" text
regsub -all "(^|\n)\[^\n\]*: . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text
regsub -all "(^|\n) inlined from \[^\n\]*" $text "" text
- regsub -all "(^|\n)collect2: ld returned \[^\n\]*" $text "" text
+ regsub -all "(^|\n)collect2: error: ld returned \[^\n\]*" $text "" text
regsub -all "(^|\n)collect: re(compiling|linking)\[^\n\]*" $text "" text
regsub -all "(^|\n)Please submit.*instructions\[^\n\]*" $text "" text
regsub -all "(^|\n)\[0-9\]\[0-9\]* errors\." $text "" text
+ regsub -all "(^|\n)(In file included|\[ \]+from)\[^\n\]*" $text "" text
+
+ # Ignore informational notes.
+ regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text
+ # Ignore informational notes.
+ regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text
+
# Ignore harmless -fpic warnings.
regsub -all "(^|\n)\[^\n\]*: warning: -f(pic|PIC) ignored for target\[^\n\]*" $text "" text
regsub -all "(^|\n)\[^\n\]*: warning: -f(pic|PIC)( and -fpic are| is)? not supported\[^\n\]*" $text "" text
regsub -all "(^|\n)\[^\n\]*ld: warning: can't add line info to anonymous symbol\[^\n\]*" $text "" text
regsub -all "(^|\n)\[^\n\]*warning: DWARFDebugInfoEntry::AppendDependants\[^\n\]*AT_\[^\n\]*_bound\[^\n\]*FORM_ref4\[^\n\]*" $text "" text
regsub -all "(^|\n)\[^\n\]*warning:\[^\n\]*TAG_variable: AT_location\[^\n\]*didn't have valid function low pc\[^\n\]*" $text "" text
-
+
+ # Ignore harmless warnings from Xcode 4.0.
+ regsub -all "(^|\n)\[^\n\]*ld: warning: could not create compact unwind for\[^\n\]*" $text "" text
+
#send_user "After:$text\n"
return $text
/* Misc functions used in this file. */
- /* Compare and hash for any structure which begins with a canonical
- pointer. Assumes all pointers are interchangeable, which is sort
- of already assumed by gcc elsewhere IIRC. */
-
- static int
- struct_ptr_eq (const void *a, const void *b)
- {
- const void * const * x = (const void * const *) a;
- const void * const * y = (const void * const *) b;
- return *x == *y;
- }
-
- static hashval_t
- struct_ptr_hash (const void *a)
- {
- const void * const * x = (const void * const *) a;
- return (size_t)*x >> 4;
- }
-
-
/* Remember and lookup EH landing pad data for arbitrary statements.
Really this means any statement that could_throw_p. We could
stuff this information into the stmt_ann data structure, but:
collect_finally_tree_1 (gimple_eh_filter_failure (stmt), region);
break;
+ case GIMPLE_EH_ELSE:
+ collect_finally_tree_1 (gimple_eh_else_n_body (stmt), region);
+ collect_finally_tree_1 (gimple_eh_else_e_body (stmt), region);
+ break;
+
default:
/* A type, a decl, or some kind of statement that we're not
interested in. Don't walk them. */
case GIMPLE_EH_FILTER:
replace_goto_queue_stmt_list (gimple_eh_filter_failure (stmt), tf);
break;
+ case GIMPLE_EH_ELSE:
+ replace_goto_queue_stmt_list (gimple_eh_else_n_body (stmt), tf);
+ replace_goto_queue_stmt_list (gimple_eh_else_e_body (stmt), tf);
+ break;
default:
/* These won't have gotos in them. */
#define verify_norecord_switch_expr(state, switch_expr)
#endif
- /* Redirect a RETURN_EXPR pointed to by STMT_P to FINLAB. Place in CONT_P
- whatever is needed to finish the return. If MOD is non-null, insert it
- before the new branch. RETURN_VALUE_P is a cache containing a temporary
- variable to be used in manipulating the value returned from the function. */
+ /* Redirect a RETURN_EXPR pointed to by Q to FINLAB. If MOD is
+ non-null, insert it before the new branch. */
static void
- do_return_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod,
- tree *return_value_p)
+ do_return_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod)
{
- tree ret_expr;
gimple x;
- /* In the case of a return, the queue node must be a gimple statement. */
+ /* In the case of a return, the queue node must be a gimple statement. */
gcc_assert (!q->is_label);
- ret_expr = gimple_return_retval (q->stmt.g);
+ /* Note that the return value may have already been computed, e.g.,
- if (ret_expr)
- {
- if (!*return_value_p)
- *return_value_p = ret_expr;
- else
- gcc_assert (*return_value_p == ret_expr);
- q->cont_stmt = q->stmt.g;
- /* The nasty part about redirecting the return value is that the
- return value itself is to be computed before the FINALLY block
- is executed. e.g.
-
- int x;
- int foo (void)
- {
- x = 0;
- try {
- return x;
- } finally {
- x++;
- }
- }
-
- should return 0, not 1. Arrange for this to happen by copying
- computed the return value into a local temporary. This also
- allows us to redirect multiple return statements through the
- same destination block; whether this is a net win or not really
- depends, I guess, but it does make generation of the switch in
- lower_try_finally_switch easier. */
-
- if (TREE_CODE (ret_expr) == RESULT_DECL)
+ int x;
+ int foo (void)
{
- if (!*return_value_p)
- *return_value_p = ret_expr;
- else
- gcc_assert (*return_value_p == ret_expr);
- q->cont_stmt = q->stmt.g;
+ x = 0;
+ try {
+ return x;
+ } finally {
+ x++;
+ }
}
- else
- gcc_unreachable ();
- }
- else
- /* If we don't return a value, all return statements are the same. */
- q->cont_stmt = q->stmt.g;
+
+ should return 0, not 1. We don't have to do anything to make
+ this happens because the return value has been placed in the
+ RESULT_DECL already. */
+
+ q->cont_stmt = q->stmt.g;
if (!q->repl_stmt)
q->repl_stmt = gimple_seq_alloc ();
return label;
}
+ /* A subroutine of lower_try_finally. If FINALLY consits of a
+ GIMPLE_EH_ELSE node, return it. */
+
+ static inline gimple
+ get_eh_else (gimple_seq finally)
+ {
+ gimple x = gimple_seq_first_stmt (finally);
+ if (gimple_code (x) == GIMPLE_EH_ELSE)
+ {
+ gcc_assert (gimple_seq_singleton_p (finally));
+ return x;
+ }
+ return NULL;
+ }
+
/* A subroutine of lower_try_finally. If the eh_protect_cleanup_actions
langhook returns non-null, then the language requires that the exception
path out of a try_finally be treated specially. To wit: the code within
gimple_stmt_iterator gsi;
bool finally_may_fallthru;
gimple_seq finally;
- gimple x;
+ gimple x, eh_else;
/* First check for nothing to do. */
if (lang_hooks.eh_protect_cleanup_actions == NULL)
return;
finally = gimple_try_cleanup (tf->top_p);
- finally_may_fallthru = gimple_seq_may_fallthru (finally);
+ eh_else = get_eh_else (finally);
/* Duplicate the FINALLY block. Only need to do this for try-finally,
- and not for cleanups. */
- if (this_state)
+ and not for cleanups. If we've got an EH_ELSE, extract it now. */
+ if (eh_else)
+ {
+ finally = gimple_eh_else_e_body (eh_else);
+ gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
+ }
+ else if (this_state)
finally = lower_try_finally_dup_block (finally, outer_state);
+ finally_may_fallthru = gimple_seq_may_fallthru (finally);
/* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
set, the handler of the TRY_CATCH_EXPR is another cleanup which ought
lower_try_finally_nofallthru (struct leh_state *state,
struct leh_tf_state *tf)
{
- tree lab, return_val;
- gimple x;
+ tree lab;
+ gimple x, eh_else;
gimple_seq finally;
struct goto_queue_node *q, *qe;
x = gimple_build_label (lab);
gimple_seq_add_stmt (&tf->top_p_seq, x);
- return_val = NULL;
q = tf->goto_queue;
qe = q + tf->goto_queue_active;
for (; q < qe; ++q)
if (q->index < 0)
- do_return_redirection (q, lab, NULL, &return_val);
+ do_return_redirection (q, lab, NULL);
else
do_goto_redirection (q, lab, NULL, tf);
replace_goto_queue (tf);
- lower_eh_constructs_1 (state, finally);
- gimple_seq_add_seq (&tf->top_p_seq, finally);
+ /* Emit the finally block into the stream. Lower EH_ELSE at this time. */
+ eh_else = get_eh_else (finally);
+ if (eh_else)
+ {
+ finally = gimple_eh_else_n_body (eh_else);
+ lower_eh_constructs_1 (state, finally);
+ gimple_seq_add_seq (&tf->top_p_seq, finally);
- if (tf->may_throw)
+ if (tf->may_throw)
+ {
+ finally = gimple_eh_else_e_body (eh_else);
+ lower_eh_constructs_1 (state, finally);
+
+ emit_post_landing_pad (&eh_seq, tf->region);
+ gimple_seq_add_seq (&eh_seq, finally);
+ }
+ }
+ else
{
- emit_post_landing_pad (&eh_seq, tf->region);
+ lower_eh_constructs_1 (state, finally);
+ gimple_seq_add_seq (&tf->top_p_seq, finally);
- x = gimple_build_goto (lab);
- gimple_seq_add_stmt (&eh_seq, x);
+ if (tf->may_throw)
+ {
+ emit_post_landing_pad (&eh_seq, tf->region);
+
+ x = gimple_build_goto (lab);
+ gimple_seq_add_stmt (&eh_seq, x);
+ }
}
}
finally = gimple_try_cleanup (tf->top_p);
tf->top_p_seq = gimple_try_eval (tf->top_p);
+ /* Since there's only one destination, and the destination edge can only
+ either be EH or non-EH, that implies that all of our incoming edges
+ are of the same type. Therefore we can lower EH_ELSE immediately. */
+ x = get_eh_else (finally);
+ if (x)
+ {
+ if (tf->may_throw)
+ finally = gimple_eh_else_e_body (x);
+ else
+ finally = gimple_eh_else_n_body (x);
+ }
+
lower_eh_constructs_1 (state, finally);
if (tf->may_throw)
if (tf->may_return)
{
/* Reachable by return expressions only. Redirect them. */
- tree return_val = NULL;
for (; q < qe; ++q)
- do_return_redirection (q, finally_label, NULL, &return_val);
+ do_return_redirection (q, finally_label, NULL);
replace_goto_queue (tf);
}
else
gimple_seq finally;
gimple_seq new_stmt;
gimple_seq seq;
- gimple x;
+ gimple x, eh_else;
tree tmp;
location_t tf_loc = gimple_location (tf->try_finally_expr);
finally = gimple_try_cleanup (tf->top_p);
+
+ /* Notice EH_ELSE, and simplify some of the remaining code
+ by considering FINALLY to be the normal return path only. */
+ eh_else = get_eh_else (finally);
+ if (eh_else)
+ finally = gimple_eh_else_n_body (eh_else);
+
tf->top_p_seq = gimple_try_eval (tf->top_p);
new_stmt = NULL;
if (tf->may_throw)
{
- seq = lower_try_finally_dup_block (finally, state);
+ /* We don't need to copy the EH path of EH_ELSE,
+ since it is only emitted once. */
+ if (eh_else)
+ seq = gimple_eh_else_e_body (eh_else);
+ else
+ seq = lower_try_finally_dup_block (finally, state);
lower_eh_constructs_1 (state, seq);
emit_post_landing_pad (&eh_seq, tf->region);
if (tf->goto_queue)
{
struct goto_queue_node *q, *qe;
- tree return_val = NULL;
int return_index, index;
struct labels_s
{
= create_artificial_label (tf_loc);
if (index == return_index)
- do_return_redirection (q, lab, NULL, &return_val);
+ do_return_redirection (q, lab, NULL);
else
do_goto_redirection (q, lab, NULL, tf);
lab = labels[index].label;
if (index == return_index)
- do_return_redirection (q, lab, NULL, &return_val);
+ do_return_redirection (q, lab, NULL);
else
do_goto_redirection (q, lab, NULL, tf);
}
lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
{
struct goto_queue_node *q, *qe;
- tree return_val = NULL;
tree finally_tmp, finally_label;
int return_index, eh_index, fallthru_index;
int nlabels, ndests, j, last_case_index;
tree last_case;
VEC (tree,heap) *case_label_vec;
gimple_seq switch_body;
- gimple x;
+ gimple x, eh_else;
tree tmp;
gimple switch_stmt;
gimple_seq finally;
location_t finally_loc;
switch_body = gimple_seq_alloc ();
+ finally = gimple_try_cleanup (tf->top_p);
+ eh_else = get_eh_else (finally);
/* Mash the TRY block to the head of the chain. */
- finally = gimple_try_cleanup (tf->top_p);
tf->top_p_seq = gimple_try_eval (tf->top_p);
/* The location of the finally is either the last stmt in the finally
block or the location of the TRY_FINALLY itself. */
- finally_loc = gimple_seq_last_stmt (tf->top_p_seq) != NULL ?
- gimple_location (gimple_seq_last_stmt (tf->top_p_seq))
- : tf_loc;
-
- /* Lower the finally block itself. */
- lower_eh_constructs_1 (state, finally);
+ x = gimple_seq_last_stmt (finally);
+ finally_loc = x ? gimple_location (x) : tf_loc;
/* Prepare for switch statement generation. */
nlabels = VEC_length (tree, tf->dest_array);
return_index = nlabels;
eh_index = return_index + tf->may_return;
- fallthru_index = eh_index + tf->may_throw;
+ fallthru_index = eh_index + (tf->may_throw && !eh_else);
ndests = fallthru_index + tf->may_fallthru;
finally_tmp = create_tmp_var (integer_type_node, "finally_tmp");
if (tf->may_fallthru)
{
x = gimple_build_assign (finally_tmp,
- build_int_cst (NULL, fallthru_index));
+ build_int_cst (integer_type_node,
+ fallthru_index));
gimple_seq_add_stmt (&tf->top_p_seq, x);
- last_case = build3 (CASE_LABEL_EXPR, void_type_node,
- build_int_cst (NULL, fallthru_index),
- NULL, create_artificial_label (tf_loc));
+ tmp = build_int_cst (integer_type_node, fallthru_index);
+ last_case = build_case_label (tmp, NULL,
+ create_artificial_label (tf_loc));
VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
gimple_seq_add_stmt (&switch_body, x);
}
- if (tf->may_throw)
+ /* For EH_ELSE, emit the exception path (plus resx) now, then
+ subsequently we only need consider the normal path. */
+ if (eh_else)
+ {
+ if (tf->may_throw)
+ {
+ finally = gimple_eh_else_e_body (eh_else);
+ lower_eh_constructs_1 (state, finally);
+
+ emit_post_landing_pad (&eh_seq, tf->region);
+ gimple_seq_add_seq (&eh_seq, finally);
+ emit_resx (&eh_seq, tf->region);
+ }
+
+ finally = gimple_eh_else_n_body (eh_else);
+ }
+ else if (tf->may_throw)
{
emit_post_landing_pad (&eh_seq, tf->region);
x = gimple_build_assign (finally_tmp,
- build_int_cst (NULL, eh_index));
+ build_int_cst (integer_type_node, eh_index));
gimple_seq_add_stmt (&eh_seq, x);
x = gimple_build_goto (finally_label);
gimple_seq_add_stmt (&eh_seq, x);
- last_case = build3 (CASE_LABEL_EXPR, void_type_node,
- build_int_cst (NULL, eh_index),
- NULL, create_artificial_label (tf_loc));
+ tmp = build_int_cst (integer_type_node, eh_index);
+ last_case = build_case_label (tmp, NULL,
+ create_artificial_label (tf_loc));
VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
x = gimple_build_label (finally_label);
gimple_seq_add_stmt (&tf->top_p_seq, x);
+ lower_eh_constructs_1 (state, finally);
gimple_seq_add_seq (&tf->top_p_seq, finally);
/* Redirect each incoming goto edge. */
if (q->index < 0)
{
x = gimple_build_assign (finally_tmp,
- build_int_cst (NULL, return_index));
+ build_int_cst (integer_type_node,
+ return_index));
gimple_seq_add_stmt (&mod, x);
- do_return_redirection (q, finally_label, mod, &return_val);
+ do_return_redirection (q, finally_label, mod);
switch_id = return_index;
}
else
{
x = gimple_build_assign (finally_tmp,
- build_int_cst (NULL, q->index));
+ build_int_cst (integer_type_node, q->index));
gimple_seq_add_stmt (&mod, x);
do_goto_redirection (q, finally_label, mod, tf);
switch_id = q->index;
{
tree case_lab;
void **slot;
- case_lab = build3 (CASE_LABEL_EXPR, void_type_node,
- build_int_cst (NULL, switch_id),
- NULL, NULL);
+ tmp = build_int_cst (integer_type_node, switch_id);
+ case_lab = build_case_label (tmp, NULL,
+ create_artificial_label (tf_loc));
/* We store the cont_stmt in the pointer map, so that we can recover
- it in the loop below. We don't create the new label while
- walking the goto_queue because pointers don't offer a stable
- order. */
+ it in the loop below. */
if (!cont_map)
cont_map = pointer_map_create ();
slot = pointer_map_insert (cont_map, case_lab);
}
for (j = last_case_index; j < last_case_index + nlabels; j++)
{
- tree label;
gimple cont_stmt;
void **slot;
gcc_assert (cont_map);
slot = pointer_map_contains (cont_map, last_case);
- /* As the comment above suggests, CASE_LABEL (last_case) was just a
- placeholder, it does not store an actual label, yet. */
gcc_assert (slot);
cont_stmt = *(gimple *) slot;
- label = create_artificial_label (tf_loc);
- CASE_LABEL (last_case) = label;
-
- x = gimple_build_label (label);
+ x = gimple_build_label (CASE_LABEL (last_case));
gimple_seq_add_stmt (&switch_body, x);
gimple_seq_add_stmt (&switch_body, cont_stmt);
maybe_record_in_goto_queue (state, cont_stmt);
the estimate of the size of the switch machinery we'd have to add. */
static bool
- decide_copy_try_finally (int ndests, gimple_seq finally)
+ decide_copy_try_finally (int ndests, bool may_throw, gimple_seq finally)
{
int f_estimate, sw_estimate;
+ gimple eh_else;
+
+ /* If there's an EH_ELSE involved, the exception path is separate
+ and really doesn't come into play for this computation. */
+ eh_else = get_eh_else (finally);
+ if (eh_else)
+ {
+ ndests -= may_throw;
+ finally = gimple_eh_else_n_body (eh_else);
+ }
if (!optimize)
- return false;
+ {
+ gimple_stmt_iterator gsi;
+
+ if (ndests == 1)
+ return true;
+
+ for (gsi = gsi_start (finally); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (!is_gimple_debug (stmt) && !gimple_clobber_p (stmt))
+ return false;
+ }
+ return true;
+ }
/* Finally estimate N times, plus N gotos. */
f_estimate = count_insns_seq (finally, &eni_size_weights);
/* We can easily special-case redirection to a single destination. */
else if (ndests == 1)
lower_try_finally_onedest (state, &this_tf);
- else if (decide_copy_try_finally (ndests, gimple_try_cleanup (tp)))
+ else if (decide_copy_try_finally (ndests, this_tf.may_throw,
+ gimple_try_cleanup (tp)))
lower_try_finally_copy (state, &this_tf);
else
lower_try_finally_switch (state, &this_tf);
}
VEC_free (tree, heap, this_tf.dest_array);
- if (this_tf.goto_queue)
- free (this_tf.goto_queue);
+ free (this_tf.goto_queue);
if (this_tf.goto_queue_map)
pointer_map_destroy (this_tf.goto_queue_map);
this zero argument with the current catch region number. */
if (state->ehp_region)
{
- tree nr = build_int_cst (NULL, state->ehp_region->index);
+ tree nr = build_int_cst (integer_type_node,
+ state->ehp_region->index);
gimple_call_set_arg (stmt, 0, nr);
}
else
case GIMPLE_EH_MUST_NOT_THROW:
replace = lower_eh_must_not_throw (state, stmt);
break;
+ case GIMPLE_EH_ELSE:
+ /* This code is only valid with GIMPLE_TRY_FINALLY. */
+ gcc_unreachable ();
default:
replace = lower_cleanup (state, stmt);
break;
/* Return since we don't want gsi_next () */
return;
+ case GIMPLE_EH_ELSE:
+ /* We should be eliminating this in lower_try_finally et al. */
+ gcc_unreachable ();
+
default:
/* A type, a decl, or some kind of statement that we're not
interested in. Don't walk them. */
PROP_gimple_leh, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func /* todo_flags_finish */
+ 0 /* todo_flags_finish */
}
};
\f
case CALL_EXPR:
t = get_callee_fndecl (expr);
/* Assume that calls to weak functions may trap. */
- if (!t || !DECL_P (t) || DECL_WEAK (t))
+ if (!t || !DECL_P (t))
return true;
+ if (DECL_WEAK (t))
+ return tree_could_trap_p (t);
+ return false;
+
+ case FUNCTION_DECL:
+ /* Assume that accesses to weak functions may trap, unless we know
+ they are certainly defined in current TU or in some other
+ LTO partition. */
+ if (DECL_WEAK (expr))
+ {
+ struct cgraph_node *node;
+ if (!DECL_EXTERNAL (expr))
+ return false;
+ node = cgraph_function_node (cgraph_get_node (expr), NULL);
+ if (node && node->in_other_partition)
+ return false;
+ return true;
+ }
+ return false;
+
+ case VAR_DECL:
+ /* Assume that accesses to weak vars may trap, unless we know
+ they are certainly defined in current TU or in some other
+ LTO partition. */
+ if (DECL_WEAK (expr))
+ {
+ struct varpool_node *node;
+ if (!DECL_EXTERNAL (expr))
+ return false;
+ node = varpool_variable_node (varpool_get_node (expr), NULL);
+ if (node && node->in_other_partition)
+ return false;
+ return true;
+ }
return false;
+ case VAR_DECL:
+ case FUNCTION_DECL:
+ /* Assume that accesses to weak vars or functions may trap. */
+ if (DECL_WEAK (expr))
+ return true;
+ return false;
+
default:
return false;
}
|| TREE_CODE_CLASS (code) == tcc_unary
|| TREE_CODE_CLASS (code) == tcc_binary)
{
- t = gimple_expr_type (stmt);
+ if (is_gimple_assign (stmt)
+ && TREE_CODE_CLASS (code) == tcc_comparison)
+ t = TREE_TYPE (gimple_assign_rhs1 (stmt));
+ else if (gimple_code (stmt) == GIMPLE_COND)
+ t = TREE_TYPE (gimple_cond_lhs (stmt));
+ else
+ t = gimple_expr_type (stmt);
fp_operation = FLOAT_TYPE_P (t);
if (fp_operation)
{
|| gimple_call_lhs (twos)
|| gimple_call_chain (ones)
|| gimple_call_chain (twos)
- || !operand_equal_p (gimple_call_fn (ones), gimple_call_fn (twos), 0)
+ || !gimple_call_same_target_p (ones, twos)
|| gimple_call_num_args (ones) != gimple_call_num_args (twos))
return false;
case GIMPLE_EH_FILTER:
refactor_eh_r (gimple_eh_filter_failure (one));
break;
+ case GIMPLE_EH_ELSE:
+ refactor_eh_r (gimple_eh_else_n_body (one));
+ refactor_eh_r (gimple_eh_else_e_body (one));
+ break;
default:
break;
}
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func /* todo_flags_finish */
+ 0 /* todo_flags_finish */
}
};
\f
Resolve this by expanding the resx node to an abort. */
- fn = implicit_built_in_decls[BUILT_IN_TRAP];
+ fn = builtin_decl_implicit (BUILT_IN_TRAP);
x = gimple_build_call (fn, 0);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
else
{
edge_iterator ei;
- tree dst_nr = build_int_cst (NULL, dst_r->index);
+ tree dst_nr = build_int_cst (integer_type_node, dst_r->index);
- fn = implicit_built_in_decls[BUILT_IN_EH_COPY_VALUES];
- src_nr = build_int_cst (NULL, src_r->index);
+ fn = builtin_decl_implicit (BUILT_IN_EH_COPY_VALUES);
+ src_nr = build_int_cst (integer_type_node, src_r->index);
x = gimple_build_call (fn, 2, dst_nr, src_nr);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
with no arguments for C++ and Java. Check for that. */
if (src_r->use_cxa_end_cleanup)
{
- fn = implicit_built_in_decls[BUILT_IN_CXA_END_CLEANUP];
+ fn = builtin_decl_implicit (BUILT_IN_CXA_END_CLEANUP);
x = gimple_build_call (fn, 0);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
}
else
{
- fn = implicit_built_in_decls[BUILT_IN_EH_POINTER];
- src_nr = build_int_cst (NULL, src_r->index);
+ fn = builtin_decl_implicit (BUILT_IN_EH_POINTER);
+ src_nr = build_int_cst (integer_type_node, src_r->index);
x = gimple_build_call (fn, 1, src_nr);
var = create_tmp_var (ptr_type_node, NULL);
var = make_ssa_name (var, x);
gimple_call_set_lhs (x, var);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
- fn = implicit_built_in_decls[BUILT_IN_UNWIND_RESUME];
+ fn = builtin_decl_implicit (BUILT_IN_UNWIND_RESUME);
x = gimple_build_call (fn, 1, var);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
}
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func | TODO_verify_flow /* todo_flags_finish */
+ TODO_verify_flow /* todo_flags_finish */
}
};
+ /* Try to optimize var = {v} {CLOBBER} stmts followed just by
+ external throw. */
+
+ static void
+ optimize_clobbers (basic_block bb)
+ {
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (is_gimple_debug (stmt))
+ continue;
+ if (!gimple_clobber_p (stmt)
+ || TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
+ return;
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ }
+ }
+
+ /* Try to sink var = {v} {CLOBBER} stmts followed just by
+ internal throw to successor BB. */
+
+ static int
+ sink_clobbers (basic_block bb)
+ {
+ edge e;
+ edge_iterator ei;
+ gimple_stmt_iterator gsi, dgsi;
+ basic_block succbb;
+ bool any_clobbers = false;
+
+ /* Only optimize if BB has a single EH successor and
+ all predecessor edges are EH too. */
+ if (!single_succ_p (bb)
+ || (single_succ_edge (bb)->flags & EDGE_EH) == 0)
+ return 0;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ if ((e->flags & EDGE_EH) == 0)
+ return 0;
+ }
+
+ /* And BB contains only CLOBBER stmts before the final
+ RESX. */
+ gsi = gsi_last_bb (bb);
+ for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (is_gimple_debug (stmt))
+ continue;
+ if (gimple_code (stmt) == GIMPLE_LABEL)
+ break;
+ if (!gimple_clobber_p (stmt)
+ || TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
+ return 0;
+ any_clobbers = true;
+ }
+ if (!any_clobbers)
+ return 0;
+
+ succbb = single_succ (bb);
+ dgsi = gsi_after_labels (succbb);
+ gsi = gsi_last_bb (bb);
+ for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ tree vdef;
+ if (is_gimple_debug (stmt))
+ continue;
+ if (gimple_code (stmt) == GIMPLE_LABEL)
+ break;
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, false);
+ vdef = gimple_vdef (stmt);
+ if (vdef && TREE_CODE (vdef) == SSA_NAME)
+ {
+ vdef = SSA_NAME_VAR (vdef);
+ mark_sym_for_renaming (vdef);
+ gimple_set_vdef (stmt, vdef);
+ gimple_set_vuse (stmt, vdef);
+ }
+ release_defs (stmt);
+ gsi_insert_before (&dgsi, stmt, GSI_SAME_STMT);
+ }
+
+ return TODO_update_ssa_only_virtuals;
+ }
/* At the end of inlining, we can lower EH_DISPATCH. Return true when
we have found some duplicate labels and removed some edges. */
blocks at the end of this pass. */
if (! pointer_set_contains (seen_values, TREE_VALUE (flt_node)))
{
- tree t = build3 (CASE_LABEL_EXPR, void_type_node,
- TREE_VALUE (flt_node), NULL, lab);
+ tree t = build_case_label (TREE_VALUE (flt_node),
+ NULL, lab);
VEC_safe_push (tree, heap, labels, t);
pointer_set_insert (seen_values, TREE_VALUE (flt_node));
have_label = true;
}
else
{
- fn = implicit_built_in_decls[BUILT_IN_EH_FILTER];
- x = gimple_build_call (fn, 1, build_int_cst (NULL, region_nr));
+ fn = builtin_decl_implicit (BUILT_IN_EH_FILTER);
+ x = gimple_build_call (fn, 1, build_int_cst (integer_type_node,
+ region_nr));
filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
filter = make_ssa_name (filter, x);
gimple_call_set_lhs (x, filter);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
/* Turn the default label into a default case. */
- default_label = build3 (CASE_LABEL_EXPR, void_type_node,
- NULL, NULL, default_label);
+ default_label = build_case_label (NULL, NULL, default_label);
sort_case_labels (labels);
x = gimple_build_switch_vec (filter, default_label, labels);
edge b_e = BRANCH_EDGE (src);
edge f_e = FALLTHRU_EDGE (src);
- fn = implicit_built_in_decls[BUILT_IN_EH_FILTER];
- x = gimple_build_call (fn, 1, build_int_cst (NULL, region_nr));
+ fn = builtin_decl_implicit (BUILT_IN_EH_FILTER);
+ x = gimple_build_call (fn, 1, build_int_cst (integer_type_node,
+ region_nr));
filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
filter = make_ssa_name (filter, x);
gimple_call_set_lhs (x, filter);
execute_lower_eh_dispatch (void)
{
basic_block bb;
- bool any_rewritten = false;
+ int flags = 0;
bool redirected = false;
assign_filter_values ();
FOR_EACH_BB (bb)
{
gimple last = last_stmt (bb);
- if (last && gimple_code (last) == GIMPLE_EH_DISPATCH)
+ if (last == NULL)
+ continue;
+ if (gimple_code (last) == GIMPLE_EH_DISPATCH)
{
redirected |= lower_eh_dispatch (bb, last);
- any_rewritten = true;
+ flags |= TODO_update_ssa_only_virtuals;
+ }
+ else if (gimple_code (last) == GIMPLE_RESX)
+ {
+ if (stmt_can_throw_external (last))
+ optimize_clobbers (bb);
+ else
+ flags |= sink_clobbers (bb);
}
}
if (redirected)
delete_unreachable_blocks ();
- return any_rewritten ? TODO_update_ssa_only_virtuals : 0;
+ return flags;
}
static bool
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func | TODO_verify_flow /* todo_flags_finish */
+ TODO_verify_flow /* todo_flags_finish */
}
};
\f
FOR_EACH_BB (bb)
{
- gimple_stmt_iterator gsi = gsi_start_bb (bb);
+ gimple_stmt_iterator gsi;
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
#endif
}
+ /* Remove unreachable handlers if any landing pads have been removed after
+ last ehcleanup pass (due to gimple_purge_dead_eh_edges). */
+
+ void
+ maybe_remove_unreachable_handlers (void)
+ {
+ eh_landing_pad lp;
+ int i;
+
+ if (cfun->eh == NULL)
+ return;
+
+ for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
+ if (lp && lp->post_landing_pad)
+ {
+ if (label_to_block (lp->post_landing_pad) == NULL)
+ {
+ remove_unreachable_handlers ();
+ return;
+ }
+ }
+ }
+
/* Remove regions that do not have landing pads. This assumes
that remove_unreachable_handlers has already been run, and
that we've just manipulated the landing pads since then. */
{
eh_region r;
int i;
+ sbitmap r_reachable;
+ basic_block bb;
+
+ r_reachable = sbitmap_alloc (VEC_length (eh_region, cfun->eh->region_array));
+ sbitmap_zero (r_reachable);
+
+ FOR_EACH_BB (bb)
+ {
+ gimple stmt = last_stmt (bb);
+ if (stmt)
+ /* Avoid removing regions referenced from RESX/EH_DISPATCH. */
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_RESX:
+ SET_BIT (r_reachable, gimple_resx_region (stmt));
+ break;
+ case GIMPLE_EH_DISPATCH:
+ SET_BIT (r_reachable, gimple_eh_dispatch_region (stmt));
+ break;
+ default:
+ break;
+ }
+ }
for (i = 1; VEC_iterate (eh_region, cfun->eh->region_array, i, r); ++i)
- if (r && r->landing_pads == NULL && r->type != ERT_MUST_NOT_THROW)
+ if (r && r->landing_pads == NULL && r->type != ERT_MUST_NOT_THROW
+ && !TEST_BIT (r_reachable, i))
{
if (dump_file)
fprintf (dump_file, "Removing unreachable region %d\n", i);
remove_eh_handler (r);
}
+
+ sbitmap_free (r_reachable);
}
/* Undo critical edge splitting on an EH landing pad. Earlier, we
bitmap rename_virts;
bitmap ophi_handled;
+ /* The destination block must not be a regular successor for any
+ of the preds of the landing pad. Thus, avoid turning
+ <..>
+ | \ EH
+ | <..>
+ | /
+ <..>
+ into
+ <..>
+ | | EH
+ <..>
+ which CFG verification would choke on. See PR45172 and PR51089. */
+ FOR_EACH_EDGE (e, ei, old_bb->preds)
+ if (find_edge (e->src, new_bb))
+ return false;
+
FOR_EACH_EDGE (e, ei, old_bb->preds)
redirect_edge_var_map_clear (e);
{
gimple_stmt_iterator gsi;
tree lab;
- edge_iterator ei;
- edge e;
/* We really ought not have totally lost everything following
a landing pad label. Given that BB is empty, there had better
return false;
}
- /* The destination block must not be a regular successor for any
- of the preds of the landing pad. Thus, avoid turning
- <..>
- | \ EH
- | <..>
- | /
- <..>
- into
- <..>
- | | EH
- <..>
- which CFG verification would choke on. See PR45172. */
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (find_edge (e->src, e_out->dest))
- return false;
-
/* Attempt to move the PHIs into the successor block. */
if (cleanup_empty_eh_merge_phis (e_out->dest, bb, e_out, false))
{
edge_iterator ei;
edge e, e_out;
bool has_non_eh_pred;
+ bool ret = false;
int new_lp_nr;
/* There can be zero or one edges out of BB. This is the quickest test. */
default:
return false;
}
+
+ resx = last_stmt (bb);
+ if (resx && is_gimple_resx (resx))
+ {
+ if (stmt_can_throw_external (resx))
+ optimize_clobbers (bb);
+ else if (sink_clobbers (bb))
+ ret = true;
+ }
+
gsi = gsi_after_labels (bb);
/* Make sure to skip debug statements. */
{
/* For the degenerate case of an infinite loop bail out. */
if (infinite_empty_loop_p (e_out))
- return false;
+ return ret;
- return cleanup_empty_eh_unsplit (bb, e_out, lp);
+ return ret | cleanup_empty_eh_unsplit (bb, e_out, lp);
}
- /* The block should consist only of a single RESX statement. */
+ /* The block should consist only of a single RESX statement, modulo a
+ preceding call to __builtin_stack_restore if there is no outgoing
+ edge, since the call can be eliminated in this case. */
resx = gsi_stmt (gsi);
+ if (!e_out && gimple_call_builtin_p (resx, BUILT_IN_STACK_RESTORE))
+ {
+ gsi_next (&gsi);
+ resx = gsi_stmt (gsi);
+ }
if (!is_gimple_resx (resx))
- return false;
+ return ret;
gcc_assert (gsi_one_before_end_p (gsi));
/* Determine if there are non-EH edges, or resx edges into the handler. */
return true;
}
- return false;
+ return ret;
succeed:
if (dump_file && (dump_flags & TDF_DETAILS))
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func /* todo_flags_finish */
+ 0 /* todo_flags_finish */
}
};
\f
$(srcdir)/unwind-compat.c
SHLIB_MAPFILES += $(srcdir)/config/ia64/libgcc-glibc.ver
+
+MULTIARCH_DIRNAME = $(call if_multiarch,ia64-linux-gnu)
{
int i;
- ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
GFC_DIMENSION_SET(ret->dim[i], 0, ub, str);
}
- if (arraysize > 0)
- ret->data = internal_malloc_size (size * arraysize);
- else
- ret->data = internal_malloc_size (1);
+ /* internal_malloc_size allocates a single byte for zero size. */
+ ret->data = internal_malloc_size (size * arraysize);
}
else if (unlikely (compile_options.bounds_check))
{
int i;
- ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
GFC_DIMENSION_SET(ret->dim[i], 0, ub, str);
}
- if (arraysize > 0)
- ret->data = internal_malloc_size (size * arraysize);
- else
- ret->data = internal_malloc_size (1);
+ /* internal_malloc_size allocates a single byte for zero size. */
+ ret->data = internal_malloc_size (size * arraysize);
}
else if (unlikely (compile_options.bounds_check))
{
int i;
- ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
GFC_DIMENSION_SET(ret->dim[i], 0, ub, str);
}
- if (arraysize > 0)
- ret->data = internal_malloc_size (size * arraysize);
- else
- ret->data = internal_malloc_size (1);
+ /* internal_malloc_size allocates a single byte for zero size. */
+ ret->data = internal_malloc_size (size * arraysize);
}
else if (unlikely (compile_options.bounds_check))
if (sseek (u->s, 0, SEEK_SET) < 0)
generate_error (&fpp->common, LIBERROR_OS, NULL);
- /* Handle special files like /dev/null differently. */
- if (!is_special (u->s))
+ /* Set this for compatibilty with g77 for /dev/null. */
+ if (ssize (u->s) == 0)
+ u->endfile = AT_ENDFILE;
+ else
{
/* We are rewinding so we are not at the end. */
u->endfile = NO_ENDFILE;
}
- else
- {
- /* Set this for compatibilty with g77 for /dev/null. */
- if (file_length (u->s) == 0 && stell (u->s) == 0)
- u->endfile = AT_ENDFILE;
- /* Future refinements on special files can go here. */
- }
-
+
u->current_record = 0;
u->strm_pos = 1;
u->read_bad = 0;
if (u->flags.form == FORM_FORMATTED)
fbuf_flush (u, u->mode);
- sflush (u->s);
+ flush_sync (u->s);
unlock_unit (u);
}
else
#include "io.h"
#include "fbuf.h"
#include "unix.h"
-
- #ifdef HAVE_STDLIB_H
#include <stdlib.h>
- #endif
-
#include <string.h>
+
static const int five = 5;
static const int six = 6;
us = find_unit (*unit);
if (us != NULL)
{
- sflush (us->s);
+ flush_sync (us->s);
unlock_unit (us);
}
}
us = find_unit (*unit);
if (us != NULL)
{
- sflush (us->s);
+ flush_sync (us->s);
unlock_unit (us);
}
}
gfc_unit * u = find_unit (*unit);
ssize_t result = -1;
- if (u != NULL && is_seekable(u->s))
+ if (u != NULL)
{
result = sseek(u->s, *offset, *whence);
- /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011
- Free Software Foundation, Inc.
+ /* Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by Andy Vaught
F2003 I/O support contributed by Jerry DeLisle
#include <errno.h>
+ /* min macro that evaluates its arguments only once. */
+ #define min(a,b) \
+ ({ typeof (a) _a = (a); \
+ typeof (b) _b = (b); \
+ _a < _b ? _a : _b; })
+
+
/* For mingw, we don't identify files by their inode number, but by a
64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
#ifdef __MINGW32__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+ #if !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
+ #undef lseek
#define lseek _lseeki64
+ #undef fstat
#define fstat _fstati64
+ #undef stat
#define stat _stati64
- typedef struct _stati64 gfstat_t;
+ #endif
#ifndef HAVE_WORKING_STAT
static uint64_t
}
#endif
-
- #else
- typedef struct stat gfstat_t;
#endif
#ifndef PATH_MAX
if (mode == F_OK)
{
- gfstat_t st;
+ struct stat st;
return stat (path, &st);
}
gfc_offset buffer_offset; /* File offset of the start of the buffer */
gfc_offset physical_offset; /* Current physical file offset */
gfc_offset logical_offset; /* Current logical file offset */
- gfc_offset file_length; /* Length of the file, -1 if not seekable. */
+ gfc_offset file_length; /* Length of the file. */
char *buffer; /* Pointer to the buffer. */
int fd; /* The POSIX file descriptor. */
int ndirty; /* Dirty bytes starting at buffer_offset */
- int special_file; /* =1 if the fd refers to a special file */
-
/* Cached stat(2) values. */
dev_t st_dev;
ino_t st_ino;
return lseek (s->fd, 0, SEEK_CUR);
}
+ static gfc_offset
+ raw_size (unix_stream * s)
+ {
+ struct stat statbuf;
+ int ret = fstat (s->fd, &statbuf);
+ if (ret == -1)
+ return ret;
+ if (S_ISREG (statbuf.st_mode))
+ return statbuf.st_size;
+ else
+ return 0;
+ }
+
static int
raw_truncate (unix_stream * s, gfc_offset length)
{
s->st.write = (void *) raw_write;
s->st.seek = (void *) raw_seek;
s->st.tell = (void *) raw_tell;
+ s->st.size = (void *) raw_size;
s->st.trunc = (void *) raw_truncate;
s->st.close = (void *) raw_close;
s->st.flush = (void *) raw_flush;
Buffered I/O functions. These functions have the same semantics as the
raw I/O functions above, except that they are buffered in order to
improve performance. The buffer must be flushed when switching from
- reading to writing and vice versa.
+ reading to writing and vice versa. Only supported for regular files.
*********************************************************************/
static int
if (s->ndirty == 0)
return 0;
- if (s->file_length != -1 && s->physical_offset != s->buffer_offset
+ if (s->physical_offset != s->buffer_offset
&& lseek (s->fd, s->buffer_offset, SEEK_SET) < 0)
return -1;
s->physical_offset = s->buffer_offset + writelen;
- /* Don't increment file_length if the file is non-seekable. */
- if (s->file_length != -1 && s->physical_offset > s->file_length)
+ if (s->physical_offset > s->file_length)
s->file_length = s->physical_offset;
s->ndirty -= writelen;
/* At this point we consider all bytes in the buffer discarded. */
to_read = nbyte - nread;
new_logical = s->logical_offset + nread;
- if (s->file_length != -1 && s->physical_offset != new_logical
+ if (s->physical_offset != new_logical
&& lseek (s->fd, new_logical, SEEK_SET) < 0)
return -1;
s->buffer_offset = s->physical_offset = new_logical;
}
else
{
- if (s->file_length != -1 && s->physical_offset != s->logical_offset)
+ if (s->physical_offset != s->logical_offset)
{
if (lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
return -1;
}
}
s->logical_offset += nbyte;
- /* Don't increment file_length if the file is non-seekable. */
- if (s->file_length != -1 && s->logical_offset > s->file_length)
+ if (s->logical_offset > s->file_length)
s->file_length = s->logical_offset;
return nbyte;
}
static gfc_offset
buf_tell (unix_stream * s)
{
- return s->logical_offset;
+ return buf_seek (s, 0, SEEK_CUR);
+ }
+
+ static gfc_offset
+ buf_size (unix_stream * s)
+ {
+ return s->file_length;
}
static int
s->st.write = (void *) buf_write;
s->st.seek = (void *) buf_seek;
s->st.tell = (void *) buf_tell;
+ s->st.size = (void *) buf_size;
s->st.trunc = (void *) buf_truncate;
s->st.close = (void *) buf_close;
s->st.flush = (void *) buf_flush;
static int
mem_close (unix_stream * s)
{
- if (s != NULL)
- free (s);
+ free (s);
return 0;
}
s->st.close = (void *) mem_close;
s->st.seek = (void *) mem_seek;
s->st.tell = (void *) mem_tell;
+ /* buf_size is not a typo, we just reuse an identical
+ implementation. */
+ s->st.size = (void *) buf_size;
s->st.trunc = (void *) mem_truncate;
s->st.read = (void *) mem_read;
s->st.write = (void *) mem_write;
s->st.close = (void *) mem_close;
s->st.seek = (void *) mem_seek;
s->st.tell = (void *) mem_tell;
+ /* buf_size is not a typo, we just reuse an identical
+ implementation. */
+ s->st.size = (void *) buf_size;
s->st.trunc = (void *) mem_truncate;
s->st.read = (void *) mem_read4;
s->st.write = (void *) mem_write4;
static stream *
fd_to_stream (int fd)
{
- gfstat_t statbuf;
+ struct stat statbuf;
unix_stream *s;
s = get_mem (sizeof (unix_stream));
s->st_dev = statbuf.st_dev;
s->st_ino = statbuf.st_ino;
- s->special_file = !S_ISREG (statbuf.st_mode);
-
- if (S_ISREG (statbuf.st_mode))
- s->file_length = statbuf.st_size;
- else if (S_ISBLK (statbuf.st_mode))
- {
- /* Hopefully more portable than ioctl(fd, BLKGETSIZE64, &size)? */
- gfc_offset cur = lseek (fd, 0, SEEK_CUR);
- s->file_length = lseek (fd, 0, SEEK_END);
- lseek (fd, cur, SEEK_SET);
- }
+ s->file_length = statbuf.st_size;
+
+ /* Only use buffered IO for regular files. */
+ if (S_ISREG (statbuf.st_mode)
+ && !options.all_unbuffered
+ && !(options.unbuffered_preconnected &&
+ (s->fd == STDIN_FILENO
+ || s->fd == STDOUT_FILENO
+ || s->fd == STDERR_FILENO)))
+ buf_init (s);
else
- s->file_length = -1;
-
- if (!(S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
- || options.all_unbuffered
- ||(options.unbuffered_preconnected &&
- (s->fd == STDIN_FILENO
- || s->fd == STDOUT_FILENO
- || s->fd == STDERR_FILENO))
- || isatty (s->fd))
raw_init (s);
- else
- buf_init (s);
return (stream *) s;
}
unpack_filename (char *cstring, const char *fstring, int len)
{
if (fstring == NULL)
- return 1;
+ return EFAULT;
len = fstrlen (fstring, len);
if (len >= PATH_MAX)
- return 1;
+ return ENAMETOOLONG;
memmove (cstring, fstring, len);
cstring[len] = '\0';
char *template;
const char *slash = "/";
int fd;
+ size_t tempdirlen;
+
+ #ifndef HAVE_MKSTEMP
+ int count;
+ size_t slashlen;
+ #endif
tempdir = getenv ("GFORTRAN_TMPDIR");
#ifdef __MINGW32__
if (tempdir == NULL)
tempdir = DEFAULT_TEMPDIR;
#endif
+
/* Check for special case that tempdir contains slash
or backslash at end. */
- if (*tempdir == 0 || tempdir[strlen (tempdir) - 1] == '/'
+ tempdirlen = strlen (tempdir);
+ if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/'
#ifdef __MINGW32__
- || tempdir[strlen (tempdir) - 1] == '\\'
+ || tempdir[tempdirlen - 1] == '\\'
#endif
)
slash = "";
- template = get_mem (strlen (tempdir) + 20);
+ // Take care that the template is longer in the mktemp() branch.
+ template = get_mem (tempdirlen + 23);
#ifdef HAVE_MKSTEMP
- sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
+ snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX",
+ tempdir, slash);
fd = mkstemp (template);
#else /* HAVE_MKSTEMP */
fd = -1;
+ count = 0;
+ slashlen = strlen (slash);
do
{
- sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
+ snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX",
+ tempdir, slash);
+ if (count > 0)
+ {
+ int c = count;
+ template[tempdirlen + slashlen + 13] = 'a' + (c% 26);
+ c /= 26;
+ template[tempdirlen + slashlen + 12] = 'a' + (c % 26);
+ c /= 26;
+ template[tempdirlen + slashlen + 11] = 'a' + (c % 26);
+ if (c >= 26)
+ break;
+ }
+
if (!mktemp (template))
- break;
+ {
+ errno = EEXIST;
+ count++;
+ continue;
+ }
+
#if defined(HAVE_CRLF) && defined(O_BINARY)
fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
- S_IREAD | S_IWRITE);
+ S_IRUSR | S_IWUSR);
#else
- fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
+ fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
#endif
}
while (fd == -1 && errno == EEXIST);
static int
regular_file (st_parameter_open *opp, unit_flags *flags)
{
- char path[PATH_MAX + 1];
+ char path[min(PATH_MAX, opp->file_len + 1)];
int mode;
int rwflag;
int crflag;
int fd;
+ int err;
- if (unpack_filename (path, opp->file, opp->file_len))
+ err = unpack_filename (path, opp->file, opp->file_len);
+ if (err)
{
- errno = ENOENT; /* Fake an OS error */
+ errno = err; /* Fake an OS error */
return -1;
}
}
- /* st_vprintf()-- vprintf function for error output. To avoid buffer
- overruns, we limit the length of the buffer to ST_VPRINTF_SIZE. 2k
- is big enough to completely fill a 80x25 terminal, so it shuld be
- OK. We use a direct write() because it is simpler and least likely
- to be clobbered by memory corruption. Writing an error message
- longer than that is an error. */
-
- #define ST_VPRINTF_SIZE 2048
-
- int
- st_vprintf (const char *format, va_list ap)
- {
- static char buffer[ST_VPRINTF_SIZE];
- int written;
- int fd;
-
- fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
- #ifdef HAVE_VSNPRINTF
- written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap);
- #else
- written = vsprintf(buffer, format, ap);
-
- if (written >= ST_VPRINTF_SIZE-1)
- {
- /* The error message was longer than our buffer. Ouch. Because
- we may have messed up things badly, report the error and
- quit. */
- #define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n"
- write (fd, buffer, ST_VPRINTF_SIZE-1);
- write (fd, ERROR_MESSAGE, strlen(ERROR_MESSAGE));
- sys_exit(2);
- #undef ERROR_MESSAGE
-
- }
- #endif
-
- written = write (fd, buffer, written);
- return written;
- }
-
- /* st_printf()-- printf() function for error output. This just calls
- st_vprintf() to do the actual work. */
-
- int
- st_printf (const char *format, ...)
- {
- int written;
- va_list ap;
- va_start (ap, format);
- written = st_vprintf(format, ap);
- va_end (ap);
- return written;
- }
-
-
/* compare_file_filename()-- Given an open stream and a fortran string
* that is a filename, figure out if the file is the same as the
* filename. */
int
compare_file_filename (gfc_unit *u, const char *name, int len)
{
- char path[PATH_MAX + 1];
- gfstat_t st;
+ char path[min(PATH_MAX, len + 1)];
+ struct stat st;
#ifdef HAVE_WORKING_STAT
unix_stream *s;
#else
#ifdef HAVE_WORKING_STAT
- # define FIND_FILE0_DECL gfstat_t *st
+ # define FIND_FILE0_DECL struct stat *st
# define FIND_FILE0_ARGS st
#else
# define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
gfc_unit *
find_file (const char *file, gfc_charlen_type file_len)
{
- char path[PATH_MAX + 1];
- gfstat_t st[1];
+ char path[min(PATH_MAX, file_len + 1)];
+ struct stat st[1];
gfc_unit *u;
#if defined(__MINGW32__) && !HAVE_WORKING_STAT
uint64_t id = 0ULL;
return u;
}
+
+/* Flush dirty data, making sure that OS metadata is updated as
+ well. Note that this is VERY slow on mingw due to committing data
+ to stable storage. */
+int
+flush_sync (stream * s)
+{
+ if (sflush (s) == -1)
+ return -1;
+#ifdef __MINGW32__
+ if (_commit (((unix_stream *)s)->fd) == -1)
+ return -1;
+#endif
+ return 0;
+}
+
+
static gfc_unit *
flush_all_units_1 (gfc_unit *u, int min_unit)
{
if (__gthread_mutex_trylock (&u->lock))
return u;
if (u->s)
- sflush (u->s);
+ flush_sync (u->s);
__gthread_mutex_unlock (&u->lock);
}
u = u->right;
if (u->closed == 0)
{
- sflush (u->s);
+ flush_sync (u->s);
__gthread_mutex_lock (&unit_lock);
__gthread_mutex_unlock (&u->lock);
(void) predec_waiting_locked (u);
int
delete_file (gfc_unit * u)
{
- char path[PATH_MAX + 1];
+ char path[min(PATH_MAX, u->file_len + 1)];
+ int err = unpack_filename (path, u->file, u->file_len);
- if (unpack_filename (path, u->file, u->file_len))
+ if (err)
{ /* Shouldn't be possible */
- errno = ENOENT;
+ errno = err;
return 1;
}
int
file_exists (const char *file, gfc_charlen_type file_len)
{
- char path[PATH_MAX + 1];
+ char path[min(PATH_MAX, file_len + 1)];
if (unpack_filename (path, file, file_len))
return 0;
GFC_IO_INT
file_size (const char *file, gfc_charlen_type file_len)
{
- char path[PATH_MAX + 1];
- gfstat_t statbuf;
+ char path[min(PATH_MAX, file_len + 1)];
+ struct stat statbuf;
if (unpack_filename (path, file, file_len))
return -1;
const char *
inquire_sequential (const char *string, int len)
{
- char path[PATH_MAX + 1];
- gfstat_t statbuf;
+ char path[min(PATH_MAX, len + 1)];
+ struct stat statbuf;
if (string == NULL ||
unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
const char *
inquire_direct (const char *string, int len)
{
- char path[PATH_MAX + 1];
- gfstat_t statbuf;
+ char path[min(PATH_MAX, len + 1)];
+ struct stat statbuf;
if (string == NULL ||
unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
const char *
inquire_formatted (const char *string, int len)
{
- char path[PATH_MAX + 1];
- gfstat_t statbuf;
+ char path[min(PATH_MAX, len + 1)];
+ struct stat statbuf;
if (string == NULL ||
unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
static const char *
inquire_access (const char *string, int len, int mode)
{
- char path[PATH_MAX + 1];
+ char path[min(PATH_MAX, len + 1)];
if (string == NULL || unpack_filename (path, string, len) ||
access (path, mode) < 0)
}
- /* file_length()-- Return the file length in bytes, -1 if unknown */
-
- gfc_offset
- file_length (stream * s)
- {
- gfc_offset curr, end;
- if (!is_seekable (s))
- return -1;
- curr = stell (s);
- if (curr == -1)
- return curr;
- end = sseek (s, 0, SEEK_END);
- sseek (s, curr, SEEK_SET);
- return end;
- }
-
-
- /* is_seekable()-- Return nonzero if the stream is seekable, zero if
- * it is not */
-
- int
- is_seekable (stream *s)
- {
- /* By convention, if file_length == -1, the file is not
- seekable. */
- return ((unix_stream *) s)->file_length!=-1;
- }
-
-
- /* is_special()-- Return nonzero if the stream is not a regular file. */
-
- int
- is_special (stream *s)
- {
- return ((unix_stream *) s)->special_file;
- }
-
-
int
stream_isatty (stream *s)
{
ssize_t (*write) (struct stream *, const void *, ssize_t);
gfc_offset (*seek) (struct stream *, gfc_offset, int);
gfc_offset (*tell) (struct stream *);
+ gfc_offset (*size) (struct stream *);
/* Avoid keyword truncate due to AIX namespace collision. */
int (*trunc) (struct stream *, gfc_offset);
int (*flush) (struct stream *);
return s->tell (s);
}
+ static inline gfc_offset
+ ssize (stream * s)
+ {
+ return s->size (s);
+ }
+
static inline int
struncate (stream * s, gfc_offset length)
{
extern const char *inquire_readwrite (const char *, int);
internal_proto(inquire_readwrite);
- extern gfc_offset file_length (stream *);
- internal_proto(file_length);
-
- extern int is_seekable (stream *);
- internal_proto(is_seekable);
-
- extern int is_special (stream *);
- internal_proto(is_special);
-
extern void flush_if_preconnected (stream *);
internal_proto(flush_if_preconnected);
+extern int flush_sync (stream *);
+internal_proto(flush_sync);
+
extern int stream_isatty (stream *);
internal_proto(stream_isatty);
{
int i;
- ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
GFC_DIMENSION_SET(ret->dim[i], 0, ub, str);
}
- if (arraysize > 0)
- ret->data = internal_malloc_size (size * arraysize);
- else
- ret->data = internal_malloc_size (1);
+ /* internal_malloc_size allocates a single byte for zero size. */
+ ret->data = internal_malloc_size (size * arraysize);
}
else if (unlikely (compile_options.bounds_check))
/* Define if ECANCELED exists. */
#undef HAVE_ECANCELED
+ /* Define if ECHILD exists. */
+ #undef HAVE_ECHILD
+
/* Define if EIDRM exists. */
#undef HAVE_EIDRM
/* Define if ENOLINK exists. */
#undef HAVE_ENOLINK
+ /* Define if ENOSPC exists. */
+ #undef HAVE_ENOSPC
+
/* Define if ENOSR exists. */
#undef HAVE_ENOSR
/* Define if EOWNERDEAD exists. */
#undef HAVE_EOWNERDEAD
+ /* Define if EPERM exists. */
+ #undef HAVE_EPERM
+
/* Define if EPROTO exists. */
#undef HAVE_EPROTO
/* Define if ETIME exists. */
#undef HAVE_ETIME
+ /* Define if ETIMEDOUT exists. */
+ #undef HAVE_ETIMEDOUT
+
/* Define if ETXTBSY exists. */
#undef HAVE_ETXTBSY
+ /* Define if EWOULDBLOCK exists. */
+ #undef HAVE_EWOULDBLOCK
+
/* Define to 1 if you have the <execinfo.h> header file. */
#undef HAVE_EXECINFO_H
/* Define if _Unwind_GetIPInfo is available. */
#undef HAVE_GETIPINFO
- /* Define if gthr-default.h exists (meaning that threading support is
- enabled). */
- #undef HAVE_GTHR_DEFAULT
+ /* Define if gets is available in <stdio.h>. */
+ #undef HAVE_GETS
/* Define to 1 if you have the `hypot' function. */
#undef HAVE_HYPOT
/* Define to 1 if you have the `sqrtl' function. */
#undef HAVE_SQRTL
+ /* Define to 1 if you have the <stdalign.h> header file. */
+ #undef HAVE_STDALIGN_H
+
/* Define to 1 if you have the <stdbool.h> header file. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
+ /* Define to 1 if you have the <sys/sysinfo.h> header file. */
+ #undef HAVE_SYS_SYSINFO_H
+
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Version number of package */
#undef VERSION
- /* Define if builtin atomic operations for bool are supported on this host. */
- #undef _GLIBCXX_ATOMIC_BUILTINS_1
-
- /* Define if builtin atomic operations for short are supported on this host.
- */
- #undef _GLIBCXX_ATOMIC_BUILTINS_2
-
- /* Define if builtin atomic operations for int are supported on this host. */
- #undef _GLIBCXX_ATOMIC_BUILTINS_4
-
- /* Define if builtin atomic operations for long long are supported on this
- host. */
- #undef _GLIBCXX_ATOMIC_BUILTINS_8
+ /* Define if the compiler supports C++11 atomics. */
+ #undef _GLIBCXX_ATOMIC_BUILTINS
/* Define to use concept checking code from the boost libraries. */
#undef _GLIBCXX_CONCEPT_CHECKS
- /* Define if a fully dynamic basic_string is wanted. */
+ /* Define to 1 if a fully dynamic basic_string is wanted, 0 to disable,
+ undefined for platform defaults */
#undef _GLIBCXX_FULLY_DYNAMIC_STRING
+/* Define if gthreads types cannot be copy-assigned in C++11. */
+#undef _GLIBCXX_GTHREADS_NO_COPY_ASSIGN_IN_CXX11
+
/* Define if gthreads library is available. */
#undef _GLIBCXX_HAS_GTHREADS
this host. */
#undef _GLIBCXX_USE_DECIMAL_FLOAT
+ /* Define if __float128 is supported on this host. */
+ #undef _GLIBCXX_USE_FLOAT128
+
/* Defined if gettimeofday is available. */
#undef _GLIBCXX_USE_GETTIMEOFDAY
+ /* Define if get_nprocs is available in <sys/sysinfo.h>. */
+ #undef _GLIBCXX_USE_GET_NPROCS
+
+ /* Define if __int128 is supported on this host. */
+ #undef _GLIBCXX_USE_INT128
+
/* Define if LFS support is available. */
#undef _GLIBCXX_USE_LFS
/* Define if NLS translations are to be used. */
#undef _GLIBCXX_USE_NLS
+ /* Define if pthreads_num_processors_np is available in <pthread.h>. */
+ #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP
+
/* Define if /dev/random and /dev/urandom are available for the random_device
of TR1 (Chapter 5.1). */
#undef _GLIBCXX_USE_RANDOM_TR1
/* Defined if sched_yield is available. */
#undef _GLIBCXX_USE_SCHED_YIELD
+ /* Define if _SC_NPROCESSORS_ONLN is available in <unistd.h>. */
+ #undef _GLIBCXX_USE_SC_NPROCESSORS_ONLN
+
+ /* Define if _SC_NPROC_ONLN is available in <unistd.h>. */
+ #undef _GLIBCXX_USE_SC_NPROC_ONLN
+
+ /* Define if sysctl(), CTL_HW and HW_NCPU are available in <sys/sysctl.h>. */
+ #undef _GLIBCXX_USE_SYSCTL_HW_NCPU
+
/* Define if code specialized for wchar_t should be used. */
#undef _GLIBCXX_USE_WCHAR_T
+ /* Define to 1 if mutex_timedlock is available. */
+ #undef _GTHREAD_USE_MUTEX_TIMEDLOCK
+
+ /* Define if all C++ overloads are available in <math.h>. */
+ #if __cplusplus >= 199711L
+ #undef __CORRECT_ISO_CPP_MATH_H_PROTO1
+ #endif
+
+ /* Define if only double std::abs(double) is available in <math.h>. */
+ #if __cplusplus >= 199711L
+ #undef __CORRECT_ISO_CPP_MATH_H_PROTO2
+ #endif
+
+ /* Define if all C++ overloads are available in <stdlib.h>. */
+ #if __cplusplus >= 199711L
+ #undef __CORRECT_ISO_CPP_STDLIB_H_PROTO
+ #endif
+
#if defined (HAVE__ACOSF) && ! defined (HAVE_ACOSF)
# define HAVE_ACOSF 1
# define acosf _acosf
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
- /// Swaps the median value of *__a, *__b and *__c to *__a
+ /// Swaps the median value of *__a, *__b and *__c to *__result
template<typename _Iterator>
void
- __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c)
+ __move_median_to_first(_Iterator __result, _Iterator __a,
+ _Iterator __b, _Iterator __c)
{
// concept requirements
__glibcxx_function_requires(_LessThanComparableConcept<
if (*__a < *__b)
{
if (*__b < *__c)
- std::iter_swap(__a, __b);
+ std::iter_swap(__result, __b);
else if (*__a < *__c)
- std::iter_swap(__a, __c);
+ std::iter_swap(__result, __c);
+ else
+ std::iter_swap(__result, __a);
}
else if (*__a < *__c)
- return;
+ std::iter_swap(__result, __a);
else if (*__b < *__c)
- std::iter_swap(__a, __c);
+ std::iter_swap(__result, __c);
else
- std::iter_swap(__a, __b);
+ std::iter_swap(__result, __b);
}
- /// Swaps the median value of *__a, *__b and *__c under __comp to *__a
+ /// Swaps the median value of *__a, *__b and *__c under __comp to *__result
template<typename _Iterator, typename _Compare>
void
- __move_median_first(_Iterator __a, _Iterator __b, _Iterator __c,
- _Compare __comp)
+ __move_median_to_first(_Iterator __result, _Iterator __a,
+ _Iterator __b, _Iterator __c,
+ _Compare __comp)
{
// concept requirements
__glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool,
if (__comp(*__a, *__b))
{
if (__comp(*__b, *__c))
- std::iter_swap(__a, __b);
+ std::iter_swap(__result, __b);
else if (__comp(*__a, *__c))
- std::iter_swap(__a, __c);
+ std::iter_swap(__result, __c);
+ else
+ std::iter_swap(__result, __a);
}
else if (__comp(*__a, *__c))
- return;
+ std::iter_swap(__result, __a);
else if (__comp(*__b, *__c))
- std::iter_swap(__a, __c);
+ std::iter_swap(__result, __c);
else
- std::iter_swap(__a, __b);
+ std::iter_swap(__result, __b);
}
// for_each
}
}
- #ifdef __GXX_EXPERIMENTAL_CXX0X__
/// This is an overload used by find_if_not() for the Input Iterator case.
template<typename _InputIterator, typename _Predicate>
inline _InputIterator
return __last;
}
}
- #endif
+
+ /// Provided for stable_partition to use.
+ template<typename _InputIterator, typename _Predicate>
+ inline _InputIterator
+ __find_if_not(_InputIterator __first, _InputIterator __last,
+ _Predicate __pred)
+ {
+ return std::__find_if_not(__first, __last, __pred,
+ std::__iterator_category(__first));
+ }
+
+ /// Like find_if_not(), but uses and updates a count of the
+ /// remaining range length instead of comparing against an end
+ /// iterator.
+ template<typename _InputIterator, typename _Predicate, typename _Distance>
+ _InputIterator
+ __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred)
+ {
+ for (; __len; --__len, ++__first)
+ if (!bool(__pred(*__first)))
+ break;
+ return __first;
+ }
// set_difference
// set_intersection
/**
* @brief Find last matching subsequence in a sequence.
* @ingroup non_mutating_algorithms
- * @param first1 Start of range to search.
- * @param last1 End of range to search.
- * @param first2 Start of sequence to match.
- * @param last2 End of sequence to match.
+ * @param __first1 Start of range to search.
+ * @param __last1 End of range to search.
+ * @param __first2 Start of sequence to match.
+ * @param __last2 End of sequence to match.
* @return The last iterator @c i in the range
- * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N)
- * for each @c N in the range @p [0,last2-first2), or @p last1 if no
- * such iterator exists.
+ * @p [__first1,__last1-(__last2-__first2)) such that @c *(i+N) ==
+ * @p *(__first2+N) for each @c N in the range @p
+ * [0,__last2-__first2), or @p __last1 if no such iterator exists.
*
- * Searches the range @p [first1,last1) for a sub-sequence that compares
- * equal value-by-value with the sequence given by @p [first2,last2) and
- * returns an iterator to the first element of the sub-sequence, or
- * @p last1 if the sub-sequence is not found. The sub-sequence will be the
- * last such subsequence contained in [first,last1).
+ * Searches the range @p [__first1,__last1) for a sub-sequence that
+ * compares equal value-by-value with the sequence given by @p
+ * [__first2,__last2) and returns an iterator to the __first
+ * element of the sub-sequence, or @p __last1 if the sub-sequence
+ * is not found. The sub-sequence will be the last such
+ * subsequence contained in [__first,__last1).
*
- * Because the sub-sequence must lie completely within the range
- * @p [first1,last1) it must start at a position less than
- * @p last1-(last2-first2) where @p last2-first2 is the length of the
- * sub-sequence.
- * This means that the returned iterator @c i will be in the range
- * @p [first1,last1-(last2-first2))
+ * Because the sub-sequence must lie completely within the range @p
+ * [__first1,__last1) it must start at a position less than @p
+ * __last1-(__last2-__first2) where @p __last2-__first2 is the
+ * length of the sub-sequence. This means that the returned
+ * iterator @c i will be in the range @p
+ * [__first1,__last1-(__last2-__first2))
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
inline _ForwardIterator1
/**
* @brief Find last matching subsequence in a sequence using a predicate.
* @ingroup non_mutating_algorithms
- * @param first1 Start of range to search.
- * @param last1 End of range to search.
- * @param first2 Start of sequence to match.
- * @param last2 End of sequence to match.
- * @param comp The predicate to use.
- * @return The last iterator @c i in the range
- * @p [first1,last1-(last2-first2)) such that @c predicate(*(i+N), @p
- * (first2+N)) is true for each @c N in the range @p [0,last2-first2), or
- * @p last1 if no such iterator exists.
+ * @param __first1 Start of range to search.
+ * @param __last1 End of range to search.
+ * @param __first2 Start of sequence to match.
+ * @param __last2 End of sequence to match.
+ * @param __comp The predicate to use.
+ * @return The last iterator @c i in the range @p
+ * [__first1,__last1-(__last2-__first2)) such that @c
+ * predicate(*(i+N), @p (__first2+N)) is true for each @c N in the
+ * range @p [0,__last2-__first2), or @p __last1 if no such iterator
+ * exists.
*
- * Searches the range @p [first1,last1) for a sub-sequence that compares
- * equal value-by-value with the sequence given by @p [first2,last2) using
- * comp as a predicate and returns an iterator to the first element of the
- * sub-sequence, or @p last1 if the sub-sequence is not found. The
- * sub-sequence will be the last such subsequence contained in
- * [first,last1).
+ * Searches the range @p [__first1,__last1) for a sub-sequence that
+ * compares equal value-by-value with the sequence given by @p
+ * [__first2,__last2) using comp as a predicate and returns an
+ * iterator to the first element of the sub-sequence, or @p __last1
+ * if the sub-sequence is not found. The sub-sequence will be the
+ * last such subsequence contained in [__first,__last1).
*
- * Because the sub-sequence must lie completely within the range
- * @p [first1,last1) it must start at a position less than
- * @p last1-(last2-first2) where @p last2-first2 is the length of the
- * sub-sequence.
- * This means that the returned iterator @c i will be in the range
- * @p [first1,last1-(last2-first2))
+ * Because the sub-sequence must lie completely within the range @p
+ * [__first1,__last1) it must start at a position less than @p
+ * __last1-(__last2-__first2) where @p __last2-__first2 is the
+ * length of the sub-sequence. This means that the returned
+ * iterator @c i will be in the range @p
+ * [__first1,__last1-(__last2-__first2))
*/
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
* @brief Checks that a predicate is true for all the elements
* of a sequence.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param pred A predicate.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __pred A predicate.
* @return True if the check is true, false otherwise.
*
- * Returns true if @p pred is true for each element in the range
- * @p [first,last), and false otherwise.
+ * Returns true if @p __pred is true for each element in the range
+ * @p [__first,__last), and false otherwise.
*/
template<typename _InputIterator, typename _Predicate>
inline bool
* @brief Checks that a predicate is false for all the elements
* of a sequence.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param pred A predicate.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __pred A predicate.
* @return True if the check is true, false otherwise.
*
- * Returns true if @p pred is false for each element in the range
- * @p [first,last), and false otherwise.
+ * Returns true if @p __pred is false for each element in the range
+ * @p [__first,__last), and false otherwise.
*/
template<typename _InputIterator, typename _Predicate>
inline bool
* @brief Checks that a predicate is false for at least an element
* of a sequence.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param pred A predicate.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __pred A predicate.
* @return True if the check is true, false otherwise.
*
- * Returns true if an element exists in the range @p [first,last) such that
- * @p pred is true, and false otherwise.
+ * Returns true if an element exists in the range @p
+ * [__first,__last) such that @p __pred is true, and false
+ * otherwise.
*/
template<typename _InputIterator, typename _Predicate>
inline bool
* @brief Find the first element in a sequence for which a
* predicate is false.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param pred A predicate.
- * @return The first iterator @c i in the range @p [first,last)
- * such that @p pred(*i) is false, or @p last if no such iterator exists.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __pred A predicate.
+ * @return The first iterator @c i in the range @p [__first,__last)
+ * such that @p __pred(*i) is false, or @p __last if no such iterator exists.
*/
template<typename _InputIterator, typename _Predicate>
inline _InputIterator
__glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__find_if_not(__first, __last, __pred,
- std::__iterator_category(__first));
+ return std::__find_if_not(__first, __last, __pred);
}
/**
* @brief Checks whether the sequence is partitioned.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param pred A predicate.
- * @return True if the range @p [first,last) is partioned by @p pred,
- * i.e. if all elements that satisfy @p pred appear before those that
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __pred A predicate.
+ * @return True if the range @p [__first,__last) is partioned by @p __pred,
+ * i.e. if all elements that satisfy @p __pred appear before those that
* do not.
*/
template<typename _InputIterator, typename _Predicate>
/**
* @brief Find the partition point of a partitioned range.
* @ingroup mutating_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param pred A predicate.
- * @return An iterator @p mid such that @p all_of(first, mid, pred)
- * and @p none_of(mid, last, pred) are both true.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __pred A predicate.
+ * @return An iterator @p mid such that @p all_of(__first, mid, __pred)
+ * and @p none_of(mid, __last, __pred) are both true.
*/
template<typename _ForwardIterator, typename _Predicate>
_ForwardIterator
/**
* @brief Copy a sequence, removing elements of a given value.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param result An output iterator.
- * @param value The value to be removed.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __result An output iterator.
+ * @param __value The value to be removed.
* @return An iterator designating the end of the resulting sequence.
*
- * Copies each element in the range @p [first,last) not equal to @p value
- * to the range beginning at @p result.
- * remove_copy() is stable, so the relative order of elements that are
- * copied is unchanged.
+ * Copies each element in the range @p [__first,__last) not equal
+ * to @p __value to the range beginning at @p __result.
+ * remove_copy() is stable, so the relative order of elements that
+ * are copied is unchanged.
*/
template<typename _InputIterator, typename _OutputIterator, typename _Tp>
_OutputIterator
/**
* @brief Copy a sequence, removing elements for which a predicate is true.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param result An output iterator.
- * @param pred A predicate.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __result An output iterator.
+ * @param __pred A predicate.
* @return An iterator designating the end of the resulting sequence.
*
- * Copies each element in the range @p [first,last) for which
- * @p pred returns false to the range beginning at @p result.
+ * Copies each element in the range @p [__first,__last) for which
+ * @p __pred returns false to the range beginning at @p __result.
*
* remove_copy_if() is stable, so the relative order of elements that are
* copied is unchanged.
/**
* @brief Copy the elements of a sequence for which a predicate is true.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param result An output iterator.
- * @param pred A predicate.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __result An output iterator.
+ * @param __pred A predicate.
* @return An iterator designating the end of the resulting sequence.
*
- * Copies each element in the range @p [first,last) for which
- * @p pred returns true to the range beginning at @p result.
+ * Copies each element in the range @p [__first,__last) for which
+ * @p __pred returns true to the range beginning at @p __result.
*
* copy_if() is stable, so the relative order of elements that are
* copied is unchanged.
__copy_n(_InputIterator __first, _Size __n,
_OutputIterator __result, input_iterator_tag)
{
- for (; __n > 0; --__n)
+ if (__n > 0)
{
- *__result = *__first;
- ++__first;
- ++__result;
+ while (true)
+ {
+ *__result = *__first;
+ ++__result;
+ if (--__n > 0)
+ ++__first;
+ else
+ break;
+ }
}
return __result;
}
/**
* @brief Copies the range [first,first+n) into [result,result+n).
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param n The number of elements to copy.
- * @param result An output iterator.
+ * @param __first An input iterator.
+ * @param __n The number of elements to copy.
+ * @param __result An output iterator.
* @return result+n.
*
* This inline function will boil down to a call to @c memmove whenever
* @brief Copy the elements of a sequence to separate output sequences
* depending on the truth value of a predicate.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param out_true An output iterator.
- * @param out_false An output iterator.
- * @param pred A predicate.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __out_true An output iterator.
+ * @param __out_false An output iterator.
+ * @param __pred A predicate.
* @return A pair designating the ends of the resulting sequences.
*
- * Copies each element in the range @p [first,last) for which
- * @p pred returns true to the range beginning at @p out_true
- * and each element for which @p pred returns false to @p out_false.
+ * Copies each element in the range @p [__first,__last) for which
+ * @p __pred returns true to the range beginning at @p out_true
+ * and each element for which @p __pred returns false to @p __out_false.
*/
template<typename _InputIterator, typename _OutputIterator1,
typename _OutputIterator2, typename _Predicate>
/**
* @brief Remove elements from a sequence.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param value The value to be removed.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __value The value to be removed.
* @return An iterator designating the end of the resulting sequence.
*
- * All elements equal to @p value are removed from the range
- * @p [first,last).
+ * All elements equal to @p __value are removed from the range
+ * @p [__first,__last).
*
* remove() is stable, so the relative order of elements that are
* not removed is unchanged.
*
- * Elements between the end of the resulting sequence and @p last
+ * Elements between the end of the resulting sequence and @p __last
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator, typename _Tp>
/**
* @brief Remove elements from a sequence using a predicate.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param pred A predicate.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __pred A predicate.
* @return An iterator designating the end of the resulting sequence.
*
- * All elements for which @p pred returns true are removed from the range
- * @p [first,last).
+ * All elements for which @p __pred returns true are removed from the range
+ * @p [__first,__last).
*
* remove_if() is stable, so the relative order of elements that are
* not removed is unchanged.
*
- * Elements between the end of the resulting sequence and @p last
+ * Elements between the end of the resulting sequence and @p __last
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator, typename _Predicate>
/**
* @brief Remove consecutive duplicate values from a sequence.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
* @return An iterator designating the end of the resulting sequence.
*
* Removes all but the first element from each group of consecutive
* values that compare equal.
* unique() is stable, so the relative order of elements that are
* not removed is unchanged.
- * Elements between the end of the resulting sequence and @p last
+ * Elements between the end of the resulting sequence and @p __last
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator>
/**
* @brief Remove consecutive values from a sequence using a predicate.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param binary_pred A binary predicate.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __binary_pred A binary predicate.
* @return An iterator designating the end of the resulting sequence.
*
* Removes all but the first element from each group of consecutive
- * values for which @p binary_pred returns true.
+ * values for which @p __binary_pred returns true.
* unique() is stable, so the relative order of elements that are
* not removed is unchanged.
- * Elements between the end of the resulting sequence and @p last
+ * Elements between the end of the resulting sequence and @p __last
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator, typename _BinaryPredicate>
/**
* @brief Reverse a sequence.
* @ingroup mutating_algorithms
- * @param first A bidirectional iterator.
- * @param last A bidirectional iterator.
+ * @param __first A bidirectional iterator.
+ * @param __last A bidirectional iterator.
* @return reverse() returns no value.
*
- * Reverses the order of the elements in the range @p [first,last),
+ * Reverses the order of the elements in the range @p [__first,__last),
* so that the first element becomes the last etc.
- * For every @c i such that @p 0<=i<=(last-first)/2), @p reverse()
- * swaps @p *(first+i) and @p *(last-(i+1))
+ * For every @c i such that @p 0<=i<=(__last-__first)/2), @p reverse()
+ * swaps @p *(__first+i) and @p *(__last-(i+1))
*/
template<typename _BidirectionalIterator>
inline void
/**
* @brief Copy a sequence, reversing its elements.
* @ingroup mutating_algorithms
- * @param first A bidirectional iterator.
- * @param last A bidirectional iterator.
- * @param result An output iterator.
+ * @param __first A bidirectional iterator.
+ * @param __last A bidirectional iterator.
+ * @param __result An output iterator.
* @return An iterator designating the end of the resulting sequence.
*
- * Copies the elements in the range @p [first,last) to the range
- * @p [result,result+(last-first)) such that the order of the
- * elements is reversed.
- * For every @c i such that @p 0<=i<=(last-first), @p reverse_copy()
- * performs the assignment @p *(result+(last-first)-i) = *(first+i).
- * The ranges @p [first,last) and @p [result,result+(last-first))
- * must not overlap.
+ * Copies the elements in the range @p [__first,__last) to the
+ * range @p [__result,__result+(__last-__first)) such that the
+ * order of the elements is reversed. For every @c i such that @p
+ * 0<=i<=(__last-__first), @p reverse_copy() performs the
+ * assignment @p *(__result+(__last-__first)-i) = *(__first+i).
+ * The ranges @p [__first,__last) and @p
+ * [__result,__result+(__last-__first)) must not overlap.
*/
template<typename _BidirectionalIterator, typename _OutputIterator>
_OutputIterator
/**
* @brief Rotate the elements of a sequence.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param middle A forward iterator.
- * @param last A forward iterator.
+ * @param __first A forward iterator.
+ * @param __middle A forward iterator.
+ * @param __last A forward iterator.
* @return Nothing.
*
- * Rotates the elements of the range @p [first,last) by @p (middle-first)
- * positions so that the element at @p middle is moved to @p first, the
- * element at @p middle+1 is moved to @first+1 and so on for each element
- * in the range @p [first,last).
+ * Rotates the elements of the range @p [__first,__last) by
+ * @p (__middle - __first) positions so that the element at @p __middle
+ * is moved to @p __first, the element at @p __middle+1 is moved to
+ * @p __first+1 and so on for each element in the range
+ * @p [__first,__last).
*
- * This effectively swaps the ranges @p [first,middle) and
- * @p [middle,last).
+ * This effectively swaps the ranges @p [__first,__middle) and
+ * @p [__middle,__last).
*
- * Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for
- * each @p n in the range @p [0,last-first).
+ * Performs
+ * @p *(__first+(n+(__last-__middle))%(__last-__first))=*(__first+n)
+ * for each @p n in the range @p [0,__last-__first).
*/
template<typename _ForwardIterator>
inline void
/**
* @brief Copy a sequence, rotating its elements.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param middle A forward iterator.
- * @param last A forward iterator.
- * @param result An output iterator.
+ * @param __first A forward iterator.
+ * @param __middle A forward iterator.
+ * @param __last A forward iterator.
+ * @param __result An output iterator.
* @return An iterator designating the end of the resulting sequence.
*
- * Copies the elements of the range @p [first,last) to the range
- * beginning at @result, rotating the copied elements by @p (middle-first)
- * positions so that the element at @p middle is moved to @p result, the
- * element at @p middle+1 is moved to @result+1 and so on for each element
- * in the range @p [first,last).
+ * Copies the elements of the range @p [__first,__last) to the
+ * range beginning at @result, rotating the copied elements by
+ * @p (__middle-__first) positions so that the element at @p __middle
+ * is moved to @p __result, the element at @p __middle+1 is moved
+ * to @p __result+1 and so on for each element in the range @p
+ * [__first,__last).
*
- * Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for
- * each @p n in the range @p [0,last-first).
+ * Performs
+ * @p *(__result+(n+(__last-__middle))%(__last-__first))=*(__first+n)
+ * for each @p n in the range @p [0,__last-__first).
*/
template<typename _ForwardIterator, typename _OutputIterator>
_OutputIterator
// partition
/// This is a helper function...
+ /// Requires __len != 0 and !__pred(*__first),
+ /// same as __stable_partition_adaptive.
template<typename _ForwardIterator, typename _Predicate, typename _Distance>
_ForwardIterator
__inplace_stable_partition(_ForwardIterator __first,
- _ForwardIterator __last,
_Predicate __pred, _Distance __len)
{
if (__len == 1)
- return __pred(*__first) ? __last : __first;
+ return __first;
_ForwardIterator __middle = __first;
std::advance(__middle, __len / 2);
- _ForwardIterator __begin = std::__inplace_stable_partition(__first,
- __middle,
- __pred,
- __len / 2);
- _ForwardIterator __end = std::__inplace_stable_partition(__middle, __last,
- __pred,
- __len
- - __len / 2);
- std::rotate(__begin, __middle, __end);
- std::advance(__begin, std::distance(__middle, __end));
- return __begin;
+ _ForwardIterator __left_split =
+ std::__inplace_stable_partition(__first, __pred, __len / 2);
+ // Advance past true-predicate values to satisfy this
+ // function's preconditions.
+ _Distance __right_len = __len - __len / 2;
+ _ForwardIterator __right_split =
+ std::__find_if_not_n(__middle, __right_len, __pred);
+ if (__right_len)
+ __right_split = std::__inplace_stable_partition(__middle,
+ __pred,
+ __right_len);
+ std::rotate(__left_split, __middle, __right_split);
+ std::advance(__left_split, std::distance(__middle, __right_split));
+ return __left_split;
}
/// This is a helper function...
+ /// Requires __first != __last and !__pred(*__first)
+ /// and __len == distance(__first, __last).
+ ///
+ /// !__pred(*__first) allows us to guarantee that we don't
+ /// move-assign an element onto itself.
template<typename _ForwardIterator, typename _Pointer, typename _Predicate,
typename _Distance>
_ForwardIterator
{
_ForwardIterator __result1 = __first;
_Pointer __result2 = __buffer;
+ // The precondition guarantees that !__pred(*__first), so
+ // move that element to the buffer before starting the loop.
+ // This ensures that we only call __pred once per element.
+ *__result2 = _GLIBCXX_MOVE(*__first);
+ ++__result2;
+ ++__first;
for (; __first != __last; ++__first)
if (__pred(*__first))
{
- *__result1 = _GLIBCXX_MOVE(*__first);
+ if (__result1 != __first)
+ *__result1 = _GLIBCXX_MOVE(*__first);
++__result1;
}
else
{
_ForwardIterator __middle = __first;
std::advance(__middle, __len / 2);
- _ForwardIterator __begin =
+ _ForwardIterator __left_split =
std::__stable_partition_adaptive(__first, __middle, __pred,
__len / 2, __buffer,
__buffer_size);
- _ForwardIterator __end =
- std::__stable_partition_adaptive(__middle, __last, __pred,
- __len - __len / 2,
- __buffer, __buffer_size);
- std::rotate(__begin, __middle, __end);
- std::advance(__begin, std::distance(__middle, __end));
- return __begin;
+ // Advance past true-predicate values to satisfy this
+ // function's preconditions.
+ _Distance __right_len = __len - __len / 2;
+ _ForwardIterator __right_split =
+ std::__find_if_not_n(__middle, __right_len, __pred);
+ if (__right_len)
+ __right_split =
+ std::__stable_partition_adaptive(__right_split, __last, __pred,
+ __right_len,
+ __buffer, __buffer_size);
+ std::rotate(__left_split, __middle, __right_split);
+ std::advance(__left_split, std::distance(__middle, __right_split));
+ return __left_split;
}
}
* @brief Move elements for which a predicate is true to the beginning
* of a sequence, preserving relative ordering.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param pred A predicate functor.
- * @return An iterator @p middle such that @p pred(i) is true for each
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __pred A predicate functor.
+ * @return An iterator @p middle such that @p __pred(i) is true for each
* iterator @p i in the range @p [first,middle) and false for each @p i
* in the range @p [middle,last).
*
* Performs the same function as @p partition() with the additional
* guarantee that the relative ordering of elements in each group is
* preserved, so any two elements @p x and @p y in the range
- * @p [first,last) such that @p pred(x)==pred(y) will have the same
+ * @p [__first,__last) such that @p __pred(x)==__pred(y) will have the same
* relative ordering after calling @p stable_partition().
*/
template<typename _ForwardIterator, typename _Predicate>
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
+ __first = std::__find_if_not(__first, __last, __pred);
+
if (__first == __last)
return __first;
else
_DistanceType(__buf.size()));
else
return
- std::__inplace_stable_partition(__first, __last, __pred,
+ std::__inplace_stable_partition(__first, __pred,
_DistanceType(__buf.requested_size()));
}
}
/**
* @brief Copy the smallest elements of a sequence.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param result_first A random-access iterator.
- * @param result_last Another random-access iterator.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __result_first A random-access iterator.
+ * @param __result_last Another random-access iterator.
* @return An iterator indicating the end of the resulting sequence.
*
- * Copies and sorts the smallest N values from the range @p [first,last)
- * to the range beginning at @p result_first, where the number of
- * elements to be copied, @p N, is the smaller of @p (last-first) and
- * @p (result_last-result_first).
- * After the sort if @p i and @j are iterators in the range
- * @p [result_first,result_first+N) such that @i precedes @j then
- * @p *j<*i is false.
- * The value returned is @p result_first+N.
+ * Copies and sorts the smallest N values from the range @p [__first,__last)
+ * to the range beginning at @p __result_first, where the number of
+ * elements to be copied, @p N, is the smaller of @p (__last-__first) and
+ * @p (__result_last-__result_first).
+ * After the sort if @e i and @e j are iterators in the range
+ * @p [__result_first,__result_first+N) such that i precedes j then
+ * *j<*i is false.
+ * The value returned is @p __result_first+N.
*/
template<typename _InputIterator, typename _RandomAccessIterator>
_RandomAccessIterator
* @brief Copy the smallest elements of a sequence using a predicate for
* comparison.
* @ingroup sorting_algorithms
- * @param first An input iterator.
- * @param last Another input iterator.
- * @param result_first A random-access iterator.
- * @param result_last Another random-access iterator.
- * @param comp A comparison functor.
+ * @param __first An input iterator.
+ * @param __last Another input iterator.
+ * @param __result_first A random-access iterator.
+ * @param __result_last Another random-access iterator.
+ * @param __comp A comparison functor.
* @return An iterator indicating the end of the resulting sequence.
*
- * Copies and sorts the smallest N values from the range @p [first,last)
+ * Copies and sorts the smallest N values from the range @p [__first,__last)
* to the range beginning at @p result_first, where the number of
- * elements to be copied, @p N, is the smaller of @p (last-first) and
- * @p (result_last-result_first).
- * After the sort if @p i and @j are iterators in the range
- * @p [result_first,result_first+N) such that @i precedes @j then
- * @p comp(*j,*i) is false.
- * The value returned is @p result_first+N.
+ * elements to be copied, @p N, is the smaller of @p (__last-__first) and
+ * @p (__result_last-__result_first).
+ * After the sort if @e i and @e j are iterators in the range
+ * @p [__result_first,__result_first+N) such that i precedes j then
+ * @p __comp(*j,*i) is false.
+ * The value returned is @p __result_first+N.
*/
template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare>
_RandomAccessIterator
_RandomAccessIterator __last)
{
_RandomAccessIterator __mid = __first + (__last - __first) / 2;
- std::__move_median_first(__first, __mid, (__last - 1));
+ std::__move_median_to_first(__first, __first + 1, __mid, __last - 1);
return std::__unguarded_partition(__first + 1, __last, *__first);
}
_RandomAccessIterator __last, _Compare __comp)
{
_RandomAccessIterator __mid = __first + (__last - __first) / 2;
- std::__move_median_first(__first, __mid, (__last - 1), __comp);
+ std::__move_median_to_first(__first, __first + 1, __mid, __last - 1,
+ __comp);
return std::__unguarded_partition(__first + 1, __last, *__first, __comp);
}
// lower_bound moved to stl_algobase.h
/**
- * @brief Finds the first position in which @a val could be inserted
+ * @brief Finds the first position in which @p __val could be inserted
* without changing the ordering.
* @ingroup binary_search_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param val The search term.
- * @param comp A functor to use for comparisons.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __val The search term.
+ * @param __comp A functor to use for comparisons.
* @return An iterator pointing to the first element <em>not less
- * than</em> @a val, or end() if every element is less
- * than @a val.
+ * than</em> @p __val, or end() if every element is less
+ * than @p __val.
* @ingroup binary_search_algorithms
*
* The comparison function should have the same effects on ordering as
}
/**
- * @brief Finds the last position in which @a val could be inserted
+ * @brief Finds the last position in which @p __val could be inserted
* without changing the ordering.
* @ingroup binary_search_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param val The search term.
- * @return An iterator pointing to the first element greater than @a val,
- * or end() if no elements are greater than @a val.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __val The search term.
+ * @return An iterator pointing to the first element greater than @p __val,
+ * or end() if no elements are greater than @p __val.
* @ingroup binary_search_algorithms
*/
template<typename _ForwardIterator, typename _Tp>
}
/**
- * @brief Finds the last position in which @a val could be inserted
+ * @brief Finds the last position in which @p __val could be inserted
* without changing the ordering.
* @ingroup binary_search_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param val The search term.
- * @param comp A functor to use for comparisons.
- * @return An iterator pointing to the first element greater than @a val,
- * or end() if no elements are greater than @a val.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __val The search term.
+ * @param __comp A functor to use for comparisons.
+ * @return An iterator pointing to the first element greater than @p __val,
+ * or end() if no elements are greater than @p __val.
* @ingroup binary_search_algorithms
*
* The comparison function should have the same effects on ordering as
}
/**
- * @brief Finds the largest subrange in which @a val could be inserted
+ * @brief Finds the largest subrange in which @p __val could be inserted
* at any place in it without changing the ordering.
* @ingroup binary_search_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param val The search term.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __val The search term.
* @return An pair of iterators defining the subrange.
* @ingroup binary_search_algorithms
*
* This is equivalent to
* @code
- * std::make_pair(lower_bound(first, last, val),
- * upper_bound(first, last, val))
+ * std::make_pair(lower_bound(__first, __last, __val),
+ * upper_bound(__first, __last, __val))
* @endcode
* but does not actually call those functions.
*/
}
/**
- * @brief Finds the largest subrange in which @a val could be inserted
+ * @brief Finds the largest subrange in which @p __val could be inserted
* at any place in it without changing the ordering.
- * @param first An iterator.
- * @param last Another iterator.
- * @param val The search term.
- * @param comp A functor to use for comparisons.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __val The search term.
+ * @param __comp A functor to use for comparisons.
* @return An pair of iterators defining the subrange.
* @ingroup binary_search_algorithms
*
* This is equivalent to
* @code
- * std::make_pair(lower_bound(first, last, val, comp),
- * upper_bound(first, last, val, comp))
+ * std::make_pair(lower_bound(__first, __last, __val, __comp),
+ * upper_bound(__first, __last, __val, __comp))
* @endcode
* but does not actually call those functions.
*/
/**
* @brief Determines whether an element exists in a range.
* @ingroup binary_search_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param val The search term.
- * @return True if @a val (or its equivalent) is in [@a first,@a last ].
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __val The search term.
+ * @return True if @p __val (or its equivalent) is in [@p
+ * __first,@p __last ].
*
- * Note that this does not actually return an iterator to @a val. For
+ * Note that this does not actually return an iterator to @p __val. For
* that, use std::find or a container's specialized find member functions.
*/
template<typename _ForwardIterator, typename _Tp>
/**
* @brief Determines whether an element exists in a range.
* @ingroup binary_search_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param val The search term.
- * @param comp A functor to use for comparisons.
- * @return True if @a val (or its equivalent) is in [@a first,@a last ].
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __val The search term.
+ * @param __comp A functor to use for comparisons.
+ * @return True if @p __val (or its equivalent) is in @p [__first,__last].
*
- * Note that this does not actually return an iterator to @a val. For
+ * Note that this does not actually return an iterator to @p __val. For
* that, use std::find or a container's specialized find member functions.
*
* The comparison function should have the same effects on ordering as
/**
* @brief Merges two sorted ranges in place.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param middle Another iterator.
- * @param last Another iterator.
+ * @param __first An iterator.
+ * @param __middle Another iterator.
+ * @param __last Another iterator.
* @return Nothing.
*
- * Merges two sorted and consecutive ranges, [first,middle) and
- * [middle,last), and puts the result in [first,last). The output will
- * be sorted. The sort is @e stable, that is, for equivalent
- * elements in the two ranges, elements from the first range will always
- * come before elements from the second.
+ * Merges two sorted and consecutive ranges, [__first,__middle) and
+ * [__middle,__last), and puts the result in [__first,__last). The
+ * output will be sorted. The sort is @e stable, that is, for
+ * equivalent elements in the two ranges, elements from the first
+ * range will always come before elements from the second.
*
- * If enough additional memory is available, this takes (last-first)-1
+ * If enough additional memory is available, this takes (__last-__first)-1
* comparisons. Otherwise an NlogN algorithm is used, where N is
- * distance(first,last).
+ * distance(__first,__last).
*/
template<typename _BidirectionalIterator>
void
/**
* @brief Merges two sorted ranges in place.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param middle Another iterator.
- * @param last Another iterator.
- * @param comp A functor to use for comparisons.
+ * @param __first An iterator.
+ * @param __middle Another iterator.
+ * @param __last Another iterator.
+ * @param __comp A functor to use for comparisons.
* @return Nothing.
*
- * Merges two sorted and consecutive ranges, [first,middle) and
- * [middle,last), and puts the result in [first,last). The output will
+ * Merges two sorted and consecutive ranges, [__first,__middle) and
+ * [middle,last), and puts the result in [__first,__last). The output will
* be sorted. The sort is @e stable, that is, for equivalent
* elements in the two ranges, elements from the first range will always
* come before elements from the second.
*
- * If enough additional memory is available, this takes (last-first)-1
+ * If enough additional memory is available, this takes (__last-__first)-1
* comparisons. Otherwise an NlogN algorithm is used, where N is
- * distance(first,last).
+ * distance(__first,__last).
*
* The comparison function should have the same effects on ordering as
* the function used for the initial sort.
/**
* @brief Determines whether all elements of a sequence exists in a range.
- * @param first1 Start of search range.
- * @param last1 End of search range.
- * @param first2 Start of sequence
- * @param last2 End of sequence.
- * @return True if each element in [first2,last2) is contained in order
- * within [first1,last1). False otherwise.
+ * @param __first1 Start of search range.
+ * @param __last1 End of search range.
+ * @param __first2 Start of sequence
+ * @param __last2 End of sequence.
+ * @return True if each element in [__first2,__last2) is contained in order
+ * within [__first1,__last1). False otherwise.
* @ingroup set_algorithms
*
- * This operation expects both [first1,last1) and [first2,last2) to be
- * sorted. Searches for the presence of each element in [first2,last2)
- * within [first1,last1). The iterators over each range only move forward,
- * so this is a linear algorithm. If an element in [first2,last2) is not
- * found before the search iterator reaches @a last2, false is returned.
+ * This operation expects both [__first1,__last1) and
+ * [__first2,__last2) to be sorted. Searches for the presence of
+ * each element in [__first2,__last2) within [__first1,__last1).
+ * The iterators over each range only move forward, so this is a
+ * linear algorithm. If an element in [__first2,__last2) is not
+ * found before the search iterator reaches @p __last2, false is
+ * returned.
*/
template<typename _InputIterator1, typename _InputIterator2>
bool
* @brief Determines whether all elements of a sequence exists in a range
* using comparison.
* @ingroup set_algorithms
- * @param first1 Start of search range.
- * @param last1 End of search range.
- * @param first2 Start of sequence
- * @param last2 End of sequence.
- * @param comp Comparison function to use.
- * @return True if each element in [first2,last2) is contained in order
- * within [first1,last1) according to comp. False otherwise.
- * @ingroup set_algorithms
+ * @param __first1 Start of search range.
+ * @param __last1 End of search range.
+ * @param __first2 Start of sequence
+ * @param __last2 End of sequence.
+ * @param __comp Comparison function to use.
+ * @return True if each element in [__first2,__last2) is contained
+ * in order within [__first1,__last1) according to comp. False
+ * otherwise. @ingroup set_algorithms
*
- * This operation expects both [first1,last1) and [first2,last2) to be
- * sorted. Searches for the presence of each element in [first2,last2)
- * within [first1,last1), using comp to decide. The iterators over each
- * range only move forward, so this is a linear algorithm. If an element
- * in [first2,last2) is not found before the search iterator reaches @a
- * last2, false is returned.
+ * This operation expects both [__first1,__last1) and
+ * [__first2,__last2) to be sorted. Searches for the presence of
+ * each element in [__first2,__last2) within [__first1,__last1),
+ * using comp to decide. The iterators over each range only move
+ * forward, so this is a linear algorithm. If an element in
+ * [__first2,__last2) is not found before the search iterator
+ * reaches @p __last2, false is returned.
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _Compare>
// max_element
/**
- * @brief Permute range into the next @a dictionary ordering.
+ * @brief Permute range into the next @e dictionary ordering.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
+ * @param __first Start of range.
+ * @param __last End of range.
* @return False if wrapped to first permutation, true otherwise.
*
- * Treats all permutations of the range as a set of @a dictionary sorted
+ * Treats all permutations of the range as a set of @e dictionary sorted
* sequences. Permutes the current sequence into the next one of this set.
* Returns true if there are more sequences to generate. If the sequence
* is the largest of the set, the smallest is generated and false returned.
}
/**
- * @brief Permute range into the next @a dictionary ordering using
+ * @brief Permute range into the next @e dictionary ordering using
* comparison functor.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
- * @param comp A comparison functor.
+ * @param __first Start of range.
+ * @param __last End of range.
+ * @param __comp A comparison functor.
* @return False if wrapped to first permutation, true otherwise.
*
- * Treats all permutations of the range [first,last) as a set of
- * @a dictionary sorted sequences ordered by @a comp. Permutes the current
+ * Treats all permutations of the range [__first,__last) as a set of
+ * @e dictionary sorted sequences ordered by @p __comp. Permutes the current
* sequence into the next one of this set. Returns true if there are more
* sequences to generate. If the sequence is the largest of the set, the
* smallest is generated and false returned.
}
/**
- * @brief Permute range into the previous @a dictionary ordering.
+ * @brief Permute range into the previous @e dictionary ordering.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
+ * @param __first Start of range.
+ * @param __last End of range.
* @return False if wrapped to last permutation, true otherwise.
*
- * Treats all permutations of the range as a set of @a dictionary sorted
+ * Treats all permutations of the range as a set of @e dictionary sorted
* sequences. Permutes the current sequence into the previous one of this
* set. Returns true if there are more sequences to generate. If the
* sequence is the smallest of the set, the largest is generated and false
}
/**
- * @brief Permute range into the previous @a dictionary ordering using
+ * @brief Permute range into the previous @e dictionary ordering using
* comparison functor.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
- * @param comp A comparison functor.
+ * @param __first Start of range.
+ * @param __last End of range.
+ * @param __comp A comparison functor.
* @return False if wrapped to last permutation, true otherwise.
*
- * Treats all permutations of the range [first,last) as a set of
- * @a dictionary sorted sequences ordered by @a comp. Permutes the current
+ * Treats all permutations of the range [__first,__last) as a set of
+ * @e dictionary sorted sequences ordered by @p __comp. Permutes the current
* sequence into the previous one of this set. Returns true if there are
* more sequences to generate. If the sequence is the smallest of the set,
* the largest is generated and false returned.
/**
* @brief Copy a sequence, replacing each element of one value with another
* value.
- * @param first An input iterator.
- * @param last An input iterator.
- * @param result An output iterator.
- * @param old_value The value to be replaced.
- * @param new_value The replacement value.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __result An output iterator.
+ * @param __old_value The value to be replaced.
+ * @param __new_value The replacement value.
* @return The end of the output sequence, @p result+(last-first).
*
- * Copies each element in the input range @p [first,last) to the
- * output range @p [result,result+(last-first)) replacing elements
- * equal to @p old_value with @p new_value.
+ * Copies each element in the input range @p [__first,__last) to the
+ * output range @p [__result,__result+(__last-__first)) replacing elements
+ * equal to @p __old_value with @p __new_value.
*/
template<typename _InputIterator, typename _OutputIterator, typename _Tp>
_OutputIterator
* @brief Copy a sequence, replacing each value for which a predicate
* returns true with another value.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param result An output iterator.
- * @param pred A predicate.
- * @param new_value The replacement value.
- * @return The end of the output sequence, @p result+(last-first).
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __result An output iterator.
+ * @param __pred A predicate.
+ * @param __new_value The replacement value.
+ * @return The end of the output sequence, @p __result+(__last-__first).
*
- * Copies each element in the range @p [first,last) to the range
- * @p [result,result+(last-first)) replacing elements for which
- * @p pred returns true with @p new_value.
+ * Copies each element in the range @p [__first,__last) to the range
+ * @p [__result,__result+(__last-__first)) replacing elements for which
+ * @p __pred returns true with @p __new_value.
*/
template<typename _InputIterator, typename _OutputIterator,
typename _Predicate, typename _Tp>
/**
* @brief Determines whether the elements of a sequence are sorted.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
+ * @param __first An iterator.
+ * @param __last Another iterator.
* @return True if the elements are sorted, false otherwise.
*/
template<typename _ForwardIterator>
* @brief Determines whether the elements of a sequence are sorted
* according to a comparison functor.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param comp A comparison functor.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __comp A comparison functor.
* @return True if the elements are sorted, false otherwise.
*/
template<typename _ForwardIterator, typename _Compare>
/**
* @brief Determines the end of a sorted sequence.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @return An iterator pointing to the last iterator i in [first, last)
- * for which the range [first, i) is sorted.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @return An iterator pointing to the last iterator i in [__first, __last)
+ * for which the range [__first, i) is sorted.
*/
template<typename _ForwardIterator>
_ForwardIterator
/**
* @brief Determines the end of a sorted sequence using comparison functor.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param comp A comparison functor.
- * @return An iterator pointing to the last iterator i in [first, last)
- * for which the range [first, i) is sorted.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __comp A comparison functor.
+ * @return An iterator pointing to the last iterator i in [__first, __last)
+ * for which the range [__first, i) is sorted.
*/
template<typename _ForwardIterator, typename _Compare>
_ForwardIterator
/**
* @brief Determines min and max at once as an ordered pair.
* @ingroup sorting_algorithms
- * @param a A thing of arbitrary type.
- * @param b Another thing of arbitrary type.
- * @return A pair(b, a) if b is smaller than a, pair(a, b) otherwise.
+ * @param __a A thing of arbitrary type.
+ * @param __b Another thing of arbitrary type.
+ * @return A pair(__b, __a) if __b is smaller than __a, pair(__a,
+ * __b) otherwise.
*/
template<typename _Tp>
inline pair<const _Tp&, const _Tp&>
/**
* @brief Determines min and max at once as an ordered pair.
* @ingroup sorting_algorithms
- * @param a A thing of arbitrary type.
- * @param b Another thing of arbitrary type.
- * @param comp A @link comparison_functor comparison functor@endlink.
- * @return A pair(b, a) if b is smaller than a, pair(a, b) otherwise.
+ * @param __a A thing of arbitrary type.
+ * @param __b Another thing of arbitrary type.
+ * @param __comp A @link comparison_functors comparison functor @endlink.
+ * @return A pair(__b, __a) if __b is smaller than __a, pair(__a,
+ * __b) otherwise.
*/
template<typename _Tp, typename _Compare>
inline pair<const _Tp&, const _Tp&>
* @brief Return a pair of iterators pointing to the minimum and maximum
* elements in a range.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
+ * @param __first Start of range.
+ * @param __last End of range.
* @return make_pair(m, M), where m is the first iterator i in
- * [first, last) such that no other element in the range is
- * smaller, and where M is the last iterator i in [first, last)
+ * [__first, __last) such that no other element in the range is
+ * smaller, and where M is the last iterator i in [__first, __last)
* such that no other element in the range is larger.
*/
template<typename _ForwardIterator>
* @brief Return a pair of iterators pointing to the minimum and maximum
* elements in a range.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
- * @param comp Comparison functor.
+ * @param __first Start of range.
+ * @param __last End of range.
+ * @param __comp Comparison functor.
* @return make_pair(m, M), where m is the first iterator i in
- * [first, last) such that no other element in the range is
- * smaller, and where M is the last iterator i in [first, last)
+ * [__first, __last) such that no other element in the range is
+ * smaller, and where M is the last iterator i in [__first, __last)
* such that no other element in the range is larger.
*/
template<typename _ForwardIterator, typename _Compare>
* @brief Checks whether a permutaion of the second sequence is equal
* to the first sequence.
* @ingroup non_mutating_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
* @return true if there exists a permutation of the elements in the range
- * [first2, first2 + (last1 - first1)), beginning with
- * ForwardIterator2 begin, such that equal(first1, last1, begin)
+ * [__first2, __first2 + (__last1 - __first1)), beginning with
+ * ForwardIterator2 begin, such that equal(__first1, __last1, begin)
* returns true; otherwise, returns false.
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
* @brief Checks whether a permutation of the second sequence is equal
* to the first sequence.
* @ingroup non_mutating_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param pred A binary predicate.
- * @return true if there exists a permutation of the elements in the range
- * [first2, first2 + (last1 - first1)), beginning with
- * ForwardIterator2 begin, such that equal(first1, last1, begin,
- * pred) returns true; otherwise, returns false.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __pred A binary predicate.
+ * @return true if there exists a permutation of the elements in
+ * the range [__first2, __first2 + (__last1 - __first1)),
+ * beginning with ForwardIterator2 begin, such that
+ * equal(__first1, __last1, __begin, __pred) returns true;
+ * otherwise, returns false.
*/
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
* @brief Shuffle the elements of a sequence using a uniform random
* number generator.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param g A UniformRandomNumberGenerator (26.5.1.3).
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __g A UniformRandomNumberGenerator (26.5.1.3).
* @return Nothing.
*
- * Reorders the elements in the range @p [first,last) using @p g to
+ * Reorders the elements in the range @p [__first,__last) using @p __g to
* provide random numbers.
*/
template<typename _RandomAccessIterator,
/**
* @brief Apply a function to every element of a sequence.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param f A unary function object.
- * @return @p f (std::move(@p f) in C++0x).
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __f A unary function object.
+ * @return @p __f (std::move(@p __f) in C++0x).
*
- * Applies the function object @p f to each element in the range
- * @p [first,last). @p f must not modify the order of the sequence.
- * If @p f has a return value it is ignored.
+ * Applies the function object @p __f to each element in the range
+ * @p [first,last). @p __f must not modify the order of the sequence.
+ * If @p __f has a return value it is ignored.
*/
template<typename _InputIterator, typename _Function>
_Function
/**
* @brief Find the first occurrence of a value in a sequence.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param val The value to find.
- * @return The first iterator @c i in the range @p [first,last)
- * such that @c *i == @p val, or @p last if no such iterator exists.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __val The value to find.
+ * @return The first iterator @c i in the range @p [__first,__last)
+ * such that @c *i == @p __val, or @p __last if no such iterator exists.
*/
template<typename _InputIterator, typename _Tp>
inline _InputIterator
* @brief Find the first element in a sequence for which a
* predicate is true.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param pred A predicate.
- * @return The first iterator @c i in the range @p [first,last)
- * such that @p pred(*i) is true, or @p last if no such iterator exists.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __pred A predicate.
+ * @return The first iterator @c i in the range @p [__first,__last)
+ * such that @p __pred(*i) is true, or @p __last if no such iterator exists.
*/
template<typename _InputIterator, typename _Predicate>
inline _InputIterator
/**
* @brief Find element from a set in a sequence.
* @ingroup non_mutating_algorithms
- * @param first1 Start of range to search.
- * @param last1 End of range to search.
- * @param first2 Start of match candidates.
- * @param last2 End of match candidates.
+ * @param __first1 Start of range to search.
+ * @param __last1 End of range to search.
+ * @param __first2 Start of match candidates.
+ * @param __last2 End of match candidates.
* @return The first iterator @c i in the range
- * @p [first1,last1) such that @c *i == @p *(i2) such that i2 is an
- * iterator in [first2,last2), or @p last1 if no such iterator exists.
+ * @p [__first1,__last1) such that @c *i == @p *(i2) such that i2 is an
+ * iterator in [__first2,__last2), or @p __last1 if no such iterator exists.
*
- * Searches the range @p [first1,last1) for an element that is equal to
- * some element in the range [first2,last2). If found, returns an iterator
- * in the range [first1,last1), otherwise returns @p last1.
+ * Searches the range @p [__first1,__last1) for an element that is
+ * equal to some element in the range [__first2,__last2). If
+ * found, returns an iterator in the range [__first1,__last1),
+ * otherwise returns @p __last1.
*/
template<typename _InputIterator, typename _ForwardIterator>
_InputIterator
/**
* @brief Find element from a set in a sequence using a predicate.
* @ingroup non_mutating_algorithms
- * @param first1 Start of range to search.
- * @param last1 End of range to search.
- * @param first2 Start of match candidates.
- * @param last2 End of match candidates.
- * @param comp Predicate to use.
+ * @param __first1 Start of range to search.
+ * @param __last1 End of range to search.
+ * @param __first2 Start of match candidates.
+ * @param __last2 End of match candidates.
+ * @param __comp Predicate to use.
* @return The first iterator @c i in the range
- * @p [first1,last1) such that @c comp(*i, @p *(i2)) is true and i2 is an
- * iterator in [first2,last2), or @p last1 if no such iterator exists.
+ * @p [__first1,__last1) such that @c comp(*i, @p *(i2)) is true
+ * and i2 is an iterator in [__first2,__last2), or @p __last1 if no
+ * such iterator exists.
*
- * Searches the range @p [first1,last1) for an element that is
- * equal to some element in the range [first2,last2). If found,
- * returns an iterator in the range [first1,last1), otherwise
- * returns @p last1.
+ * Searches the range @p [__first1,__last1) for an element that is
+ * equal to some element in the range [__first2,__last2). If
+ * found, returns an iterator in the range [__first1,__last1),
+ * otherwise returns @p __last1.
*/
template<typename _InputIterator, typename _ForwardIterator,
typename _BinaryPredicate>
/**
* @brief Find two adjacent values in a sequence that are equal.
* @ingroup non_mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
* @return The first iterator @c i such that @c i and @c i+1 are both
- * valid iterators in @p [first,last) and such that @c *i == @c *(i+1),
- * or @p last if no such iterator exists.
+ * valid iterators in @p [__first,__last) and such that @c *i == @c *(i+1),
+ * or @p __last if no such iterator exists.
*/
template<typename _ForwardIterator>
_ForwardIterator
/**
* @brief Find two adjacent values in a sequence using a predicate.
* @ingroup non_mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param binary_pred A binary predicate.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __binary_pred A binary predicate.
* @return The first iterator @c i such that @c i and @c i+1 are both
- * valid iterators in @p [first,last) and such that
- * @p binary_pred(*i,*(i+1)) is true, or @p last if no such iterator
+ * valid iterators in @p [__first,__last) and such that
+ * @p __binary_pred(*i,*(i+1)) is true, or @p __last if no such iterator
* exists.
*/
template<typename _ForwardIterator, typename _BinaryPredicate>
/**
* @brief Count the number of copies of a value in a sequence.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param value The value to be counted.
- * @return The number of iterators @c i in the range @p [first,last)
- * for which @c *i == @p value
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __value The value to be counted.
+ * @return The number of iterators @c i in the range @p [__first,__last)
+ * for which @c *i == @p __value
*/
template<typename _InputIterator, typename _Tp>
typename iterator_traits<_InputIterator>::difference_type
/**
* @brief Count the elements of a sequence for which a predicate is true.
* @ingroup non_mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param pred A predicate.
- * @return The number of iterators @c i in the range @p [first,last)
- * for which @p pred(*i) is true.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __pred A predicate.
+ * @return The number of iterators @c i in the range @p [__first,__last)
+ * for which @p __pred(*i) is true.
*/
template<typename _InputIterator, typename _Predicate>
typename iterator_traits<_InputIterator>::difference_type
/**
* @brief Search a sequence for a matching sub-sequence.
* @ingroup non_mutating_algorithms
- * @param first1 A forward iterator.
- * @param last1 A forward iterator.
- * @param first2 A forward iterator.
- * @param last2 A forward iterator.
- * @return The first iterator @c i in the range
- * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N)
- * for each @c N in the range @p [0,last2-first2), or @p last1 if no
- * such iterator exists.
+ * @param __first1 A forward iterator.
+ * @param __last1 A forward iterator.
+ * @param __first2 A forward iterator.
+ * @param __last2 A forward iterator.
+ * @return The first iterator @c i in the range @p
+ * [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == @p
+ * *(__first2+N) for each @c N in the range @p
+ * [0,__last2-__first2), or @p __last1 if no such iterator exists.
+ *
+ * Searches the range @p [__first1,__last1) for a sub-sequence that
+ * compares equal value-by-value with the sequence given by @p
+ * [__first2,__last2) and returns an iterator to the first element
+ * of the sub-sequence, or @p __last1 if the sub-sequence is not
+ * found.
*
- * Searches the range @p [first1,last1) for a sub-sequence that compares
- * equal value-by-value with the sequence given by @p [first2,last2) and
- * returns an iterator to the first element of the sub-sequence, or
- * @p last1 if the sub-sequence is not found.
+ * Because the sub-sequence must lie completely within the range @p
+ * [__first1,__last1) it must start at a position less than @p
+ * __last1-(__last2-__first2) where @p __last2-__first2 is the
+ * length of the sub-sequence.
*
- * Because the sub-sequence must lie completely within the range
- * @p [first1,last1) it must start at a position less than
- * @p last1-(last2-first2) where @p last2-first2 is the length of the
- * sub-sequence.
* This means that the returned iterator @c i will be in the range
- * @p [first1,last1-(last2-first2))
+ * @p [__first1,__last1-(__last2-__first2))
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
_ForwardIterator1
/**
* @brief Search a sequence for a matching sub-sequence using a predicate.
* @ingroup non_mutating_algorithms
- * @param first1 A forward iterator.
- * @param last1 A forward iterator.
- * @param first2 A forward iterator.
- * @param last2 A forward iterator.
- * @param predicate A binary predicate.
+ * @param __first1 A forward iterator.
+ * @param __last1 A forward iterator.
+ * @param __first2 A forward iterator.
+ * @param __last2 A forward iterator.
+ * @param __predicate A binary predicate.
* @return The first iterator @c i in the range
- * @p [first1,last1-(last2-first2)) such that
- * @p predicate(*(i+N),*(first2+N)) is true for each @c N in the range
- * @p [0,last2-first2), or @p last1 if no such iterator exists.
+ * @p [__first1,__last1-(__last2-__first2)) such that
+ * @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range
+ * @p [0,__last2-__first2), or @p __last1 if no such iterator exists.
*
- * Searches the range @p [first1,last1) for a sub-sequence that compares
- * equal value-by-value with the sequence given by @p [first2,last2),
- * using @p predicate to determine equality, and returns an iterator
- * to the first element of the sub-sequence, or @p last1 if no such
- * iterator exists.
+ * Searches the range @p [__first1,__last1) for a sub-sequence that
+ * compares equal value-by-value with the sequence given by @p
+ * [__first2,__last2), using @p __predicate to determine equality,
+ * and returns an iterator to the first element of the
+ * sub-sequence, or @p __last1 if no such iterator exists.
*
* @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2)
*/
/**
* @brief Search a sequence for a number of consecutive values.
* @ingroup non_mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param count The number of consecutive values.
- * @param val The value to find.
- * @return The first iterator @c i in the range @p [first,last-count)
- * such that @c *(i+N) == @p val for each @c N in the range @p [0,count),
- * or @p last if no such iterator exists.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __count The number of consecutive values.
+ * @param __val The value to find.
+ * @return The first iterator @c i in the range @p
+ * [__first,__last-__count) such that @c *(i+N) == @p __val for
+ * each @c N in the range @p [0,__count), or @p __last if no such
+ * iterator exists.
*
- * Searches the range @p [first,last) for @p count consecutive elements
- * equal to @p val.
+ * Searches the range @p [__first,__last) for @p count consecutive elements
+ * equal to @p __val.
*/
template<typename _ForwardIterator, typename _Integer, typename _Tp>
_ForwardIterator
* @brief Search a sequence for a number of consecutive values using a
* predicate.
* @ingroup non_mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param count The number of consecutive values.
- * @param val The value to find.
- * @param binary_pred A binary predicate.
- * @return The first iterator @c i in the range @p [first,last-count)
- * such that @p binary_pred(*(i+N),val) is true for each @c N in the
- * range @p [0,count), or @p last if no such iterator exists.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __count The number of consecutive values.
+ * @param __val The value to find.
+ * @param __binary_pred A binary predicate.
+ * @return The first iterator @c i in the range @p
+ * [__first,__last-__count) such that @p
+ * __binary_pred(*(i+N),__val) is true for each @c N in the range
+ * @p [0,__count), or @p __last if no such iterator exists.
*
- * Searches the range @p [first,last) for @p count consecutive elements
- * for which the predicate returns true.
+ * Searches the range @p [__first,__last) for @p __count
+ * consecutive elements for which the predicate returns true.
*/
template<typename _ForwardIterator, typename _Integer, typename _Tp,
typename _BinaryPredicate>
/**
* @brief Perform an operation on a sequence.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param result An output iterator.
- * @param unary_op A unary operator.
- * @return An output iterator equal to @p result+(last-first).
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __result An output iterator.
+ * @param __unary_op A unary operator.
+ * @return An output iterator equal to @p __result+(__last-__first).
*
* Applies the operator to each element in the input range and assigns
* the results to successive elements of the output sequence.
- * Evaluates @p *(result+N)=unary_op(*(first+N)) for each @c N in the
- * range @p [0,last-first).
+ * Evaluates @p *(__result+N)=unary_op(*(__first+N)) for each @c N in the
+ * range @p [0,__last-__first).
*
* @p unary_op must not alter its argument.
*/
/**
* @brief Perform an operation on corresponding elements of two sequences.
* @ingroup mutating_algorithms
- * @param first1 An input iterator.
- * @param last1 An input iterator.
- * @param first2 An input iterator.
- * @param result An output iterator.
- * @param binary_op A binary operator.
+ * @param __first1 An input iterator.
+ * @param __last1 An input iterator.
+ * @param __first2 An input iterator.
+ * @param __result An output iterator.
+ * @param __binary_op A binary operator.
* @return An output iterator equal to @p result+(last-first).
*
* Applies the operator to the corresponding elements in the two
* input ranges and assigns the results to successive elements of the
* output sequence.
- * Evaluates @p *(result+N)=binary_op(*(first1+N),*(first2+N)) for each
- * @c N in the range @p [0,last1-first1).
+ * Evaluates @p
+ * *(__result+N)=__binary_op(*(__first1+N),*(__first2+N)) for each
+ * @c N in the range @p [0,__last1-__first1).
*
* @p binary_op must not alter either of its arguments.
*/
* @brief Replace each occurrence of one value in a sequence with another
* value.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param old_value The value to be replaced.
- * @param new_value The replacement value.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __old_value The value to be replaced.
+ * @param __new_value The replacement value.
* @return replace() returns no value.
*
- * For each iterator @c i in the range @p [first,last) if @c *i ==
- * @p old_value then the assignment @c *i = @p new_value is performed.
+ * For each iterator @c i in the range @p [__first,__last) if @c *i ==
+ * @p __old_value then the assignment @c *i = @p __new_value is performed.
*/
template<typename _ForwardIterator, typename _Tp>
void
* @brief Replace each value in a sequence for which a predicate returns
* true with another value.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param pred A predicate.
- * @param new_value The replacement value.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __pred A predicate.
+ * @param __new_value The replacement value.
* @return replace_if() returns no value.
*
- * For each iterator @c i in the range @p [first,last) if @p pred(*i)
- * is true then the assignment @c *i = @p new_value is performed.
+ * For each iterator @c i in the range @p [__first,__last) if @p __pred(*i)
+ * is true then the assignment @c *i = @p __new_value is performed.
*/
template<typename _ForwardIterator, typename _Predicate, typename _Tp>
void
* @brief Assign the result of a function object to each value in a
* sequence.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param gen A function object taking no arguments and returning
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __gen A function object taking no arguments and returning
* std::iterator_traits<_ForwardIterator>::value_type
* @return generate() returns no value.
*
- * Performs the assignment @c *i = @p gen() for each @c i in the range
- * @p [first,last).
+ * Performs the assignment @c *i = @p __gen() for each @c i in the range
+ * @p [__first,__last).
*/
template<typename _ForwardIterator, typename _Generator>
void
* @brief Assign the result of a function object to each value in a
* sequence.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param n The length of the sequence.
- * @param gen A function object taking no arguments and returning
+ * @param __first A forward iterator.
+ * @param __n The length of the sequence.
+ * @param __gen A function object taking no arguments and returning
* std::iterator_traits<_ForwardIterator>::value_type
- * @return The end of the sequence, @p first+n
+ * @return The end of the sequence, @p __first+__n
*
- * Performs the assignment @c *i = @p gen() for each @c i in the range
- * @p [first,first+n).
+ * Performs the assignment @c *i = @p __gen() for each @c i in the range
+ * @p [__first,__first+__n).
*
* _GLIBCXX_RESOLVE_LIB_DEFECTS
* DR 865. More algorithms that throw away information
/**
* @brief Copy a sequence, removing consecutive duplicate values.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param result An output iterator.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __result An output iterator.
* @return An iterator designating the end of the resulting sequence.
*
- * Copies each element in the range @p [first,last) to the range
- * beginning at @p result, except that only the first element is copied
+ * Copies each element in the range @p [__first,__last) to the range
+ * beginning at @p __result, except that only the first element is copied
* from groups of consecutive elements that compare equal.
* unique_copy() is stable, so the relative order of elements that are
* copied is unchanged.
/**
* @brief Copy a sequence, removing consecutive values using a predicate.
* @ingroup mutating_algorithms
- * @param first An input iterator.
- * @param last An input iterator.
- * @param result An output iterator.
- * @param binary_pred A binary predicate.
+ * @param __first An input iterator.
+ * @param __last An input iterator.
+ * @param __result An output iterator.
+ * @param __binary_pred A binary predicate.
* @return An iterator designating the end of the resulting sequence.
*
- * Copies each element in the range @p [first,last) to the range
- * beginning at @p result, except that only the first element is copied
- * from groups of consecutive elements for which @p binary_pred returns
+ * Copies each element in the range @p [__first,__last) to the range
+ * beginning at @p __result, except that only the first element is copied
+ * from groups of consecutive elements for which @p __binary_pred returns
* true.
* unique_copy() is stable, so the relative order of elements that are
* copied is unchanged.
/**
* @brief Randomly shuffle the elements of a sequence.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
* @return Nothing.
*
- * Reorder the elements in the range @p [first,last) using a random
+ * Reorder the elements in the range @p [__first,__last) using a random
* distribution, so that every possible ordering of the sequence is
* equally likely.
*/
* @brief Shuffle the elements of a sequence using a random number
* generator.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param rand The RNG functor or function.
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __rand The RNG functor or function.
* @return Nothing.
*
- * Reorders the elements in the range @p [first,last) using @p rand to
- * provide a random distribution. Calling @p rand(N) for a positive
+ * Reorders the elements in the range @p [__first,__last) using @p __rand to
+ * provide a random distribution. Calling @p __rand(N) for a positive
* integer @p N should return a randomly chosen integer from the
* range [0,N).
*/
* @brief Move elements for which a predicate is true to the beginning
* of a sequence.
* @ingroup mutating_algorithms
- * @param first A forward iterator.
- * @param last A forward iterator.
- * @param pred A predicate functor.
- * @return An iterator @p middle such that @p pred(i) is true for each
- * iterator @p i in the range @p [first,middle) and false for each @p i
- * in the range @p [middle,last).
+ * @param __first A forward iterator.
+ * @param __last A forward iterator.
+ * @param __pred A predicate functor.
+ * @return An iterator @p middle such that @p __pred(i) is true for each
+ * iterator @p i in the range @p [__first,middle) and false for each @p i
+ * in the range @p [middle,__last).
*
- * @p pred must not modify its operand. @p partition() does not preserve
+ * @p __pred must not modify its operand. @p partition() does not preserve
* the relative ordering of elements in each group, use
* @p stable_partition() if this is needed.
*/
/**
* @brief Sort the smallest elements of a sequence.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param middle Another iterator.
- * @param last Another iterator.
+ * @param __first An iterator.
+ * @param __middle Another iterator.
+ * @param __last Another iterator.
* @return Nothing.
*
- * Sorts the smallest @p (middle-first) elements in the range
- * @p [first,last) and moves them to the range @p [first,middle). The
- * order of the remaining elements in the range @p [middle,last) is
+ * Sorts the smallest @p (__middle-__first) elements in the range
+ * @p [first,last) and moves them to the range @p [__first,__middle). The
+ * order of the remaining elements in the range @p [__middle,__last) is
* undefined.
- * After the sort if @p i and @j are iterators in the range
- * @p [first,middle) such that @i precedes @j and @k is an iterator in
- * the range @p [middle,last) then @p *j<*i and @p *k<*i are both false.
+ * After the sort if @e i and @e j are iterators in the range
+ * @p [__first,__middle) such that i precedes j and @e k is an iterator in
+ * the range @p [__middle,__last) then *j<*i and *k<*i are both false.
*/
template<typename _RandomAccessIterator>
inline void
* @brief Sort the smallest elements of a sequence using a predicate
* for comparison.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param middle Another iterator.
- * @param last Another iterator.
- * @param comp A comparison functor.
+ * @param __first An iterator.
+ * @param __middle Another iterator.
+ * @param __last Another iterator.
+ * @param __comp A comparison functor.
* @return Nothing.
*
- * Sorts the smallest @p (middle-first) elements in the range
- * @p [first,last) and moves them to the range @p [first,middle). The
- * order of the remaining elements in the range @p [middle,last) is
+ * Sorts the smallest @p (__middle-__first) elements in the range
+ * @p [__first,__last) and moves them to the range @p [__first,__middle). The
+ * order of the remaining elements in the range @p [__middle,__last) is
* undefined.
- * After the sort if @p i and @j are iterators in the range
- * @p [first,middle) such that @i precedes @j and @k is an iterator in
- * the range @p [middle,last) then @p *comp(j,*i) and @p comp(*k,*i)
+ * After the sort if @e i and @e j are iterators in the range
+ * @p [__first,__middle) such that i precedes j and @e k is an iterator in
+ * the range @p [__middle,__last) then @p *__comp(j,*i) and @p __comp(*k,*i)
* are both false.
*/
template<typename _RandomAccessIterator, typename _Compare>
/**
* @brief Sort a sequence just enough to find a particular position.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param nth Another iterator.
- * @param last Another iterator.
+ * @param __first An iterator.
+ * @param __nth Another iterator.
+ * @param __last Another iterator.
* @return Nothing.
*
- * Rearranges the elements in the range @p [first,last) so that @p *nth
+ * Rearranges the elements in the range @p [__first,__last) so that @p *__nth
* is the same element that would have been in that position had the
- * whole sequence been sorted.
- * whole sequence been sorted. The elements either side of @p *nth are
- * not completely sorted, but for any iterator @i in the range
- * @p [first,nth) and any iterator @j in the range @p [nth,last) it
- * holds that @p *j<*i is false.
+ * whole sequence been sorted. The elements either side of @p *__nth are
+ * not completely sorted, but for any iterator @e i in the range
+ * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it
+ * holds that *j < *i is false.
*/
template<typename _RandomAccessIterator>
inline void
* @brief Sort a sequence just enough to find a particular position
* using a predicate for comparison.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param nth Another iterator.
- * @param last Another iterator.
- * @param comp A comparison functor.
+ * @param __first An iterator.
+ * @param __nth Another iterator.
+ * @param __last Another iterator.
+ * @param __comp A comparison functor.
* @return Nothing.
*
- * Rearranges the elements in the range @p [first,last) so that @p *nth
+ * Rearranges the elements in the range @p [__first,__last) so that @p *__nth
* is the same element that would have been in that position had the
- * whole sequence been sorted. The elements either side of @p *nth are
- * not completely sorted, but for any iterator @i in the range
- * @p [first,nth) and any iterator @j in the range @p [nth,last) it
- * holds that @p comp(*j,*i) is false.
+ * whole sequence been sorted. The elements either side of @p *__nth are
+ * not completely sorted, but for any iterator @e i in the range
+ * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it
+ * holds that @p __comp(*j,*i) is false.
*/
template<typename _RandomAccessIterator, typename _Compare>
inline void
/**
* @brief Sort the elements of a sequence.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
+ * @param __first An iterator.
+ * @param __last Another iterator.
* @return Nothing.
*
- * Sorts the elements in the range @p [first,last) in ascending order,
- * such that @p *(i+1)<*i is false for each iterator @p i in the range
- * @p [first,last-1).
+ * Sorts the elements in the range @p [__first,__last) in ascending order,
+ * such that for each iterator @e i in the range @p [__first,__last-1),
+ * *(i+1)<*i is false.
*
* The relative ordering of equivalent elements is not preserved, use
* @p stable_sort() if this is needed.
/**
* @brief Sort the elements of a sequence using a predicate for comparison.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param comp A comparison functor.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __comp A comparison functor.
* @return Nothing.
*
- * Sorts the elements in the range @p [first,last) in ascending order,
- * such that @p comp(*(i+1),*i) is false for every iterator @p i in the
- * range @p [first,last-1).
+ * Sorts the elements in the range @p [__first,__last) in ascending order,
+ * such that @p __comp(*(i+1),*i) is false for every iterator @e i in the
+ * range @p [__first,__last-1).
*
* The relative ordering of equivalent elements is not preserved, use
* @p stable_sort() if this is needed.
/**
* @brief Merges two sorted ranges.
* @ingroup sorting_algorithms
- * @param first1 An iterator.
- * @param first2 Another iterator.
- * @param last1 Another iterator.
- * @param last2 Another iterator.
- * @param result An iterator pointing to the end of the merged range.
+ * @param __first1 An iterator.
+ * @param __first2 Another iterator.
+ * @param __last1 Another iterator.
+ * @param __last2 Another iterator.
+ * @param __result An iterator pointing to the end of the merged range.
* @return An iterator pointing to the first element <em>not less
- * than</em> @a val.
+ * than</em> @e val.
*
- * Merges the ranges [first1,last1) and [first2,last2) into the sorted range
- * [result, result + (last1-first1) + (last2-first2)). Both input ranges
- * must be sorted, and the output range must not overlap with either of
- * the input ranges. The sort is @e stable, that is, for equivalent
- * elements in the two ranges, elements from the first range will always
- * come before elements from the second.
+ * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into
+ * the sorted range @p [__result, __result + (__last1-__first1) +
+ * (__last2-__first2)). Both input ranges must be sorted, and the
+ * output range must not overlap with either of the input ranges.
+ * The sort is @e stable, that is, for equivalent elements in the
+ * two ranges, elements from the first range will always come
+ * before elements from the second.
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator>
/**
* @brief Merges two sorted ranges.
* @ingroup sorting_algorithms
- * @param first1 An iterator.
- * @param first2 Another iterator.
- * @param last1 Another iterator.
- * @param last2 Another iterator.
- * @param result An iterator pointing to the end of the merged range.
- * @param comp A functor to use for comparisons.
+ * @param __first1 An iterator.
+ * @param __first2 Another iterator.
+ * @param __last1 Another iterator.
+ * @param __last2 Another iterator.
+ * @param __result An iterator pointing to the end of the merged range.
+ * @param __comp A functor to use for comparisons.
* @return An iterator pointing to the first element "not less
- * than" @a val.
+ * than" @e val.
*
- * Merges the ranges [first1,last1) and [first2,last2) into the sorted range
- * [result, result + (last1-first1) + (last2-first2)). Both input ranges
- * must be sorted, and the output range must not overlap with either of
- * the input ranges. The sort is @e stable, that is, for equivalent
- * elements in the two ranges, elements from the first range will always
- * come before elements from the second.
+ * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into
+ * the sorted range @p [__result, __result + (__last1-__first1) +
+ * (__last2-__first2)). Both input ranges must be sorted, and the
+ * output range must not overlap with either of the input ranges.
+ * The sort is @e stable, that is, for equivalent elements in the
+ * two ranges, elements from the first range will always come
+ * before elements from the second.
*
* The comparison function should have the same effects on ordering as
* the function used for the initial sort.
* @brief Sort the elements of a sequence, preserving the relative order
* of equivalent elements.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
+ * @param __first An iterator.
+ * @param __last Another iterator.
* @return Nothing.
*
- * Sorts the elements in the range @p [first,last) in ascending order,
- * such that @p *(i+1)<*i is false for each iterator @p i in the range
- * @p [first,last-1).
+ * Sorts the elements in the range @p [__first,__last) in ascending order,
+ * such that for each iterator @p i in the range @p [__first,__last-1),
+ * @p *(i+1)<*i is false.
*
* The relative ordering of equivalent elements is preserved, so any two
- * elements @p x and @p y in the range @p [first,last) such that
+ * elements @p x and @p y in the range @p [__first,__last) such that
* @p x<y is false and @p y<x is false will have the same relative
* ordering after calling @p stable_sort().
*/
* @brief Sort the elements of a sequence using a predicate for comparison,
* preserving the relative order of equivalent elements.
* @ingroup sorting_algorithms
- * @param first An iterator.
- * @param last Another iterator.
- * @param comp A comparison functor.
+ * @param __first An iterator.
+ * @param __last Another iterator.
+ * @param __comp A comparison functor.
* @return Nothing.
*
- * Sorts the elements in the range @p [first,last) in ascending order,
- * such that @p comp(*(i+1),*i) is false for each iterator @p i in the
- * range @p [first,last-1).
+ * Sorts the elements in the range @p [__first,__last) in ascending order,
+ * such that for each iterator @p i in the range @p [__first,__last-1),
+ * @p __comp(*(i+1),*i) is false.
*
* The relative ordering of equivalent elements is preserved, so any two
- * elements @p x and @p y in the range @p [first,last) such that
- * @p comp(x,y) is false and @p comp(y,x) is false will have the same
+ * elements @p x and @p y in the range @p [__first,__last) such that
+ * @p __comp(x,y) is false and @p __comp(y,x) is false will have the same
* relative ordering after calling @p stable_sort().
*/
template<typename _RandomAccessIterator, typename _Compare>
/**
* @brief Return the union of two sorted ranges.
* @ingroup set_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param last2 End of second range.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of second range.
* @return End of the output range.
* @ingroup set_algorithms
*
/**
* @brief Return the union of two sorted ranges using a comparison functor.
* @ingroup set_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param last2 End of second range.
- * @param comp The comparison functor.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of second range.
+ * @param __comp The comparison functor.
* @return End of the output range.
* @ingroup set_algorithms
*
* This operation iterates over both ranges, copying elements present in
* each range in order to the output range. Iterators increment for each
* range. When the current element of one range is less than the other
- * according to @a comp, that element is copied and the iterator advanced.
- * If an equivalent element according to @a comp is contained in both
+ * according to @p __comp, that element is copied and the iterator advanced.
+ * If an equivalent element according to @p __comp is contained in both
* ranges, the element from the first range is copied and both ranges
* advance. The output range may not overlap either input range.
*/
/**
* @brief Return the intersection of two sorted ranges.
* @ingroup set_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param last2 End of second range.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of second range.
* @return End of the output range.
* @ingroup set_algorithms
*
* @brief Return the intersection of two sorted ranges using comparison
* functor.
* @ingroup set_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param last2 End of second range.
- * @param comp The comparison functor.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of second range.
+ * @param __comp The comparison functor.
* @return End of the output range.
* @ingroup set_algorithms
*
* This operation iterates over both ranges, copying elements present in
* both ranges in order to the output range. Iterators increment for each
* range. When the current element of one range is less than the other
- * according to @a comp, that iterator advances. If an element is
- * contained in both ranges according to @a comp, the element from the
+ * according to @p __comp, that iterator advances. If an element is
+ * contained in both ranges according to @p __comp, the element from the
* first range is copied and both ranges advance. The output range may not
* overlap either input range.
*/
/**
* @brief Return the difference of two sorted ranges.
* @ingroup set_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param last2 End of second range.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of second range.
* @return End of the output range.
* @ingroup set_algorithms
*
* @brief Return the difference of two sorted ranges using comparison
* functor.
* @ingroup set_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param last2 End of second range.
- * @param comp The comparison functor.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of second range.
+ * @param __comp The comparison functor.
* @return End of the output range.
* @ingroup set_algorithms
*
* This operation iterates over both ranges, copying elements present in
* the first range but not the second in order to the output range.
* Iterators increment for each range. When the current element of the
- * first range is less than the second according to @a comp, that element
+ * first range is less than the second according to @p __comp, that element
* is copied and the iterator advances. If the current element of the
* second range is less, no element is copied and the iterator advances.
- * If an element is contained in both ranges according to @a comp, no
+ * If an element is contained in both ranges according to @p __comp, no
* elements are copied and both ranges advance. The output range may not
* overlap either input range.
*/
/**
* @brief Return the symmetric difference of two sorted ranges.
* @ingroup set_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param last2 End of second range.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of second range.
* @return End of the output range.
* @ingroup set_algorithms
*
* @brief Return the symmetric difference of two sorted ranges using
* comparison functor.
* @ingroup set_algorithms
- * @param first1 Start of first range.
- * @param last1 End of first range.
- * @param first2 Start of second range.
- * @param last2 End of second range.
- * @param comp The comparison functor.
+ * @param __first1 Start of first range.
+ * @param __last1 End of first range.
+ * @param __first2 Start of second range.
+ * @param __last2 End of second range.
+ * @param __comp The comparison functor.
* @return End of the output range.
* @ingroup set_algorithms
*
* This operation iterates over both ranges, copying elements present in
* one range but not the other in order to the output range. Iterators
* increment for each range. When the current element of one range is less
- * than the other according to @a comp, that element is copied and the
+ * than the other according to @p comp, that element is copied and the
* iterator advances. If an element is contained in both ranges according
- * to @a comp, no elements are copied and both ranges advance. The output
+ * to @p __comp, no elements are copied and both ranges advance. The output
* range may not overlap either input range.
*/
template<typename _InputIterator1, typename _InputIterator2,
/**
* @brief Return the minimum element in a range.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
+ * @param __first Start of range.
+ * @param __last End of range.
* @return Iterator referencing the first instance of the smallest value.
*/
template<typename _ForwardIterator>
/**
* @brief Return the minimum element in a range using comparison functor.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
- * @param comp Comparison functor.
+ * @param __first Start of range.
+ * @param __last End of range.
+ * @param __comp Comparison functor.
* @return Iterator referencing the first instance of the smallest value
- * according to comp.
+ * according to __comp.
*/
template<typename _ForwardIterator, typename _Compare>
_ForwardIterator
/**
* @brief Return the maximum element in a range.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
+ * @param __first Start of range.
+ * @param __last End of range.
* @return Iterator referencing the first instance of the largest value.
*/
template<typename _ForwardIterator>
/**
* @brief Return the maximum element in a range using comparison functor.
* @ingroup sorting_algorithms
- * @param first Start of range.
- * @param last End of range.
- * @param comp Comparison functor.
+ * @param __first Start of range.
+ * @param __last End of range.
+ * @param __comp Comparison functor.
* @return Iterator referencing the first instance of the largest value
- * according to comp.
+ * according to __comp.
*/
template<typename _ForwardIterator, typename _Compare>
_ForwardIterator
## Makefile for the GNU C++ Support library.
##
## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- ## 2009, 2010, 2011
+ ## 2009, 2010, 2011, 2012
## Free Software Foundation, Inc.
##
## Process this file with automake to produce Makefile.in.
noinst_LTLIBRARIES = libsupc++convenience.la
std_HEADERS = \
- cxxabi.h exception initializer_list new typeinfo
+ cxxabi.h exception initializer_list new typeinfo
bits_HEADERS = \
- cxxabi_forced.h hash_bytes.h \
- exception_defines.h exception_ptr.h nested_exception.h
+ atomic_lockfree_defines.h cxxabi_forced.h \
+ exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h
headers = $(std_HEADERS) $(bits_HEADERS)
if GLIBCXX_HOSTED
c_sources = \
- cp-demangle.c
+ cp-demangle.c
endif
sources = \
eh_ptr.cc \
eh_term_handler.cc \
eh_terminate.cc \
+ eh_tm.cc \
eh_throw.cc \
eh_type.cc \
eh_unex_handler.cc \
vmi_class_type_info.cc \
vterminate.cc
- libsupc___la_SOURCES = $(sources) $(c_sources)
+ libsupc___la_SOURCES = $(sources) $(c_sources)
libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
+ cp-demangle.c:
+ rm -f $@
+ $(LN_S) $(toplevel_srcdir)/libiberty/cp-demangle.c $@
+ cp-demangle.lo: cp-demangle.c
+ $(LTCOMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $<
+ cp-demangle.o: cp-demangle.c
+ $(C_COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $<
+
+
+ # Use special rules for the C++0x sources so that the proper flags are passed.
+ eh_ptr.lo: eh_ptr.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+ eh_ptr.o: eh_ptr.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
+ eh_throw.lo: eh_throw.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+ eh_throw.o: eh_throw.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
+ guard.lo: guard.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+ guard.o: guard.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
+ nested_exception.lo: nested_exception.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+ nested_exception.o: nested_exception.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
# set this option because CONFIG_CXXFLAGS has to be after
# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
# as the occasion call for it.
AM_CXXFLAGS = \
- -fno-implicit-templates \
- $(LIBSUPCXX_PICFLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS)
+ $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
+ $(XTEMPLATE_FLAGS) \
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
"gxx_include_dir=$(gxx_include_dir)"
# LTCOMPILE is copied from LTCXXCOMPILE below.
LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared $(LIBTOOLFLAGS) --mode=compile \
- $(CC) $(DEFS) $(C_INCLUDES) $(LIBSUPCXX_PICFLAGS) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-
- cp-demangle.c:
- rm -f $@
- $(LN_S) $(toplevel_srcdir)/libiberty/cp-demangle.c $@
- cp-demangle.lo: cp-demangle.c
- $(LTCOMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $<
- cp-demangle.o: cp-demangle.c
- $(C_COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $<
-
+ $(CC) $(DEFS) $(C_INCLUDES) \
+ $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+nested_exception.lo: nested_exception.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+nested_exception.o: nested_exception.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
# Libtool notes
- # 1) Need to explicitly set LTCXXCOMPILE so that AM_CXXFLAGS is
- # last. (That way, things like -O2 passed down from the toplevel can
- # be overridden by --enable-debug.)
-
- # 2) In general, libtool expects an argument such as `--tag=CXX' when
+ # 1) In general, libtool expects an argument such as `--tag=CXX' when
# using the C++ compiler, because that will enable the settings
# detected when C++ support was being configured. However, when no
# such flag is given in the command line, libtool attempts to figure
# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
# attempt to infer which configuration to use.
- #
- # We have to put --tag disable-shared after --tag CXX lest things
- # CXX undo the affect of disable-shared.
- LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+ #
+ # The second tag argument, `--tag disable-shared` means that libtool
+ # only compiles each source once, for static objects. In actuality,
+ # glibcxx_lt_pic_flag and glibcxx_compiler_shared_flag are added to
+ # the libtool command that is used create the object, which is
+ # suitable for shared libraries. The `--tag disable-shared` must be
+ # placed after --tag CXX lest things CXX undo the affect of
+ # disable-shared.
+
+ # 2) Need to explicitly set LTCXXCOMPILE so that AM_CXXFLAGS is
+ # last. (That way, things like -O2 passed down from the toplevel can
+ # be overridden by --enable-debug.)
+ LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
- CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=link $(CXX) \
- $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
-
+ CXXLINK = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
# Install notes
# We have to have rules modified from the default to counteract SUN make
int main()
{
- check_add_unsigned<bool>(); // { dg-error "instantiated from" }
- check_add_unsigned<wchar_t>(); // { dg-error "instantiated from" }
+ check_add_unsigned<bool>(); // { dg-error "required from" }
+ check_add_unsigned<wchar_t>(); // { dg-error "required from" }
return 0;
}
// { dg-error "invalid use of incomplete" "" { target *-*-* } 28 }
-// { dg-error "declaration of" "" { target *-*-* } 63 }
+// { dg-error "declaration of" "" { target *-*-* } 64 }
int main()
{
- check_remove_unsigned<bool>(); // { dg-error "instantiated from" }
- check_remove_unsigned<wchar_t>(); // { dg-error "instantiated from" }
+ check_remove_unsigned<bool>(); // { dg-error "required from" }
+ check_remove_unsigned<wchar_t>(); // { dg-error "required from" }
return 0;
}
// { dg-error "invalid use of incomplete" "" { target *-*-* } 28 }
-// { dg-error "declaration of" "" { target *-*-* } 106 }
+// { dg-error "declaration of" "" { target *-*-* } 107 }