0823efedd0
Merge from cxx-conversion branch (http://gcc.gnu.org/wiki/cxx-conversion). As described in http://gcc.gnu.org/ml/gcc/2012-08/msg00015.html, this patch changes the default bootstrap process so that stage 1 always builds with a C++ compiler. Other than the bootstrap change, the patch makes no functional changes to the compiler. Everything should build as it does now in trunk. The main changes in this patch are: 1- Configuration changes. 2- Re-write of VEC. 3- Re-write of gengtype to support C++ templates and user-provided marking functions. 4- New hash table class. 5- Re-write double_int. 6- Implement tree macros as inline functions so they can be called from gdb. As discussed before, several of these changes do not fully change the call sites to use the new APIs. The bootstrap changes have already been tested on a wide range of targets (http://gcc.gnu.org/wiki/CppBuildStatus). Additionally, I have tested the merged trunk on: x86_64-unknown-linux-gnu, mips64el-unknown-linux-gnu, powerpc64-unknown-linux-gnu, i686-pc-linux-gnu, and ia64-unknown-linux-gnu. ChangeLog 2012-08-14 Diego Novillo <dnovillo@google.com> Merge from cxx-conversion branch. * Makefile.tpl (STAGE[+id+]_CXXFLAGS): Remove POSTSTAGE1_CONFIGURE_FLAGS. * Makefile.in: Regenerate. * configure.ac (ENABLE_BUILD_WITH_CXX): Remove. Update all users. Force C++ when bootstrapping. * configure: Regenerate. libcpp/ChangeLog 2012-08-14 Diego Novillo <dnovillo@google.com> Merge from cxx-conversion branch. Configury. * Makefile.in: Remove all handlers of ENABLE_BUILD_WITH_CXX. * configure.ac: Likewise. * configure: Regenerate. 2012-08-14 Lawrence Crowl <crowl@google.com> Merge from cxx-conversion branch. New C++ hash table. * include/symtab.h (typedef struct ht hash_table): Change the typedef name to cpp_hash_table. Update all users of the typedef. gcc/ChangeLog 2012-08-14 Diego Novillo <dnovillo@google.com> Merge from cxx-conversion branch. Configury. * configure.ac (CXX_FOR_BUILD): Define and substitute. (BUILD_CXXFLAGS): Define. Remove all handlers of ENABLE_BUILD_WITH_CXX. Force all build to be with C++. * Makefile.in (BUILD_CXXFLAGS): Use it. Remove all handlers of ENABLE_BUILD_WITH_CXX. * configure: Regenerate. * config.in: Regenerate. * doc/install.texi: Remove documentation for --enable-build-with-cxx and --enable-build-poststage1-with-cxx. 2012-08-14 Diego Novillo <dnovillo@google.com> Merge from cxx-conversion branch. Re-implement VEC in C++. * vec.c (vec_heap_free): Convert into a template function. (vec_gc_o_reserve_1): Make extern. (vec_gc_p_reserve): Remove. (vec_gc_p_reserve_exact): Remove. (vec_gc_o_reserve): Remove. (vec_gc_o_reserve_exact): Remove. (vec_heap_o_reserve_1): Make extern. (vec_heap_p_reserve): Remove. (vec_heap_p_reserve_exact): Remove. (vec_heap_o_reserve): Remove. (vec_heap_o_reserve_exact): Remove. (vec_stack_p_reserve): Remove. (vec_stack_p_reserve_exact): Remove. * vec.h (VEC_CHECK_INFO, VEC_CHECK_DECL, VEC_CHECK_PASS, VEC_ASSERT, VEC_ASSERT_FAIL, vec_assert_fail): Move earlier in the file. (VEC): Define to vec_t<T>. (vec_allocation_t): Define. (struct vec_prefix): Move earlier in the file. (vec_t<T>): New template. (DEF_VEC_I, DEF_VECL_ALLOC_I, DEF_VEC_P, DEF_VEC_ALLOC_P, DEF_VEC_O, DEF_VEC_ALLOC_P, DEF_VEC_O, DEF_VEC_ALLOC_O, DEF_VEC_ALLOC_P_STACK, DEF_VEC_ALLOC_O_STACK, DEF_VEC_ALLOC_I_STACK): Expand to 'struct vec_swallow_trailing_semi'. (DEF_VEC_A): Provide template instantiations for GC/PCH markers that do not traverse the vector. (vec_stack_p_reserve): Remove. (vec_stack_p_reserve_exact): Remove. (vec_stack_p_reserve_exact_1): Remove. (vec_stack_o_reserve): Remove. (vec_stack_o_reserve_exact): Remove. (vec_stack_free): Re-write as a template function. (vec_reserve): New template function. (vec_reserve_exact): New template function. (vec_heap_free): New template function if GATHER_STATISTICS is defined. Otherwise, macro that expands to free(). (VEC_length_1): New template function. (VEC_length): Call it. (VEC_empty_1): New template function. (VEC_empty): Call it. (VEC_address_1): New template function. (VEC_address): Call it. (VEC_last_1): New template function. (VEC_last): Call it. Change return type to T&. Change all users that used VEC_Os. (VEC_index_1): New template function. (VEC_index): Call it. Return a T& instead of a T*. Update all callers that were using VEC_O before. (VEC_iterate_1): New template function. (VEC_iterate): Call it. (VEC_embedded_size_1): New template function. (VEC_embedded_size): Call it. (VEC_embedded_init_1): New template function. (VEC_embedded_init): Call it. (VEC_alloc_1): New template function. (VEC_alloc): Call it. If A is 'stack', call XALLOCAVAR to do the allocation. (VEC_free_1): New template function. (VEC_free): Call it. (VEC_copy_1): New template function. (VEC_copy): Call it. (VEC_space_1): New template function (VEC_space): Call it. (VEC_reserve_1): New template function. (VEC_reserve): Call it. (VEC_reserve_exact_1): New template function. (VEC_reserve_exact): Call it. (VEC_splice_1): New template function. (VEC_splice): Call it. (VEC_safe_splice_1): New template function. (VEC_safe_splice): Call it. (VEC_quick_push_1): New template function. Create two overloads, one accepting T, the other accepting T *. Update all callers where T and T * are ambiguous. (VEC_quick_push): Call it. (VEC_safe_push_1): New template function. Create two overloads, one accepting T, the other accepting T *. Update all callers where T and T * are ambiguous. (VEC_safe_push): Call it. (VEC_pop_1): New template function. (VEC_pop): Call it. (VEC_truncate_1): New template function. (VEC_truncate): Call it. (VEC_safe_grow_1): New template function. (VEC_safe_grow): Call it. (VEC_safe_grow_cleared_1): New template function. (VEC_safe_grow_cleared): Call it. (VEC_replace_1): New template function. (VEC_replace): Call it. Always accept T instead of T*. Update all callers that used VEC_Os. (VEC_quick_insert_1): New template function. (VEC_quick_insert): Call it. (VEC_safe_insert_1): New template function. (VEC_safe_insert): Call it. (VEC_ordered_remove_1): New template function. (VEC_ordered_remove): Call it. (VEC_unordered_remove_1): New template function. (VEC_unordered_remove): Call it. (VEC_block_remove_1): New template function. (VEC_block_remove): Call it. (VEC_lower_bound_1): New template function. (VEC_lower_bound): Call it. (VEC_OP): Remove. (DEF_VEC_FUNC_P): Remove. (DEF_VEC_ALLOC_FUNC_P): Remove. (DEF_VEC_NONALLOC_FUNCS_P): Remove. (DEF_VEC_FUNC_O): Remove. (DEF_VEC_ALLOC_FUNC_O): Remove. (DEF_VEC_NONALLOC_FUNCS_O): Remove. (DEF_VEC_ALLOC_FUNC_I): Remove. (DEF_VEC_NONALLOC_FUNCS_I): Remove. (DEF_VEC_ALLOC_FUNC_P_STACK): Remove. (DEF_VEC_ALLOC_FUNC_O_STACK): Remove. (DEF_VEC_ALLOC_FUNC_I_STACK): Remove. (vec_reserve_exact): New template function. * gengtype-lex.l (DEF_VEC_ALLOC_[IOP]/{EOID}): Remove. * gengtype-parse.c (token_names): Remove DEF_VEC_ALLOC_[IOP]. (typedef_name): Emit vec_t<C1> instead of VEC_C1_C2. (def_vec_alloc): Remove. Update all callers. * gengtype.c (filter_type_name): New. (output_mangled_typename): Call it. (write_func_for_structure): Likewise. (write_types): Likewise. (write_root): Likewise. (write_typed_alloc_def): Likewise. (note_def_vec): Emit vec_t<TYPE_NAME> instead of VEC_TYPE_NAME_base. (note_def_vec_alloc): Remove. * gengtype.h (note_def_vec_alloc): Remove. (DEFVEC_ALLOC): Remove token code. * df-scan.c (df_bb_verify): Remove call to df_free_collection_rec inside the insn traversal loop. * gimplify.c (gimplify_compound_lval): Rename STACK to EXPR_STACK. * ipa-inline.c (inline_small_functions): Rename HEAP to EDGE_HEAP. * reg-stack.c (stack): Rename to STACK_PTR. Update all users. * tree-vrp.c (stack): Rename to EQUIV_STACK. Update all users. * config/bfin/bfin.c (hwloop_optimize): Update some calls to VEC_* for vectors of non-pointers. * config/c6x/c6x.c (try_rename_operands): Likewise. (reshuffle_units): Likewise. * config/mips/mips.c (mips_multi_start): Likewise. (mips_multi_add): Likewise. (mips_multi_copy_insn): Likewise. (mips_multi_set_operand): Likewise. * hw-doloop.c (discover_loop): Likewise. (discover_loops): Likewise. (reorg_loops): Likewise. 2012-08-14 Diego Novillo <dnovillo@google.com> Merge from cxx-conversion branch. C++ support in gengtype. * coretypes.h (gt_pointer_operator): Move from ... * ggc.h: ... here. * doc/gty.texi: Document support for C++ templates and user-provided markers. * gcc/gengtype-lex.l: Update copyright year. Remove support for recognizing DEF_VEC_O, DEF_VEC_P and DEFVEC_I. * gengtype-parse.c: Update copyright year. (token_names): Remove DEF_VEC_O, DEF_VEC_P and DEF_VEC_I. (require_template_declaration): New. (typedef_name): Call it. (type): Replace IS_UNION with KIND. Replace all users. (def_vec): Remove. Update all users. * gengtype-state.c (type_lineloc): Handle TYPE_USER_STRUCT. (write_state_user_struct_type): New. (write_state_type): Call it. (read_state_user_struct_type): New. (read_state_type): Call it. * gengtype.c: Update copyright year. (dump_pair): Move declaration to the top. (dump_type): Likewise. (dump_type_list): Likewise. (dbgprint_count_type_at): Handle TYPE_USER_STRUCT. (create_user_defined_type): New. (resolve_typedef): Call it. (new_structure): Replace argument ISUNION with KIND. Change users to refer to KIND directly. Update all callers. (find_structure): Likewise. (set_gc_used_type): Handle TYPE_USER_STRUCT. (create_file): Update HDR to include new copyright year. (struct walk_type_data): Add field IN_PTR_FIELD. (output_mangled_typename): Handle TYPE_USER_STRUCT. (walk_type): Set D->IN_PTR_FIELD when walking a TYPE_POINTER. Clear it afterwards. Handle TYPE_USER_STRUCT. (write_types_process_field): Handle TYPE_USER_STRUCT. (get_type_specifier): Move earlier in the file. (write_type_decl): New. (write_marker_function_name): New. (write_user_func_for_structure_ptr): New. (write_user_func_for_structure_body): New. (write_user_marking_functions): New. (write_func_for_structure): Call write_marker_function_name and write_type_decl. Do not call walk_type for TYPE_USER_STRUCT. Emit a call to the user function directly. Call write_user_marking_functions on TYPE_USER_STRUCTs. (write_types_local_user_process_field): New. (write_pch_user_walking_for_structure_body): New. (write_pch_user_walking_functions): New. (write_types_local_process_field): Handle TYPE_USER_STRUCT. (write_local_func_for_structure): Do not call walk_type for TYPE_USER_STRUCT. Instead, emit the call to gt_pch_nx directly. Call write_pch_user_walking_functions for TYPE_USER_STRUCTs. (write_root): Handle TYPE_USER_STRUCT. (vec_prefix_type): Remove. Update all users. (note_def_vec): Remove. Update all users. (dump_typekind): Handle TYPE_USER_STRUCT. (dump_type): Initialize SEEN_TYPES, if needed. Handle TYPE_USER_STRUCT. (dump_everything): Do not initialize SEEN_TYPES. * gengtype.h: Update copyright year. (enum typekind): Add TYPE_USER_STRUCT. (union_or_struct_p): Rename from UNION_OR_STRUCT_P. Convert into function. Add an overload taking const_type_p. Update all callers. (new_structure): Change second field to type enum typekind. Update all users. (find_structure): Likewise. (note_def_vec): Remove. (DEFVEC_OP): Remove. (DEFVEC_I): Remove. * ggc-page.c (gt_ggc_mx): Add entry points for marking 'const char *&', 'unsigned char *&' and 'unsigned char&'. * ggc-zone.c (gt_ggc_mx): Add entry points for marking 'const char *&' and 'unsigned char *&'. * stringpool.c (gt_pch_nx): Add entry points for marking 'const char *&', 'unsigned char *&' and 'unsigned char&'. Add an entry point for the overload taking arguments 'unsigned char *', 'gt_pointer_operator' and 'void *'. * vec.h (struct vec_prefix): Remove GTY marker. (struct vec_t): Remove GTY((length)) attribute from field 'vec'. (gt_ggc_mx (vec_t<T> *)): New template function. (gt_pch_nx (vec_t<T> *)): New template function. (gt_pch_nx (vec_t<T *> *, gt_pointer_operator, void *)): New template function. (gt_pch_nx (vec_t<T> *, gt_pointer_operator, void *)): New template function. * basic-block.h (struct edge_def): Mark GTY((user)). Remove all GTY markers from fields. (gt_ggc_mx): Declare. (gt_pch_nx): Declare. * tree-cfg.c (gt_ggc_mx): New. (gt_pch_nx): New. * gengtype-lex.l (USER_GTY): Add pattern for "user". * gengtype-parse.c (option): Handle USER_GTY. (opts_have): New. (type): Call it. If the keyword 'user' is used, do not walk the fields of the structure. * gengtype.h (USER_GTY): Add. * doc/gty.texi: Update. 2012-08-14 Lawrence Crowl <crowl@google.com> Merge cxx-conversion branch. Implement C++ hash table. * hash-table.h: New. Implementation borrowed from libiberty/hashtab.c. * hash-table.c: Likewise. * tree-ssa-tail-merge.c: Include hash-table.h instead of hashtab.h. (static htab_t same_succ_htab): Change type to hash_table; move specification of helper functions from create call to declaration. Change users to invoke member functions. (same_succ_print_traverse): Make extern ssa_.... Change callers. Remove void* casting. (same_succ_hash): Likewise. (same_succ_equal): Likewise. (same_succ_delete): Likewise. * tree-ssa-threadupdate.c: Include hash-table.h. (struct local_info): Rename to ssa_local_info_t to avoid overloading the type name local_info with the variable name local_info. (static htab_t redirection_data): Change type to hash_table. Move specification of helper functions from create call to declaration. Change users to invoke member functions. (redirection_data_hash): Make extern ssa_.... Change callers. Remove void* casting. (redirection_data_eq): Likewise. (fix_duplicate_block_edges): Likewise. (create_duplicates): Likewise. (fixup_template_block): Likewise. (redirect_edges): Likewise. (lookup_redirection_data): Change types associated with the hash table from void* to their actual type. Remove unnecessary casts. * tree-ssa-ccp.c: Include hash-table.h. (typedef gimple_htab): New. Uses hash_table. Replace specific uses of htab_t with gimple_htab. Change users to invoke member functions. Move specification of helper functions from create call to declaration. * tree-ssa-coalesce.c: Include hash-table.h instead of hashtab.h. (hash_ssa_name_by_var): Make extern. Remove void* casting. (eq_ssa_name_by_var): Likewise. (coalesce_ssa_name): Change type of local static htab_t ssa_name_hash to hash_table. Change users to invoke member functions. Move specification of helper functions from create call to declaration. * coverage.c: Include hash-table.h instead of hashtab.h. (static htab_t counts_hash): Change type to hash_table; move specification of helper functions from create call to declaration. Change users to invoke member functions. (htab_counts_entry_hash): Make extern. Rename with coverage_... instead of htab_... Remove void* casting. (htab_counts_entry_eq): Likewise. (htab_counts_entry_del): Likewise. * tree-ssa-pre.c: Include hash-table.h instead of hashtab.h. (static htab_t expression_to_id): Change type to hash_table. Move specification of helper functions from create call to declaration. Change users to invoke member functions. (static htab_t phi_translate_table): Likewise. (pre_expr_eq): Make extern ssa_.... Change callers. Remove void* casting. (pre_expr_hash): Likewise. (expr_pred_trans_hash): Likewise. (expr_pred_trans_eq): Likewise. (alloc_expression_id): Change types associated with the hash table from void* to their actual type. Remove unnecessary casts. (lookup_expression_id): Likewise. (phi_trans_lookup): Likewise. (phi_trans_add): Likewise. * stringpool.c: Rename uses of libcpp typedef hash_table to cpp_hash_table. * Makefile.in: Add hash-table.o to OBJS-libcommon-target. Add $(HASH_TABLE_H). Add new dependences on $(HASH_TABLE_H). 2012-08-14 Lawrence Crowl <crowl@google.com> Merge from cxx-conversion branch. Re-write double_int in C++. * hash-table.h (typedef double_int): Change to struct (POD). (double_int::make): New overloads for int to double-int conversion. (double_int::mask): New. (double_int::max_value): New. (double_int::min_value): New. (double_int::operator ++): New. (double_int::operator --): New. (double_int::operator *=): New. (double_int::operator +=): New. (double_int::operator -=): New. (double_int::to_signed): New. (double_int::to_unsigned): New. (double_int::fits_unsigned): New. (double_int::fits_signed): New. (double_int::fits): New. (double_int::trailing_zeros): New. (double_int::popcount): New. (double_int::multiple_of): New. (double_int::set_bit): New. (double_int::mul_with_sign): New. (double_int::operator * (binary)): New. (double_int::operator + (binary)): New. (double_int::operator - (binary)): New. (double_int::operator - (unary)): New. (double_int::operator ~ (unary)): New. (double_int::operator & (binary)): New. (double_int::operator | (binary)): New. (double_int::operator ^ (binary)): New. (double_int::and_not): New. (double_int::lshift): New. (double_int::rshift): New. (double_int::alshift): New. (double_int::arshift): New. (double_int::llshift): New. (double_int::lrshift): New. (double_int::lrotate): New. (double_int::rrotate): New. (double_int::div): New. (double_int::sdiv): New. (double_int::udiv): New. (double_int::mod): New. (double_int::smod): New. (double_int::umod): New. (double_int::divmod): New. (double_int::sdivmod): New. (double_int::udivmod): New. (double_int::ext): New. (double_int::zext): New. (double_int::sext): New. (double_int::is_zero): New. (double_int::is_one): New. (double_int::is_minus_one): New. (double_int::is_negative): New. (double_int::cmp): New. (double_int::ucmp): New. (double_int::scmp): New. (double_int::ult): New. (double_int::ugt): New. (double_int::slt): New. (double_int::sgt): New. (double_int::max): New. (double_int::smax): New. (double_int::umax): New. (double_int::min): New. (double_int::smin): New. (double_int::umin): New. (double_int::operator ==): New. (double_int::operator !=): New. (shwi_to_double_int): Change implementation to use member function. (double_int_minus_one): Likewise. (double_int_zero): Likewise. (double_int_one): Likewise. (double_int_two): Likewise. (double_int_ten): Likewise. (uhwi_to_double_int): Likewise. (double_int_to_shwi): Likewise. (double_int_to_uhwi): Likewise. (double_int_fits_in_uhwi_p): Likewise. (double_int_fits_in_shwi_p): Likewise. (double_int_fits_in_hwi_p): Likewise. (double_int_mul): Likewise. (double_int_mul_with_sign): Likewise. (double_int_add): Likewise. (double_int_sub): Likewise. (double_int_neg): Likewise. (double_int_div): Likewise. (double_int_sdiv): Likewise. (double_int_udiv): Likewise. (double_int_mod): Likewise. (double_int_smod): Likewise. (double_int_umod): Likewise. (double_int_divmod): Likewise. (double_int_sdivmod): Likewise. (double_int_udivmod): Likewise. (double_int_multiple_of): Likewise. (double_int_setbit): Likewise. (double_int_ctz): Likewise. (double_int_not): Likewise. (double_int_ior): Likewise. (double_int_and): Likewise. (double_int_and_not): Likewise. (double_int_xor): Likewise. (double_int_lshift): Likewise. (double_int_rshift): Likewise. (double_int_lrotate): Likewise. (double_int_rrotate): Likewise. (double_int_cmp): Likewise. (double_int_scmp): Likewise. (double_int_ucmp): Likewise. (double_int_max): Likewise. (double_int_smax): Likewise. (double_int_umax): Likewise. (double_int_min): Likewise. (double_int_smin): Likewise. (double_int_umin): Likewise. (double_int_ext): Likewise. (double_int_sext): Likewise. (double_int_zext): Likewise. (double_int_mask): Likewise. (double_int_max_value): Likewise. (double_int_min_value): Likewise. (double_int_zero_p): Likewise. (double_int_one_p): Likewise. (double_int_minus_one_p): Likewise. (double_int_equal_p): Likewise. (double_int_popcount): Likewise. * hash-table.c (double_int_mask): Reuse implementation for double_int::mask. (double_int_max_value): Likewise. (double_int_min_value): Likewise. (double_int_ext): Likewise. (double_int_zext): Likewise. (double_int_sext): Likewise. (double_int_mul_with_sign): Likewise. (double_int_divmod): Likewise. (double_int_sdivmod): Likewise. (double_int_udivmod): Likewise. (double_int_div): Likewise. (double_int_sdiv): Likewise. (double_int_udiv): Likewise. (double_int_mod): Likewise. (double_int_smod): Likewise. (double_int_umod): Likewise. (double_int_multiple_of): Likewise. (double_int_lshift): Likewise. (double_int_rshift): Likewise. (double_int_lrotate): Likewise. (double_int_rrotate): Likewise. (double_int_cmp): Likewise. (double_int_ucmp): Likewise. (double_int_scmp): Likewise. (double_int_max): Likewise. (double_int_smax): Likewise. (double_int_umax): Likewise. (double_int_min): Likewise. (double_int_smin): Likewise. (double_int_umin): Likewise. (double_int_min): Likewise. (double_int_min): Likewise. (double_int_min): Likewise. (double_int_min): Likewise. (double_int_min): Likewise. (double_int_min): Likewise. (double_int::alshift): New. (double_int::arshift): New. (double_int::llshift): New. (double_int::lrshift): New. (double_int::ult): New. (double_int::ugt): New. (double_int::slt): New. (double_int::sgt): New. (double_int_setbit): Reuse implementation for double_int::set_bit, which avoids a name conflict with a macro. (double_int_double_int_ctz): Reuse implementation for double_int::trailing_zeros. (double_int_fits_in_shwi_p): Reuse implementation for double_int::fits_signed. (double_int_fits_in_hwi_p): Reuse implementation for double_int::fits. (double_int_mul): Reuse implementation for binary double_int::operator *. (double_int_add): Likewise. (double_int_sub): Likewise. (double_int_neg): Reuse implementation for unary double_int::operator -. (double_int_max_value): Likewise. * fixed-value.c: Change to use member functions introduced above. 2012-08-14 Lawrence Crowl <crowl@google.com> Merge cxx-conversion branch. Support tree macro calling from gdb. * tree.h (tree_check): New. (TREE_CHECK): Use inline function above instead of __extension__. (tree_not_check): New. (TREE_NOT_CHECK): Use inline function above instead of __extension__. (tree_check2): New. (TREE_CHECK2): Use inline function above instead of __extension__. (tree_not_check2): New. (TREE_NOT_CHECK2): Use inline function above instead of __extension__. (tree_check3): New. (TREE_CHECK3): Use inline function above instead of __extension__. (tree_not_check3): New. (TREE_NOT_CHECK3): Use inline function above instead of __extension__. (tree_check4): New. (TREE_CHECK4): Use inline function above instead of __extension__. (tree_not_check4): New. (TREE_NOT_CHECK4): Use inline function above instead of __extension__. (tree_check5): New. (TREE_CHECK5): Use inline function above instead of __extension__. (tree_not_check5): New. (TREE_NOT_CHECK5): Use inline function above instead of __extension__. (contains_struct_check): New. (CONTAINS_STRUCT_CHECK): Use inline function above instead of __extension__. (tree_class_check): New. (TREE_CLASS_CHECK): Use inline function above instead of __extension__. (tree_range_check): New. (TREE_RANGE_CHECK): Use inline function above instead of __extension__. (omp_clause_subcode_check): New. (OMP_CLAUSE_SUBCODE_CHECK): Use inline function above instead of __extension__. (omp_clause_range_check): New. (OMP_CLAUSE_RANGE_CHECK): Use inline function above instead of __extension__. (expr_check): New. (EXPR_CHECK): Use inline function above instead of __extension__. (non_type_check): New. (NON_TYPE_CHECK): Use inline function above instead of __extension__. (tree_vec_elt_check): New. (TREE_VEC_ELT_CHECK): Use inline function above instead of __extension__. (omp_clause_elt_check): New. (OMP_CLAUSE_ELT_CHECK): Use inline function above instead of __extension__. (tree_operand_check): New. (TREE_OPERAND_CHECK): Use inline function above instead of __extension__. (tree_operand_check_code): New. (TREE_OPERAND_CHECK_CODE): Use inline function above instead of __extension__. (TREE_CHAIN): Simplify implementation. (TREE_TYPE): Simplify implementation. (tree_operand_length): Move for compilation dependences. * gdbinit.in: (macro define __FILE__): New. (macro define __LINE__): New. (skip "tree.h"): New. gcc/cp/ChangeLog 2012-08-14 Diego Novillo <dnovillo@google.com> Merge from cxx-conversion branch. Re-write VEC in C++. * call.c (add_function_candidate): Remove const qualifier from call to VEC_index. 2012-08-14 Diego Novillo <dnovillo@google.com> Merge from cxx-conversion branch. Configury. * go-c.h: Remove all handlers of ENABLE_BUILD_WITH_CXX. * go-gcc.cc: Likewise. * go-system.h: Likewise. From-SVN: r190402
755 lines
23 KiB
C
755 lines
23 KiB
C
/* CPP Library.
|
|
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
|
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
|
|
2009, 2010, 2011 Free Software Foundation, Inc.
|
|
Contributed by Per Bothner, 1994-95.
|
|
Based on CCCP program by Paul Rubin, June 1986
|
|
Adapted to ANSI C, Richard Stallman, Jan 1987
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by the
|
|
Free Software Foundation; either version 3, or (at your option) any
|
|
later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; see the file COPYING3. If not see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include "config.h"
|
|
#include "system.h"
|
|
#include "cpplib.h"
|
|
#include "internal.h"
|
|
#include "mkdeps.h"
|
|
#include "localedir.h"
|
|
#include "filenames.h"
|
|
|
|
static void init_library (void);
|
|
static void mark_named_operators (cpp_reader *, int);
|
|
static void read_original_filename (cpp_reader *);
|
|
static void read_original_directory (cpp_reader *);
|
|
static void post_options (cpp_reader *);
|
|
|
|
/* If we have designated initializers (GCC >2.7) these tables can be
|
|
initialized, constant data. Otherwise, they have to be filled in at
|
|
runtime. */
|
|
#if HAVE_DESIGNATED_INITIALIZERS
|
|
|
|
#define init_trigraph_map() /* Nothing. */
|
|
#define TRIGRAPH_MAP \
|
|
__extension__ const uchar _cpp_trigraph_map[UCHAR_MAX + 1] = {
|
|
|
|
#define END };
|
|
#define s(p, v) [p] = v,
|
|
|
|
#else
|
|
|
|
#define TRIGRAPH_MAP uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \
|
|
static void init_trigraph_map (void) { \
|
|
unsigned char *x = _cpp_trigraph_map;
|
|
|
|
#define END }
|
|
#define s(p, v) x[p] = v;
|
|
|
|
#endif
|
|
|
|
TRIGRAPH_MAP
|
|
s('=', '#') s(')', ']') s('!', '|')
|
|
s('(', '[') s('\'', '^') s('>', '}')
|
|
s('/', '\\') s('<', '{') s('-', '~')
|
|
END
|
|
|
|
#undef s
|
|
#undef END
|
|
#undef TRIGRAPH_MAP
|
|
|
|
/* A set of booleans indicating what CPP features each source language
|
|
requires. */
|
|
struct lang_flags
|
|
{
|
|
char c99;
|
|
char cplusplus;
|
|
char extended_numbers;
|
|
char extended_identifiers;
|
|
char std;
|
|
char cplusplus_comments;
|
|
char digraphs;
|
|
char uliterals;
|
|
char rliterals;
|
|
char user_literals;
|
|
};
|
|
|
|
static const struct lang_flags lang_defaults[] =
|
|
{ /* c99 c++ xnum xid std // digr ulit rlit user_literals */
|
|
/* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1, 0, 0, 0 },
|
|
/* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1, 1, 1, 0 },
|
|
/* GNUC11 */ { 1, 0, 1, 0, 0, 1, 1, 1, 1, 0 },
|
|
/* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
|
/* STDC94 */ { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0 },
|
|
/* STDC99 */ { 1, 0, 1, 0, 1, 1, 1, 0, 0, 0 },
|
|
/* STDC11 */ { 1, 0, 1, 0, 1, 1, 1, 1, 0, 0 },
|
|
/* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1, 0, 0, 0 },
|
|
/* CXX98 */ { 0, 1, 1, 0, 1, 1, 1, 0, 0, 0 },
|
|
/* GNUCXX11 */ { 1, 1, 1, 0, 0, 1, 1, 1, 1, 1 },
|
|
/* CXX11 */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
|
|
/* ASM */ { 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }
|
|
/* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX11, and
|
|
CXX11 when no longer experimental (when all uses of identifiers
|
|
in the compiler have been audited for correct handling of
|
|
extended identifiers). */
|
|
};
|
|
|
|
/* Sets internal flags correctly for a given language. */
|
|
void
|
|
cpp_set_lang (cpp_reader *pfile, enum c_lang lang)
|
|
{
|
|
const struct lang_flags *l = &lang_defaults[(int) lang];
|
|
|
|
CPP_OPTION (pfile, lang) = lang;
|
|
|
|
CPP_OPTION (pfile, c99) = l->c99;
|
|
CPP_OPTION (pfile, cplusplus) = l->cplusplus;
|
|
CPP_OPTION (pfile, extended_numbers) = l->extended_numbers;
|
|
CPP_OPTION (pfile, extended_identifiers) = l->extended_identifiers;
|
|
CPP_OPTION (pfile, std) = l->std;
|
|
CPP_OPTION (pfile, trigraphs) = l->std;
|
|
CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments;
|
|
CPP_OPTION (pfile, digraphs) = l->digraphs;
|
|
CPP_OPTION (pfile, uliterals) = l->uliterals;
|
|
CPP_OPTION (pfile, rliterals) = l->rliterals;
|
|
CPP_OPTION (pfile, user_literals) = l->user_literals;
|
|
}
|
|
|
|
/* Initialize library global state. */
|
|
static void
|
|
init_library (void)
|
|
{
|
|
static int initialized = 0;
|
|
|
|
if (! initialized)
|
|
{
|
|
initialized = 1;
|
|
|
|
_cpp_init_lexer ();
|
|
|
|
/* Set up the trigraph map. This doesn't need to do anything if
|
|
we were compiled with a compiler that supports C99 designated
|
|
initializers. */
|
|
init_trigraph_map ();
|
|
|
|
#ifdef ENABLE_NLS
|
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* Initialize a cpp_reader structure. */
|
|
cpp_reader *
|
|
cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
|
|
struct line_maps *line_table)
|
|
{
|
|
cpp_reader *pfile;
|
|
|
|
/* Initialize this instance of the library if it hasn't been already. */
|
|
init_library ();
|
|
|
|
pfile = XCNEW (cpp_reader);
|
|
memset (&pfile->base_context, 0, sizeof (pfile->base_context));
|
|
|
|
cpp_set_lang (pfile, lang);
|
|
CPP_OPTION (pfile, warn_multichar) = 1;
|
|
CPP_OPTION (pfile, discard_comments) = 1;
|
|
CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1;
|
|
CPP_OPTION (pfile, tabstop) = 8;
|
|
CPP_OPTION (pfile, operator_names) = 1;
|
|
CPP_OPTION (pfile, warn_trigraphs) = 2;
|
|
CPP_OPTION (pfile, warn_endif_labels) = 1;
|
|
CPP_OPTION (pfile, cpp_warn_deprecated) = 1;
|
|
CPP_OPTION (pfile, cpp_warn_long_long) = 0;
|
|
CPP_OPTION (pfile, dollars_in_ident) = 1;
|
|
CPP_OPTION (pfile, warn_dollars) = 1;
|
|
CPP_OPTION (pfile, warn_variadic_macros) = 1;
|
|
CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1;
|
|
/* By default, track locations of tokens resulting from macro
|
|
expansion. The '2' means, track the locations with the highest
|
|
accuracy. Read the comments for struct
|
|
cpp_options::track_macro_expansion to learn about the other
|
|
values. */
|
|
CPP_OPTION (pfile, track_macro_expansion) = 2;
|
|
CPP_OPTION (pfile, warn_normalize) = normalized_C;
|
|
CPP_OPTION (pfile, warn_literal_suffix) = 1;
|
|
|
|
/* Default CPP arithmetic to something sensible for the host for the
|
|
benefit of dumb users like fix-header. */
|
|
CPP_OPTION (pfile, precision) = CHAR_BIT * sizeof (long);
|
|
CPP_OPTION (pfile, char_precision) = CHAR_BIT;
|
|
CPP_OPTION (pfile, wchar_precision) = CHAR_BIT * sizeof (int);
|
|
CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);
|
|
CPP_OPTION (pfile, unsigned_char) = 0;
|
|
CPP_OPTION (pfile, unsigned_wchar) = 1;
|
|
CPP_OPTION (pfile, bytes_big_endian) = 1; /* does not matter */
|
|
|
|
/* Default to no charset conversion. */
|
|
CPP_OPTION (pfile, narrow_charset) = _cpp_default_encoding ();
|
|
CPP_OPTION (pfile, wide_charset) = 0;
|
|
|
|
/* Default the input character set to UTF-8. */
|
|
CPP_OPTION (pfile, input_charset) = _cpp_default_encoding ();
|
|
|
|
/* A fake empty "directory" used as the starting point for files
|
|
looked up without a search path. Name cannot be '/' because we
|
|
don't want to prepend anything at all to filenames using it. All
|
|
other entries are correct zero-initialized. */
|
|
pfile->no_search_path.name = (char *) "";
|
|
|
|
/* Initialize the line map. */
|
|
pfile->line_table = line_table;
|
|
|
|
/* Initialize lexer state. */
|
|
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
|
|
|
|
/* Set up static tokens. */
|
|
pfile->avoid_paste.type = CPP_PADDING;
|
|
pfile->avoid_paste.val.source = NULL;
|
|
pfile->eof.type = CPP_EOF;
|
|
pfile->eof.flags = 0;
|
|
|
|
/* Create a token buffer for the lexer. */
|
|
_cpp_init_tokenrun (&pfile->base_run, 250);
|
|
pfile->cur_run = &pfile->base_run;
|
|
pfile->cur_token = pfile->base_run.base;
|
|
|
|
/* Initialize the base context. */
|
|
pfile->context = &pfile->base_context;
|
|
pfile->base_context.c.macro = 0;
|
|
pfile->base_context.prev = pfile->base_context.next = 0;
|
|
|
|
/* Aligned and unaligned storage. */
|
|
pfile->a_buff = _cpp_get_buff (pfile, 0);
|
|
pfile->u_buff = _cpp_get_buff (pfile, 0);
|
|
|
|
/* Initialize table for push_macro/pop_macro. */
|
|
pfile->pushed_macros = 0;
|
|
|
|
/* Do not force token locations by default. */
|
|
pfile->forced_token_location_p = NULL;
|
|
|
|
/* The expression parser stack. */
|
|
_cpp_expand_op_stack (pfile);
|
|
|
|
/* Initialize the buffer obstack. */
|
|
_obstack_begin (&pfile->buffer_ob, 0, 0,
|
|
(void *(*) (long)) xmalloc,
|
|
(void (*) (void *)) free);
|
|
|
|
_cpp_init_files (pfile);
|
|
|
|
_cpp_init_hashtable (pfile, table);
|
|
|
|
return pfile;
|
|
}
|
|
|
|
/* Set the line_table entry in PFILE. This is called after reading a
|
|
PCH file, as the old line_table will be incorrect. */
|
|
void
|
|
cpp_set_line_map (cpp_reader *pfile, struct line_maps *line_table)
|
|
{
|
|
pfile->line_table = line_table;
|
|
}
|
|
|
|
/* Free resources used by PFILE. Accessing PFILE after this function
|
|
returns leads to undefined behavior. Returns the error count. */
|
|
void
|
|
cpp_destroy (cpp_reader *pfile)
|
|
{
|
|
cpp_context *context, *contextn;
|
|
struct def_pragma_macro *pmacro;
|
|
tokenrun *run, *runn;
|
|
int i;
|
|
|
|
free (pfile->op_stack);
|
|
|
|
while (CPP_BUFFER (pfile) != NULL)
|
|
_cpp_pop_buffer (pfile);
|
|
|
|
free (pfile->out.base);
|
|
|
|
if (pfile->macro_buffer)
|
|
{
|
|
free (pfile->macro_buffer);
|
|
pfile->macro_buffer = NULL;
|
|
pfile->macro_buffer_len = 0;
|
|
}
|
|
|
|
if (pfile->deps)
|
|
deps_free (pfile->deps);
|
|
obstack_free (&pfile->buffer_ob, 0);
|
|
|
|
_cpp_destroy_hashtable (pfile);
|
|
_cpp_cleanup_files (pfile);
|
|
_cpp_destroy_iconv (pfile);
|
|
|
|
_cpp_free_buff (pfile->a_buff);
|
|
_cpp_free_buff (pfile->u_buff);
|
|
_cpp_free_buff (pfile->free_buffs);
|
|
|
|
for (run = &pfile->base_run; run; run = runn)
|
|
{
|
|
runn = run->next;
|
|
free (run->base);
|
|
if (run != &pfile->base_run)
|
|
free (run);
|
|
}
|
|
|
|
for (context = pfile->base_context.next; context; context = contextn)
|
|
{
|
|
contextn = context->next;
|
|
free (context);
|
|
}
|
|
|
|
if (pfile->comments.entries)
|
|
{
|
|
for (i = 0; i < pfile->comments.count; i++)
|
|
free (pfile->comments.entries[i].comment);
|
|
|
|
free (pfile->comments.entries);
|
|
}
|
|
if (pfile->pushed_macros)
|
|
{
|
|
do
|
|
{
|
|
pmacro = pfile->pushed_macros;
|
|
pfile->pushed_macros = pmacro->next;
|
|
free (pmacro->name);
|
|
free (pmacro);
|
|
}
|
|
while (pfile->pushed_macros);
|
|
}
|
|
|
|
free (pfile);
|
|
}
|
|
|
|
/* This structure defines one built-in identifier. A node will be
|
|
entered in the hash table under the name NAME, with value VALUE.
|
|
|
|
There are two tables of these. builtin_array holds all the
|
|
"builtin" macros: these are handled by builtin_macro() in
|
|
macro.c. Builtin is somewhat of a misnomer -- the property of
|
|
interest is that these macros require special code to compute their
|
|
expansions. The value is a "cpp_builtin_type" enumerator.
|
|
|
|
operator_array holds the C++ named operators. These are keywords
|
|
which act as aliases for punctuators. In C++, they cannot be
|
|
altered through #define, and #if recognizes them as operators. In
|
|
C, these are not entered into the hash table at all (but see
|
|
<iso646.h>). The value is a token-type enumerator. */
|
|
struct builtin_macro
|
|
{
|
|
const uchar *const name;
|
|
const unsigned short len;
|
|
const unsigned short value;
|
|
const bool always_warn_if_redefined;
|
|
};
|
|
|
|
#define B(n, t, f) { DSC(n), t, f }
|
|
static const struct builtin_macro builtin_array[] =
|
|
{
|
|
B("__TIMESTAMP__", BT_TIMESTAMP, false),
|
|
B("__TIME__", BT_TIME, false),
|
|
B("__DATE__", BT_DATE, false),
|
|
B("__FILE__", BT_FILE, false),
|
|
B("__BASE_FILE__", BT_BASE_FILE, false),
|
|
B("__LINE__", BT_SPECLINE, true),
|
|
B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL, true),
|
|
B("__COUNTER__", BT_COUNTER, true),
|
|
/* Keep builtins not used for -traditional-cpp at the end, and
|
|
update init_builtins() if any more are added. */
|
|
B("_Pragma", BT_PRAGMA, true),
|
|
B("__STDC__", BT_STDC, true),
|
|
};
|
|
#undef B
|
|
|
|
struct builtin_operator
|
|
{
|
|
const uchar *const name;
|
|
const unsigned short len;
|
|
const unsigned short value;
|
|
};
|
|
|
|
#define B(n, t) { DSC(n), t }
|
|
static const struct builtin_operator operator_array[] =
|
|
{
|
|
B("and", CPP_AND_AND),
|
|
B("and_eq", CPP_AND_EQ),
|
|
B("bitand", CPP_AND),
|
|
B("bitor", CPP_OR),
|
|
B("compl", CPP_COMPL),
|
|
B("not", CPP_NOT),
|
|
B("not_eq", CPP_NOT_EQ),
|
|
B("or", CPP_OR_OR),
|
|
B("or_eq", CPP_OR_EQ),
|
|
B("xor", CPP_XOR),
|
|
B("xor_eq", CPP_XOR_EQ)
|
|
};
|
|
#undef B
|
|
|
|
/* Mark the C++ named operators in the hash table. */
|
|
static void
|
|
mark_named_operators (cpp_reader *pfile, int flags)
|
|
{
|
|
const struct builtin_operator *b;
|
|
|
|
for (b = operator_array;
|
|
b < (operator_array + ARRAY_SIZE (operator_array));
|
|
b++)
|
|
{
|
|
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
|
|
hp->flags |= flags;
|
|
hp->is_directive = 0;
|
|
hp->directive_index = b->value;
|
|
}
|
|
}
|
|
|
|
/* Helper function of cpp_type2name. Return the string associated with
|
|
named operator TYPE. */
|
|
const char *
|
|
cpp_named_operator2name (enum cpp_ttype type)
|
|
{
|
|
const struct builtin_operator *b;
|
|
|
|
for (b = operator_array;
|
|
b < (operator_array + ARRAY_SIZE (operator_array));
|
|
b++)
|
|
{
|
|
if (type == b->value)
|
|
return (const char *) b->name;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
cpp_init_special_builtins (cpp_reader *pfile)
|
|
{
|
|
const struct builtin_macro *b;
|
|
size_t n = ARRAY_SIZE (builtin_array);
|
|
|
|
if (CPP_OPTION (pfile, traditional))
|
|
n -= 2;
|
|
else if (! CPP_OPTION (pfile, stdc_0_in_system_headers)
|
|
|| CPP_OPTION (pfile, std))
|
|
n--;
|
|
|
|
for (b = builtin_array; b < builtin_array + n; b++)
|
|
{
|
|
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
|
|
hp->type = NT_MACRO;
|
|
hp->flags |= NODE_BUILTIN;
|
|
if (b->always_warn_if_redefined
|
|
|| CPP_OPTION (pfile, warn_builtin_macro_redefined))
|
|
hp->flags |= NODE_WARN;
|
|
hp->value.builtin = (enum cpp_builtin_type) b->value;
|
|
}
|
|
}
|
|
|
|
/* Read the builtins table above and enter them, and language-specific
|
|
macros, into the hash table. HOSTED is true if this is a hosted
|
|
environment. */
|
|
void
|
|
cpp_init_builtins (cpp_reader *pfile, int hosted)
|
|
{
|
|
cpp_init_special_builtins (pfile);
|
|
|
|
if (!CPP_OPTION (pfile, traditional)
|
|
&& (! CPP_OPTION (pfile, stdc_0_in_system_headers)
|
|
|| CPP_OPTION (pfile, std)))
|
|
_cpp_define_builtin (pfile, "__STDC__ 1");
|
|
|
|
if (CPP_OPTION (pfile, cplusplus))
|
|
{
|
|
if (CPP_OPTION (pfile, lang) == CLK_CXX11
|
|
|| CPP_OPTION (pfile, lang) == CLK_GNUCXX11)
|
|
_cpp_define_builtin (pfile, "__cplusplus 201103L");
|
|
else
|
|
_cpp_define_builtin (pfile, "__cplusplus 199711L");
|
|
}
|
|
else if (CPP_OPTION (pfile, lang) == CLK_ASM)
|
|
_cpp_define_builtin (pfile, "__ASSEMBLER__ 1");
|
|
else if (CPP_OPTION (pfile, lang) == CLK_STDC94)
|
|
_cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L");
|
|
else if (CPP_OPTION (pfile, lang) == CLK_STDC11
|
|
|| CPP_OPTION (pfile, lang) == CLK_GNUC11)
|
|
_cpp_define_builtin (pfile, "__STDC_VERSION__ 201112L");
|
|
else if (CPP_OPTION (pfile, c99))
|
|
_cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L");
|
|
|
|
if (CPP_OPTION (pfile, uliterals)
|
|
&& !CPP_OPTION (pfile, cplusplus))
|
|
{
|
|
_cpp_define_builtin (pfile, "__STDC_UTF_16__ 1");
|
|
_cpp_define_builtin (pfile, "__STDC_UTF_32__ 1");
|
|
}
|
|
|
|
if (hosted)
|
|
_cpp_define_builtin (pfile, "__STDC_HOSTED__ 1");
|
|
else
|
|
_cpp_define_builtin (pfile, "__STDC_HOSTED__ 0");
|
|
|
|
if (CPP_OPTION (pfile, objc))
|
|
_cpp_define_builtin (pfile, "__OBJC__ 1");
|
|
}
|
|
|
|
/* Sanity-checks are dependent on command-line options, so it is
|
|
called as a subroutine of cpp_read_main_file (). */
|
|
#if ENABLE_CHECKING
|
|
static void sanity_checks (cpp_reader *);
|
|
static void sanity_checks (cpp_reader *pfile)
|
|
{
|
|
cppchar_t test = 0;
|
|
size_t max_precision = 2 * CHAR_BIT * sizeof (cpp_num_part);
|
|
|
|
/* Sanity checks for assumptions about CPP arithmetic and target
|
|
type precisions made by cpplib. */
|
|
test--;
|
|
if (test < 1)
|
|
cpp_error (pfile, CPP_DL_ICE, "cppchar_t must be an unsigned type");
|
|
|
|
if (CPP_OPTION (pfile, precision) > max_precision)
|
|
cpp_error (pfile, CPP_DL_ICE,
|
|
"preprocessor arithmetic has maximum precision of %lu bits;"
|
|
" target requires %lu bits",
|
|
(unsigned long) max_precision,
|
|
(unsigned long) CPP_OPTION (pfile, precision));
|
|
|
|
if (CPP_OPTION (pfile, precision) < CPP_OPTION (pfile, int_precision))
|
|
cpp_error (pfile, CPP_DL_ICE,
|
|
"CPP arithmetic must be at least as precise as a target int");
|
|
|
|
if (CPP_OPTION (pfile, char_precision) < 8)
|
|
cpp_error (pfile, CPP_DL_ICE, "target char is less than 8 bits wide");
|
|
|
|
if (CPP_OPTION (pfile, wchar_precision) < CPP_OPTION (pfile, char_precision))
|
|
cpp_error (pfile, CPP_DL_ICE,
|
|
"target wchar_t is narrower than target char");
|
|
|
|
if (CPP_OPTION (pfile, int_precision) < CPP_OPTION (pfile, char_precision))
|
|
cpp_error (pfile, CPP_DL_ICE,
|
|
"target int is narrower than target char");
|
|
|
|
/* This is assumed in eval_token() and could be fixed if necessary. */
|
|
if (sizeof (cppchar_t) > sizeof (cpp_num_part))
|
|
cpp_error (pfile, CPP_DL_ICE,
|
|
"CPP half-integer narrower than CPP character");
|
|
|
|
if (CPP_OPTION (pfile, wchar_precision) > BITS_PER_CPPCHAR_T)
|
|
cpp_error (pfile, CPP_DL_ICE,
|
|
"CPP on this host cannot handle wide character constants over"
|
|
" %lu bits, but the target requires %lu bits",
|
|
(unsigned long) BITS_PER_CPPCHAR_T,
|
|
(unsigned long) CPP_OPTION (pfile, wchar_precision));
|
|
}
|
|
#else
|
|
# define sanity_checks(PFILE)
|
|
#endif
|
|
|
|
/* This is called after options have been parsed, and partially
|
|
processed. */
|
|
void
|
|
cpp_post_options (cpp_reader *pfile)
|
|
{
|
|
int flags;
|
|
|
|
sanity_checks (pfile);
|
|
|
|
post_options (pfile);
|
|
|
|
/* Mark named operators before handling command line macros. */
|
|
flags = 0;
|
|
if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
|
|
flags |= NODE_OPERATOR;
|
|
if (CPP_OPTION (pfile, warn_cxx_operator_names))
|
|
flags |= NODE_DIAGNOSTIC | NODE_WARN_OPERATOR;
|
|
if (flags != 0)
|
|
mark_named_operators (pfile, flags);
|
|
}
|
|
|
|
/* Setup for processing input from the file named FNAME, or stdin if
|
|
it is the empty string. Return the original filename
|
|
on success (e.g. foo.i->foo.c), or NULL on failure. */
|
|
const char *
|
|
cpp_read_main_file (cpp_reader *pfile, const char *fname)
|
|
{
|
|
if (CPP_OPTION (pfile, deps.style) != DEPS_NONE)
|
|
{
|
|
if (!pfile->deps)
|
|
pfile->deps = deps_init ();
|
|
|
|
/* Set the default target (if there is none already). */
|
|
deps_add_default_target (pfile->deps, fname);
|
|
}
|
|
|
|
pfile->main_file
|
|
= _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0);
|
|
if (_cpp_find_failed (pfile->main_file))
|
|
return NULL;
|
|
|
|
_cpp_stack_file (pfile, pfile->main_file, false);
|
|
|
|
/* For foo.i, read the original filename foo.c now, for the benefit
|
|
of the front ends. */
|
|
if (CPP_OPTION (pfile, preprocessed))
|
|
{
|
|
read_original_filename (pfile);
|
|
fname =
|
|
ORDINARY_MAP_FILE_NAME
|
|
((LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table)));
|
|
}
|
|
return fname;
|
|
}
|
|
|
|
/* For preprocessed files, if the first tokens are of the form # NUM.
|
|
handle the directive so we know the original file name. This will
|
|
generate file_change callbacks, which the front ends must handle
|
|
appropriately given their state of initialization. */
|
|
static void
|
|
read_original_filename (cpp_reader *pfile)
|
|
{
|
|
const cpp_token *token, *token1;
|
|
|
|
/* Lex ahead; if the first tokens are of the form # NUM, then
|
|
process the directive, otherwise back up. */
|
|
token = _cpp_lex_direct (pfile);
|
|
if (token->type == CPP_HASH)
|
|
{
|
|
pfile->state.in_directive = 1;
|
|
token1 = _cpp_lex_direct (pfile);
|
|
_cpp_backup_tokens (pfile, 1);
|
|
pfile->state.in_directive = 0;
|
|
|
|
/* If it's a #line directive, handle it. */
|
|
if (token1->type == CPP_NUMBER
|
|
&& _cpp_handle_directive (pfile, token->flags & PREV_WHITE))
|
|
{
|
|
read_original_directory (pfile);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* Backup as if nothing happened. */
|
|
_cpp_backup_tokens (pfile, 1);
|
|
}
|
|
|
|
/* For preprocessed files, if the tokens following the first filename
|
|
line is of the form # <line> "/path/name//", handle the
|
|
directive so we know the original current directory. */
|
|
static void
|
|
read_original_directory (cpp_reader *pfile)
|
|
{
|
|
const cpp_token *hash, *token;
|
|
|
|
/* Lex ahead; if the first tokens are of the form # NUM, then
|
|
process the directive, otherwise back up. */
|
|
hash = _cpp_lex_direct (pfile);
|
|
if (hash->type != CPP_HASH)
|
|
{
|
|
_cpp_backup_tokens (pfile, 1);
|
|
return;
|
|
}
|
|
|
|
token = _cpp_lex_direct (pfile);
|
|
|
|
if (token->type != CPP_NUMBER)
|
|
{
|
|
_cpp_backup_tokens (pfile, 2);
|
|
return;
|
|
}
|
|
|
|
token = _cpp_lex_direct (pfile);
|
|
|
|
if (token->type != CPP_STRING
|
|
|| ! (token->val.str.len >= 5
|
|
&& IS_DIR_SEPARATOR (token->val.str.text[token->val.str.len-2])
|
|
&& IS_DIR_SEPARATOR (token->val.str.text[token->val.str.len-3])))
|
|
{
|
|
_cpp_backup_tokens (pfile, 3);
|
|
return;
|
|
}
|
|
|
|
if (pfile->cb.dir_change)
|
|
{
|
|
char *debugdir = (char *) alloca (token->val.str.len - 3);
|
|
|
|
memcpy (debugdir, (const char *) token->val.str.text + 1,
|
|
token->val.str.len - 4);
|
|
debugdir[token->val.str.len - 4] = '\0';
|
|
|
|
pfile->cb.dir_change (pfile, debugdir);
|
|
}
|
|
}
|
|
|
|
/* This is called at the end of preprocessing. It pops the last
|
|
buffer and writes dependency output.
|
|
|
|
Maybe it should also reset state, such that you could call
|
|
cpp_start_read with a new filename to restart processing. */
|
|
void
|
|
cpp_finish (cpp_reader *pfile, FILE *deps_stream)
|
|
{
|
|
/* Warn about unused macros before popping the final buffer. */
|
|
if (CPP_OPTION (pfile, warn_unused_macros))
|
|
cpp_forall_identifiers (pfile, _cpp_warn_if_unused_macro, NULL);
|
|
|
|
/* lex.c leaves the final buffer on the stack. This it so that
|
|
it returns an unending stream of CPP_EOFs to the client. If we
|
|
popped the buffer, we'd dereference a NULL buffer pointer and
|
|
segfault. It's nice to allow the client to do worry-free excess
|
|
cpp_get_token calls. */
|
|
while (pfile->buffer)
|
|
_cpp_pop_buffer (pfile);
|
|
|
|
if (CPP_OPTION (pfile, deps.style) != DEPS_NONE
|
|
&& deps_stream)
|
|
{
|
|
deps_write (pfile->deps, deps_stream, 72);
|
|
|
|
if (CPP_OPTION (pfile, deps.phony_targets))
|
|
deps_phony_targets (pfile->deps, deps_stream);
|
|
}
|
|
|
|
/* Report on headers that could use multiple include guards. */
|
|
if (CPP_OPTION (pfile, print_include_names))
|
|
_cpp_report_missing_guards (pfile);
|
|
}
|
|
|
|
static void
|
|
post_options (cpp_reader *pfile)
|
|
{
|
|
/* -Wtraditional is not useful in C++ mode. */
|
|
if (CPP_OPTION (pfile, cplusplus))
|
|
CPP_OPTION (pfile, cpp_warn_traditional) = 0;
|
|
|
|
/* Permanently disable macro expansion if we are rescanning
|
|
preprocessed text. Read preprocesed source in ISO mode. */
|
|
if (CPP_OPTION (pfile, preprocessed))
|
|
{
|
|
if (!CPP_OPTION (pfile, directives_only))
|
|
pfile->state.prevent_expansion = 1;
|
|
CPP_OPTION (pfile, traditional) = 0;
|
|
}
|
|
|
|
if (CPP_OPTION (pfile, warn_trigraphs) == 2)
|
|
CPP_OPTION (pfile, warn_trigraphs) = !CPP_OPTION (pfile, trigraphs);
|
|
|
|
if (CPP_OPTION (pfile, traditional))
|
|
{
|
|
CPP_OPTION (pfile, cplusplus_comments) = 0;
|
|
|
|
CPP_OPTION (pfile, trigraphs) = 0;
|
|
CPP_OPTION (pfile, warn_trigraphs) = 0;
|
|
}
|
|
}
|