Mercurial > hg > CbC > CbC_gcc
diff gcc/tree.h @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children | 351920fa3827 |
line wrap: on
line diff
--- a/gcc/tree.h Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/tree.h Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* Definitions for the ubiquitous 'tree' type for GNU compilers. - Copyright (C) 1989-2018 Free Software Foundation, Inc. + Copyright (C) 1989-2020 Free Software Foundation, Inc. This file is part of GCC. @@ -94,6 +94,10 @@ (MARK_TS_TYPE_COMMON (C), \ tree_contains_struct[C][TS_TYPE_WITH_LANG_SPECIFIC] = true) +#define MARK_TS_TYPE_NON_COMMON(C) \ + (MARK_TS_TYPE_WITH_LANG_SPECIFIC (C), \ + tree_contains_struct[C][TS_TYPE_NON_COMMON] = true) \ + #define MARK_TS_DECL_MINIMAL(C) \ (MARK_TS_COMMON (C), \ tree_contains_struct[C][TS_DECL_MINIMAL] = true) @@ -114,6 +118,10 @@ (MARK_TS_DECL_WITH_VIS (C), \ tree_contains_struct[C][TS_DECL_NON_COMMON] = true) +#define MARK_TS_EXP(C) \ + (MARK_TS_TYPED (C), \ + tree_contains_struct[C][TS_EXP] = true) + /* Returns the string representing CLASS. */ #define TREE_CODE_CLASS_STRING(CLASS)\ @@ -131,6 +139,12 @@ #define CONSTANT_CLASS_P(NODE)\ (TREE_CODE_CLASS (TREE_CODE (NODE)) == tcc_constant) +/* Nonzero if NODE represents a constant, or is a location wrapper + around such a node. */ + +#define CONSTANT_CLASS_OR_WRAPPER_P(NODE)\ + (CONSTANT_CLASS_P (tree_strip_any_location_wrapper (NODE))) + /* Nonzero if NODE represents a type. */ #define TYPE_P(NODE)\ @@ -429,6 +443,8 @@ TREE_CHECK3 (T, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE) #define NOT_RECORD_OR_UNION_CHECK(T) \ TREE_NOT_CHECK3 (T, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE) +#define ARRAY_OR_INTEGER_TYPE_CHECK(T) \ + TREE_CHECK2 (T, ARRAY_TYPE, INTEGER_TYPE) #define NUMERICAL_TYPE_CHECK(T) \ TREE_CHECK5 (T, INTEGER_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, REAL_TYPE, \ @@ -698,6 +714,11 @@ /* Used to indicate that this TYPE represents a compiler-generated entity. */ #define TYPE_ARTIFICIAL(NODE) (TYPE_CHECK (NODE)->base.nowarning_flag) +/* True if the type is indivisible at the source level, i.e. if its + component parts cannot be accessed directly. This is used to suppress + normal GNU extensions for target-specific vector types. */ +#define TYPE_INDIVISIBLE_P(NODE) (TYPE_CHECK (NODE)->type_common.indivisible_p) + /* In an IDENTIFIER_NODE, this means that assemble_name was called with this string as an argument. */ #define TREE_SYMBOL_REFERENCED(NODE) \ @@ -894,6 +915,11 @@ (TREE_CHECK2 (NODE, VAR_DECL, \ RESULT_DECL)->decl_common.decl_nonshareable_flag) +/* In a PARM_DECL, set for Fortran hidden string length arguments that some + buggy callers don't pass to the callee. */ +#define DECL_HIDDEN_STRING_LENGTH(NODE) \ + (TREE_CHECK (NODE, PARM_DECL)->decl_common.decl_nonshareable_flag) + /* In a CALL_EXPR, means that the call is the jump from a thunk to the thunked-to function. */ #define CALL_FROM_THUNK_P(NODE) (CALL_EXPR_CHECK (NODE)->base.protected_flag) @@ -917,6 +943,11 @@ #define TREE_DEPRECATED(NODE) \ ((NODE)->base.deprecated_flag) +/* Nonzero indicates an IDENTIFIER_NODE that names an anonymous + aggregate, (as created by anon_aggr_name_format). */ +#define IDENTIFIER_ANON_P(NODE) \ + (IDENTIFIER_NODE_CHECK (NODE)->base.private_flag) + /* Nonzero in an IDENTIFIER_NODE if the name is a local alias, whose uses are to be substituted for uses of the TREE_CHAINed identifier. */ #define IDENTIFIER_TRANSPARENT_ALIAS(NODE) \ @@ -1175,6 +1206,19 @@ extern tree maybe_wrap_with_location (tree, location_t); +extern int suppress_location_wrappers; + +/* A class for suppressing the creation of location wrappers. + Location wrappers will not be created during the lifetime + of an instance of this class. */ + +class auto_suppress_location_wrappers +{ + public: + auto_suppress_location_wrappers () { ++suppress_location_wrappers; } + ~auto_suppress_location_wrappers () { --suppress_location_wrappers; } +}; + /* In a TARGET_EXPR node. */ #define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0) #define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1) @@ -1245,6 +1289,9 @@ ASM_OPERAND with no operands. */ #define ASM_INPUT_P(NODE) (ASM_EXPR_CHECK (NODE)->base.static_flag) #define ASM_VOLATILE_P(NODE) (ASM_EXPR_CHECK (NODE)->base.public_flag) +/* Nonzero if we want to consider this asm as minimum length and cost + for inlining decisions. */ +#define ASM_INLINE_P(NODE) (ASM_EXPR_CHECK (NODE)->base.protected_flag) /* COND_EXPR accessors. */ #define COND_EXPR_COND(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 0)) @@ -1306,9 +1353,9 @@ /* Generic accessors for OMP nodes that keep the body as operand 0, and clauses as operand 1. */ #define OMP_BODY(NODE) \ - TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_TASKGROUP), 0) + TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_MASTER), 0) #define OMP_CLAUSES(NODE) \ - TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_SINGLE), 1) + TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_SCAN), 1) /* Generic accessors for OMP nodes that keep clauses as operand 0. */ #define OMP_STANDALONE_CLAUSES(NODE) \ @@ -1349,14 +1396,14 @@ #define OMP_TASKREG_BODY(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 0) #define OMP_TASKREG_CLAUSES(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 1) -#define OMP_LOOP_CHECK(NODE) TREE_RANGE_CHECK (NODE, OMP_FOR, OACC_LOOP) -#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 0) -#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 1) -#define OMP_FOR_INIT(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 2) -#define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 3) -#define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 4) -#define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 5) -#define OMP_FOR_ORIG_DECLS(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 6) +#define OMP_LOOPING_CHECK(NODE) TREE_RANGE_CHECK (NODE, OMP_FOR, OACC_LOOP) +#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 0) +#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 1) +#define OMP_FOR_INIT(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 2) +#define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 3) +#define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 4) +#define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 5) +#define OMP_FOR_ORIG_DECLS(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 6) #define OMP_SECTIONS_BODY(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 0) #define OMP_SECTIONS_CLAUSES(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 1) @@ -1369,6 +1416,8 @@ #define OMP_MASTER_BODY(NODE) TREE_OPERAND (OMP_MASTER_CHECK (NODE), 0) #define OMP_TASKGROUP_BODY(NODE) TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 0) +#define OMP_TASKGROUP_CLAUSES(NODE) \ + TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 1) #define OMP_ORDERED_BODY(NODE) TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 0) #define OMP_ORDERED_CLAUSES(NODE) TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 1) @@ -1397,6 +1446,9 @@ #define OMP_TARGET_EXIT_DATA_CLAUSES(NODE)\ TREE_OPERAND (OMP_TARGET_EXIT_DATA_CHECK (NODE), 0) +#define OMP_SCAN_BODY(NODE) TREE_OPERAND (OMP_SCAN_CHECK (NODE), 0) +#define OMP_SCAN_CLAUSES(NODE) TREE_OPERAND (OMP_SCAN_CHECK (NODE), 1) + #define OMP_CLAUSE_SIZE(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \ OMP_CLAUSE_FROM, \ @@ -1406,7 +1458,7 @@ #define OMP_CLAUSE_DECL(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \ OMP_CLAUSE_PRIVATE, \ - OMP_CLAUSE__LOOPTEMP_), 0) + OMP_CLAUSE__SCANTEMP_), 0) #define OMP_CLAUSE_HAS_LOCATION(NODE) \ (LOCATION_LOCUS ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus) \ != UNKNOWN_LOCATION) @@ -1432,11 +1484,10 @@ #define OMP_TARGET_COMBINED(NODE) \ (OMP_TARGET_CHECK (NODE)->base.private_flag) -/* True if OMP_ATOMIC* is supposed to be sequentially consistent - as opposed to relaxed. */ -#define OMP_ATOMIC_SEQ_CST(NODE) \ +/* Memory order for OMP_ATOMIC*. */ +#define OMP_ATOMIC_MEMORY_ORDER(NODE) \ (TREE_RANGE_CHECK (NODE, OMP_ATOMIC, \ - OMP_ATOMIC_CAPTURE_NEW)->base.private_flag) + OMP_ATOMIC_CAPTURE_NEW)->base.u.omp_atomic_memory_order) /* True on a PRIVATE clause if its decl is kept around for debugging information only and its DECL_VALUE_EXPR is supposed to point @@ -1459,6 +1510,11 @@ #define OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT(NODE) \ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_FIRSTPRIVATE)->base.public_flag) +/* True on a FIRSTPRIVATE clause if only the reference and not what it refers + to should be firstprivatized. */ +#define OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE(NODE) \ + TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_FIRSTPRIVATE)) + /* True on a LASTPRIVATE clause if a FIRSTPRIVATE clause for the same decl is present in the chain. */ #define OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE(NODE) \ @@ -1470,12 +1526,17 @@ #define OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ(NODE) \ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init -/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop construct - (thus should be lastprivate on the outer taskloop and firstprivate on - task). */ -#define OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV(NODE) \ +/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop or + loop construct (thus should be lastprivate on the outer taskloop and + firstprivate on task for the taskloop construct and carefully handled + for loop construct). */ +#define OMP_CLAUSE_LASTPRIVATE_LOOP_IV(NODE) \ TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE)) +/* True if a LASTPRIVATE clause has CONDITIONAL: modifier. */ +#define OMP_CLAUSE_LASTPRIVATE_CONDITIONAL(NODE) \ + TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE)) + /* True on a SHARED clause if a FIRSTPRIVATE clause for the same decl is present in the chain (this can happen only for taskloop with FIRSTPRIVATE/LASTPRIVATE on it originally. */ @@ -1561,13 +1622,22 @@ treatment if OMP_CLAUSE_SIZE is zero. */ #define OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION(NODE) \ TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)) -/* Nonzero if this map clause is for an ACC parallel reduction variable. */ +/* Nonzero if this map clause is for an OpenACC compute construct's reduction + variable. */ #define OMP_CLAUSE_MAP_IN_REDUCTION(NODE) \ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)) +/* True on an OMP_CLAUSE_USE_DEVICE_PTR with an OpenACC 'if_present' + clause. */ +#define OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_USE_DEVICE_PTR)->base.public_flag) + #define OMP_CLAUSE_PROC_BIND_KIND(NODE) \ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PROC_BIND)->omp_clause.subcode.proc_bind_kind) +#define OMP_CLAUSE_DEVICE_TYPE_KIND(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE_TYPE)->omp_clause.subcode.device_type_kind) + #define OMP_CLAUSE_COLLAPSE_EXPR(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_COLLAPSE), 0) #define OMP_CLAUSE_COLLAPSE_ITERVAR(NODE) \ @@ -1579,24 +1649,38 @@ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ORDERED), 0) #define OMP_CLAUSE_REDUCTION_CODE(NODE) \ - (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)->omp_clause.subcode.reduction_code) + (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION)->omp_clause.subcode.reduction_code) #define OMP_CLAUSE_REDUCTION_INIT(NODE) \ - OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 1) + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION), 1) #define OMP_CLAUSE_REDUCTION_MERGE(NODE) \ - OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 2) + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION), 2) #define OMP_CLAUSE_REDUCTION_GIMPLE_INIT(NODE) \ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init #define OMP_CLAUSE_REDUCTION_GIMPLE_MERGE(NODE) \ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_merge #define OMP_CLAUSE_REDUCTION_PLACEHOLDER(NODE) \ - OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 3) + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION), 3) #define OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER(NODE) \ - OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 4) + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION), 4) /* True if a REDUCTION clause may reference the original list item (omp_orig) in its OMP_CLAUSE_REDUCTION_{,GIMPLE_}INIT. */ #define OMP_CLAUSE_REDUCTION_OMP_ORIG_REF(NODE) \ - (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)->base.public_flag) + (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION)->base.public_flag) + +/* True if a REDUCTION clause has task reduction-modifier. */ +#define OMP_CLAUSE_REDUCTION_TASK(NODE) \ + TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)) + +/* True if a REDUCTION clause has inscan reduction-modifier. */ +#define OMP_CLAUSE_REDUCTION_INSCAN(NODE) \ + TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)) /* True if a LINEAR clause doesn't need copy in. True for iterator vars which are always initialized inside of the loop construct, false otherwise. */ @@ -1665,6 +1749,21 @@ #define OMP_CLAUSE_DEFAULT_KIND(NODE) \ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULT)->omp_clause.subcode.default_kind) +#define OMP_CLAUSE_DEFAULTMAP_KIND(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULTMAP)->omp_clause.subcode.defaultmap_kind) +#define OMP_CLAUSE_DEFAULTMAP_CATEGORY(NODE) \ + ((enum omp_clause_defaultmap_kind) \ + (OMP_CLAUSE_DEFAULTMAP_KIND (NODE) & OMP_CLAUSE_DEFAULTMAP_CATEGORY_MASK)) +#define OMP_CLAUSE_DEFAULTMAP_BEHAVIOR(NODE) \ + ((enum omp_clause_defaultmap_kind) \ + (OMP_CLAUSE_DEFAULTMAP_KIND (NODE) & OMP_CLAUSE_DEFAULTMAP_MASK)) +#define OMP_CLAUSE_DEFAULTMAP_SET_KIND(NODE, BEHAVIOR, CATEGORY) \ + (OMP_CLAUSE_DEFAULTMAP_KIND (NODE) \ + = (enum omp_clause_defaultmap_kind) (CATEGORY | BEHAVIOR)) + +#define OMP_CLAUSE_BIND_KIND(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_BIND)->omp_clause.subcode.bind_kind) + #define OMP_CLAUSE_TILE_LIST(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_TILE), 0) #define OMP_CLAUSE_TILE_ITERVAR(NODE) \ @@ -1680,6 +1779,21 @@ #define OMP_CLAUSE__GRIDDIM__GROUP(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__GRIDDIM_), 1) +/* _CONDTEMP_ holding temporary with iteration count. */ +#define OMP_CLAUSE__CONDTEMP__ITER(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__CONDTEMP_)->base.public_flag) + +/* _SCANTEMP_ holding temporary with pointer to thread's local array; + allocation. */ +#define OMP_CLAUSE__SCANTEMP__ALLOC(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__SCANTEMP_)->base.public_flag) + +/* _SCANTEMP_ holding temporary with a control variable for deallocation; + one boolean_type_node for test whether alloca was used, another one + to pass to __builtin_stack_restore or free. */ +#define OMP_CLAUSE__SCANTEMP__CONTROL(NODE) \ + TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__SCANTEMP_)) + /* SSA_NAME accessors. */ /* Whether SSA_NAME NODE is a virtual operand. This simply caches the @@ -1853,7 +1967,10 @@ so they must be checked as well. */ #define TYPE_UID(NODE) (TYPE_CHECK (NODE)->type_common.uid) +/* Type size in bits as a tree expression. Need not be constant + and may be null. */ #define TYPE_SIZE(NODE) (TYPE_CHECK (NODE)->type_common.size) +/* Likewise, type size in bytes. */ #define TYPE_SIZE_UNIT(NODE) (TYPE_CHECK (NODE)->type_common.size_unit) #define TYPE_POINTER_TO(NODE) (TYPE_CHECK (NODE)->type_common.pointer_to) #define TYPE_REFERENCE_TO(NODE) (TYPE_CHECK (NODE)->type_common.reference_to) @@ -2039,7 +2156,14 @@ /* If set in an ARRAY_TYPE, indicates a string type (for languages that distinguish string from array of char). If set in a INTEGER_TYPE, indicates a character type. */ -#define TYPE_STRING_FLAG(NODE) (TYPE_CHECK (NODE)->type_common.string_flag) +#define TYPE_STRING_FLAG(NODE) \ + (ARRAY_OR_INTEGER_TYPE_CHECK (NODE)->type_common.string_flag) + +/* If set for RECORD_TYPE or UNION_TYPE it indicates that the type conforms + to the C++ one definition rule. This is used for LTO canonical type + computation. */ +#define TYPE_CXX_ODR_P(NODE) \ + (RECORD_OR_UNION_CHECK (NODE)->type_common.string_flag) /* Nonzero in a VECTOR_TYPE if the frontends should not emit warnings about missing conversions to other vector types of the same size. */ @@ -2374,7 +2498,7 @@ #define DECL_INITIAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.initial) /* Holds the size of the datum, in bits, as a tree expression. - Need not be constant. */ + Need not be constant and may be null. */ #define DECL_SIZE(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size) /* Likewise for the size in bytes. */ #define DECL_SIZE_UNIT(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size_unit) @@ -2412,10 +2536,10 @@ (DECL_COMMON_CHECK (NODE)->decl_common.mode = (MODE)) /* For FUNCTION_DECL, if it is built-in, this identifies which built-in - operation it is. Note, however, that this field is overloaded, with - DECL_BUILT_IN_CLASS as the discriminant, so the latter must always be - checked before any access to the former. */ -#define DECL_FUNCTION_CODE(NODE) \ + operation it is. This is only intended for low-level accesses; + normally DECL_FUNCTION_CODE, DECL_FE_FUNCTION_CODE or DECL_MD_FUNCTION + should be used instead. */ +#define DECL_UNCHECKED_FUNCTION_CODE(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.function_code) /* Test if FCODE is a function code for an alloca operation. */ @@ -2784,8 +2908,8 @@ #define DECL_VISIBILITY(NODE) \ (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility) -/* Nonzero means that the decl had its visibility specified rather than - being inferred. */ +/* Nonzero means that the decl (or an enclosing scope) had its + visibility specified rather than being inferred. */ #define DECL_VISIBILITY_SPECIFIED(NODE) \ (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility_specified) @@ -2892,11 +3016,45 @@ #define DECL_IS_MALLOC(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.malloc_flag) +/* Macro for direct set and get of function_decl.decl_type. */ +#define FUNCTION_DECL_DECL_TYPE(NODE) \ + (NODE->function_decl.decl_type) + +/* Set decl_type of a DECL. Set it to T when SET is true, or reset + it to NONE. */ + +static inline void +set_function_decl_type (tree decl, function_decl_type t, bool set) +{ + if (set) + { + gcc_assert (FUNCTION_DECL_DECL_TYPE (decl) == NONE + || FUNCTION_DECL_DECL_TYPE (decl) == t); + decl->function_decl.decl_type = t; + } + else if (FUNCTION_DECL_DECL_TYPE (decl) == t) + FUNCTION_DECL_DECL_TYPE (decl) = NONE; +} + /* Nonzero in a FUNCTION_DECL means this function should be treated as C++ operator new, meaning that it returns a pointer for which we should not use type based aliasing. */ -#define DECL_IS_OPERATOR_NEW(NODE) \ - (FUNCTION_DECL_CHECK (NODE)->function_decl.operator_new_flag) +#define DECL_IS_OPERATOR_NEW_P(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_NEW) + +#define DECL_IS_REPLACEABLE_OPERATOR_NEW_P(NODE) \ + (DECL_IS_OPERATOR_NEW_P (NODE) && DECL_IS_MALLOC (NODE)) + +#define DECL_SET_IS_OPERATOR_NEW(NODE, VAL) \ + set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_NEW, VAL) + +/* Nonzero in a FUNCTION_DECL means this function should be treated as + C++ operator delete. */ +#define DECL_IS_OPERATOR_DELETE_P(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_DELETE) + +#define DECL_SET_IS_OPERATOR_DELETE(NODE, VAL) \ + set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_DELETE, VAL) /* Nonzero in a FUNCTION_DECL means this function may return more than once. */ @@ -3003,10 +3161,9 @@ #define DECL_STRUCT_FUNCTION(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.f) - /* For a builtin function, identify which part of the compiler defined it. */ #define DECL_BUILT_IN_CLASS(NODE) \ - (FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class) + ((built_in_class) FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class) /* In FUNCTION_DECL, a chain of ..._DECL nodes. */ #define DECL_ARGUMENTS(NODE) \ @@ -3041,8 +3198,11 @@ (FUNCTION_DECL_CHECK (NODE)->decl_with_vis.cxx_destructor) /* In FUNCTION_DECL, this is set if this function is a lambda function. */ -#define DECL_LAMBDA_FUNCTION(NODE) \ - (FUNCTION_DECL_CHECK (NODE)->function_decl.lambda_function) +#define DECL_LAMBDA_FUNCTION_P(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == LAMBDA_FUNCTION) + +#define DECL_SET_LAMBDA_FUNCTION(NODE, VAL) \ + set_function_decl_type (FUNCTION_DECL_CHECK (NODE), LAMBDA_FUNCTION, VAL) /* In FUNCTION_DECL that represent an virtual method this is set when the method is final. */ @@ -3676,14 +3836,16 @@ unsigned int precision = VECTOR_TYPE_CHECK (node)->type_common.precision; if (NUM_POLY_INT_COEFFS == 2) { + /* See the corresponding code in SET_TYPE_VECTOR_SUBPARTS for a + description of the encoding. */ poly_uint64 res = 0; - res.coeffs[0] = 1 << (precision & 0xff); + res.coeffs[0] = HOST_WIDE_INT_1U << (precision & 0xff); if (precision & 0x100) - res.coeffs[1] = 1 << (precision & 0xff); + res.coeffs[1] = HOST_WIDE_INT_1U << (precision & 0xff); return res; } else - return 1 << precision; + return HOST_WIDE_INT_1U << precision; } /* Set the number of elements in VECTOR_TYPE NODE to SUBPARTS, which must @@ -3698,6 +3860,21 @@ gcc_assert (index >= 0); if (NUM_POLY_INT_COEFFS == 2) { + /* We have two coefficients that are each in the range 1 << [0, 63], + so supporting all combinations would require 6 bits per coefficient + and 12 bits in total. Since the precision field is only 10 bits + in size, we need to be more restrictive than that. + + At present, coeff[1] is always either 0 (meaning that the number + of units is constant) or equal to coeff[0] (meaning that the number + of units is N + X * N for some target-dependent zero-based runtime + parameter X). We can therefore encode coeff[1] in a single bit. + + The most compact encoding would be to use mask 0x3f for coeff[0] + and 0x40 for coeff[1], leaving 0x380 unused. It's possible to + get slightly more efficient code on some hosts if we instead + treat the shift amount as an independent byte, so here we use + 0xff for coeff[0] and 0x100 for coeff[1]. */ unsigned HOST_WIDE_INT coeff1 = subparts.coeffs[1]; gcc_assert (coeff1 == 0 || coeff1 == coeff0); VECTOR_TYPE_CHECK (node)->type_common.precision @@ -3725,6 +3902,61 @@ return true; } +/* Return the built-in function that DECL represents, given that it is known + to be a FUNCTION_DECL with built-in class BUILT_IN_NORMAL. */ +inline built_in_function +DECL_FUNCTION_CODE (const_tree decl) +{ + const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl; + gcc_checking_assert (fndecl.built_in_class == BUILT_IN_NORMAL); + return (built_in_function) fndecl.function_code; +} + +/* Return the target-specific built-in function that DECL represents, + given that it is known to be a FUNCTION_DECL with built-in class + BUILT_IN_MD. */ +inline int +DECL_MD_FUNCTION_CODE (const_tree decl) +{ + const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl; + gcc_checking_assert (fndecl.built_in_class == BUILT_IN_MD); + return fndecl.function_code; +} + +/* Return the frontend-specific built-in function that DECL represents, + given that it is known to be a FUNCTION_DECL with built-in class + BUILT_IN_FRONTEND. */ +inline int +DECL_FE_FUNCTION_CODE (const_tree decl) +{ + const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl; + gcc_checking_assert (fndecl.built_in_class == BUILT_IN_FRONTEND); + return fndecl.function_code; +} + +/* Record that FUNCTION_DECL DECL represents built-in function FCODE of + class FCLASS. */ +inline void +set_decl_built_in_function (tree decl, built_in_class fclass, + unsigned int fcode) +{ + tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl; + fndecl.built_in_class = fclass; + fndecl.function_code = fcode; +} + +/* Record that FUNCTION_DECL NEWDECL represents the same built-in function + as OLDDECL (or none, if OLDDECL doesn't represent a built-in function). */ +inline void +copy_decl_built_in_function (tree newdecl, const_tree olddecl) +{ + tree_function_decl &newfndecl = FUNCTION_DECL_CHECK (newdecl)->function_decl; + const tree_function_decl &oldfndecl + = FUNCTION_DECL_CHECK (olddecl)->function_decl; + newfndecl.built_in_class = oldfndecl.built_in_class; + newfndecl.function_code = oldfndecl.function_code; +} + /* In NON_LVALUE_EXPR and VIEW_CONVERT_EXPR, set when this node is merely a wrapper added to express a location_t on behalf of the node's child (e.g. by maybe_wrap_with_location). */ @@ -3871,9 +4103,6 @@ #define dfloat32_type_node global_trees[TI_DFLOAT32_TYPE] #define dfloat64_type_node global_trees[TI_DFLOAT64_TYPE] #define dfloat128_type_node global_trees[TI_DFLOAT128_TYPE] -#define dfloat32_ptr_type_node global_trees[TI_DFLOAT32_PTR_TYPE] -#define dfloat64_ptr_type_node global_trees[TI_DFLOAT64_PTR_TYPE] -#define dfloat128_ptr_type_node global_trees[TI_DFLOAT128_PTR_TYPE] /* The fixed-point types. */ #define sat_short_fract_type_node global_trees[TI_SAT_SFRACT_TYPE] @@ -3978,6 +4207,11 @@ #define current_target_pragma global_trees[TI_CURRENT_TARGET_PRAGMA] #define current_optimize_pragma global_trees[TI_CURRENT_OPTIMIZE_PRAGMA] +/* SCEV analyzer global shared trees. */ +#define chrec_not_analyzed_yet NULL_TREE +#define chrec_dont_know global_trees[TI_CHREC_DONT_KNOW] +#define chrec_known global_trees[TI_CHREC_KNOWN] + #define char_type_node integer_types[itk_char] #define signed_char_type_node integer_types[itk_signed_char] #define unsigned_char_type_node integer_types[itk_unsigned_char] @@ -4146,11 +4380,13 @@ extern tree make_vector (unsigned, unsigned CXX_MEM_STAT_INFO); extern tree build_vector_from_ctor (tree, vec<constructor_elt, va_gc> *); extern tree build_vector_from_val (tree, tree); +extern tree build_uniform_cst (tree, tree); extern tree build_vec_series (tree, tree, tree); extern tree build_index_vector (tree, poly_uint64, poly_uint64); +extern tree build_vector_a_then_b (tree, unsigned int, tree, tree); extern void recompute_constructor_flags (tree); extern void verify_constructor_flags (tree); -extern tree build_constructor (tree, vec<constructor_elt, va_gc> *); +extern tree build_constructor (tree, vec<constructor_elt, va_gc> * CXX_MEM_STAT_INFO); extern tree build_constructor_single (tree, tree, tree); extern tree build_constructor_from_list (tree, tree); extern tree build_constructor_va (tree, int, ...); @@ -4194,7 +4430,8 @@ extern tree maybe_build_call_expr_loc (location_t, combined_fn, tree, int, ...); extern tree build_alloca_call_expr (tree, unsigned int, HOST_WIDE_INT); -extern tree build_string_literal (int, const char *); +extern tree build_string_literal (int, const char *, tree = char_type_node, + unsigned HOST_WIDE_INT = HOST_WIDE_INT_M1U); /* Construct various nodes representing data types. */ @@ -4208,8 +4445,7 @@ extern tree build_reference_type (tree); extern tree build_vector_type_for_mode (tree, machine_mode); extern tree build_vector_type (tree, poly_int64); -extern tree build_truth_vector_type (poly_uint64, poly_uint64); -extern tree build_same_sized_truth_vector_type (tree vectype); +extern tree build_truth_vector_type_for_mode (poly_uint64, machine_mode); extern tree build_opaque_vector_type (tree, poly_int64); extern tree build_index_type (tree); extern tree build_array_type (tree, tree, bool = false); @@ -4288,7 +4524,19 @@ extern unsigned int tree_int_cst_min_precision (tree, signop); extern tree strip_array_types (tree); extern tree excess_precision_type (tree); -extern bool valid_constant_size_p (const_tree); + +/* Desription of the reason why the argument of valid_constant_size_p + is not a valid size. */ +enum cst_size_error { + cst_size_ok, + cst_size_not_constant, + cst_size_negative, + cst_size_too_big, + cst_size_overflow +}; + +extern bool valid_constant_size_p (const_tree, cst_size_error * = NULL); +extern tree max_object_size (); /* Return true if T holds a value that can be represented as a poly_int64 without loss of precision. Store the value in *VALUE if so. */ @@ -4447,6 +4695,7 @@ combinations indicate definitive answers. */ extern bool initializer_zerop (const_tree, bool * = NULL); +extern bool initializer_each_zero_or_onep (const_tree); extern wide_int vector_cst_int_elt (const_tree, unsigned int); extern tree vector_cst_elt (const_tree, unsigned int); @@ -4456,6 +4705,14 @@ extern tree uniform_vector_p (const_tree); +/* If the argument is INTEGER_CST, return it. If the argument is vector + with all elements the same INTEGER_CST, return that INTEGER_CST. Otherwise + return NULL_TREE. */ + +extern tree uniform_integer_cst_p (tree); + +extern int single_nonzero_element (const_tree); + /* Given a CONSTRUCTOR CTOR, return the element values as a vector. */ extern vec<tree, va_gc> *ctor_to_vec (tree); @@ -4798,6 +5055,7 @@ extern tree get_callee_fndecl (const_tree); extern combined_fn get_call_combined_fn (const_tree); extern int type_num_arguments (const_tree); +extern tree type_argument_type (const_tree, unsigned) ATTRIBUTE_NONNULL (1); extern bool associative_tree_code (enum tree_code); extern bool commutative_tree_code (enum tree_code); extern bool commutative_ternary_tree_code (enum tree_code); @@ -4812,6 +5070,7 @@ extern bool prototype_p (const_tree); extern bool is_typedef_decl (const_tree x); extern bool typedef_variant_p (const_tree); +extern bool auto_var_p (const_tree); extern bool auto_var_in_fn_p (const_tree, const_tree); extern tree build_low_bits_mask (tree, unsigned); extern bool tree_nop_conversion_p (const_tree, const_tree); @@ -4958,8 +5217,7 @@ extern tree get_binfo_at_offset (tree, poly_int64, tree); extern bool virtual_method_call_p (const_tree); extern tree obj_type_ref_class (const_tree ref); -extern bool types_same_for_odr (const_tree type1, const_tree type2, - bool strict=false); +extern bool types_same_for_odr (const_tree type1, const_tree type2); extern bool contains_bitfld_component_ref_p (const_tree); extern bool block_may_fallthru (const_tree); extern void using_eh_for_cleanups (void); @@ -5006,6 +5264,13 @@ by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */ extern tree component_ref_field_offset (tree); +/* Return the size of the member referenced by the COMPONENT_REF, using + its initializer expression if necessary in order to determine the size + of an initialized flexible array member. The size might be zero for + an object with an uninitialized flexible array member or null if it + cannot be determined. */ +extern tree component_ref_size (tree, bool * = NULL); + extern int tree_map_base_eq (const void *, const void *); extern unsigned int tree_map_base_hash (const void *); extern int tree_map_base_marked_p (const void *); @@ -5088,6 +5353,58 @@ #define tree_vec_map_hash tree_decl_map_hash #define tree_vec_map_marked_p tree_map_base_marked_p +/* Hasher for tree decls. Pointer equality is enough here, but the DECL_UID + is a better hash than the pointer value and gives a predictable traversal + order. Additionally it can be used across PCH save/restore. */ +struct tree_decl_hash : ggc_ptr_hash <tree_node> +{ + static inline hashval_t hash (tree); +}; + +inline hashval_t +tree_decl_hash::hash (tree t) +{ + return DECL_UID (t); +} + +/* Similarly for types. Uses TYPE_UID as hash function. */ +struct tree_type_hash : ggc_ptr_hash <tree_node> +{ + static inline hashval_t hash (tree); +}; + +inline hashval_t +tree_type_hash::hash (tree t) +{ + return TYPE_UID (t); +} + +/* Hash for SSA_NAMEs in the same function. Pointer equality is enough + here, but the SSA_NAME_VERSION is a better hash than the pointer + value and gives a predictable traversal order. */ +struct tree_ssa_name_hash : ggc_ptr_hash <tree_node> +{ + static inline hashval_t hash (tree); +}; + +inline hashval_t +tree_ssa_name_hash::hash (tree t) +{ + return SSA_NAME_VERSION (t); +} + +/* Hasher for general trees, based on their TREE_HASH. */ +struct tree_hash : ggc_ptr_hash <tree_node> +{ + static hashval_t hash (tree); +}; + +inline hashval_t +tree_hash::hash (tree t) +{ + return TREE_HASH (t); +} + /* A hash_map of two trees for use with GTY((cache)). Garbage collection for such a map will not mark keys, and will mark values if the key is already marked. */ @@ -5095,6 +5412,18 @@ : simple_cache_map_traits<default_hash_traits<tree>, tree> { }; typedef hash_map<tree,tree,tree_cache_traits> tree_cache_map; +/* Similarly, but use DECL_UID as hash function rather than pointer hashing. + This is for hash_maps from decls to trees that need to work across PCH. */ +struct decl_tree_cache_traits + : simple_cache_map_traits<tree_decl_hash, tree> { }; +typedef hash_map<tree,tree,decl_tree_cache_traits> decl_tree_cache_map; + +/* Similarly, but use TYPE_UID as hash function rather than pointer hashing. + This is for hash_maps from types to trees that need to work across PCH. */ +struct type_tree_cache_traits + : simple_cache_map_traits<tree_type_hash, tree> { }; +typedef hash_map<tree,tree,type_tree_cache_traits> type_tree_cache_map; + /* Initialize the abstract argument list iterator object ITER with the arguments from CALL_EXPR node EXP. */ static inline void @@ -5282,6 +5611,31 @@ && builtin_info[uns_fncode].declared_p); } +/* Determine if the function identified by FNDECL is one that + makes sense to match by name, for those places where we detect + "magic" functions by name. + + Return true if FNDECL has a name and is an extern fndecl at file scope. + FNDECL must be a non-NULL decl. + + Avoid using this, as it's generally better to use attributes rather + than to check for functions by name. */ + +static inline bool +maybe_special_function_p (const_tree fndecl) +{ + tree name_decl = DECL_NAME (fndecl); + if (name_decl + /* Exclude functions not at the file scope, or not `extern', + since they are not the magic functions we would otherwise + think they are. */ + && (DECL_CONTEXT (fndecl) == NULL_TREE + || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL) + && TREE_PUBLIC (fndecl)) + return true; + return false; +} + /* Return true if T (assumed to be a DECL) is a global variable. A variable is considered global if its storage is not automatic. */ @@ -5303,8 +5657,7 @@ || DECL_EXTERNAL (var) || TREE_ADDRESSABLE (var)) && !((TREE_STATIC (var) || TREE_PUBLIC (var) || DECL_EXTERNAL (var)) - && ((TREE_READONLY (var) - && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (var))) + && (TREE_READONLY (var) || (TREE_CODE (var) == VAR_DECL && DECL_NONALIASED (var))))); } @@ -5335,9 +5688,9 @@ /* For anonymous aggregate types, we need some sort of name to hold on to. In practice, this should not appear, but it should - not be harmful if it does. */ -extern const char *anon_aggrname_format(); -extern bool anon_aggrname_p (const_tree); + not be harmful if it does. Identifiers returned will be + IDENTIFIER_ANON_P. */ +extern tree make_anon_name (); /* The tree and const_tree overload templates. */ namespace wi @@ -5799,7 +6152,7 @@ if (COMPLETE_TYPE_P (t)) return true; - /* Incomplete types can not be accessed in general except for arrays + /* Incomplete types cannot be accessed in general except for arrays where we can fetch its element despite we have no array bounds. */ if (TREE_CODE (t) == ARRAY_TYPE && COMPLETE_TYPE_P (TREE_TYPE (t))) return true; @@ -5815,6 +6168,7 @@ extern bool nonnull_arg_p (const_tree); extern bool default_is_empty_record (const_tree); +extern bool flexible_array_type_p (const_tree); extern HOST_WIDE_INT arg_int_size_in_bytes (const_tree); extern tree arg_size_in_bytes (const_tree); extern bool expr_type_first_operand_type_p (tree_code); @@ -5841,8 +6195,9 @@ /* Pointer type used to declare builtins before we have seen its real declaration. */ -struct builtin_structptr_type -{ +class builtin_structptr_type +{ +public: tree& node; tree& base; const char *str; @@ -5861,12 +6216,12 @@ Note that it is different from the DECL_IS_BUILTIN accessor. For instance, user declared prototypes of C library functions are not - DECL_IS_BUILTIN but may be DECL_BUILT_IN. */ + DECL_IS_BUILTIN but may be fndecl_built_in_p. */ inline bool fndecl_built_in_p (const_tree node) { - return (DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN); + return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN; } /* Return true if a FUNCTION_DECL NODE is a GCC built-in function @@ -5875,16 +6230,17 @@ inline bool fndecl_built_in_p (const_tree node, built_in_class klass) { - return (fndecl_built_in_p (node) && DECL_BUILT_IN_CLASS (node) == klass); + return fndecl_built_in_p (node) && DECL_BUILT_IN_CLASS (node) == klass; } /* Return true if a FUNCTION_DECL NODE is a GCC built-in function of class KLASS with name equal to NAME. */ inline bool -fndecl_built_in_p (const_tree node, int name, built_in_class klass) -{ - return (fndecl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name); +fndecl_built_in_p (const_tree node, unsigned int name, built_in_class klass) +{ + return (fndecl_built_in_p (node, klass) + && DECL_UNCHECKED_FUNCTION_CODE (node) == name); } /* Return true if a FUNCTION_DECL NODE is a GCC built-in function @@ -5897,4 +6253,54 @@ && DECL_FUNCTION_CODE (node) == name); } +/* A struct for encapsulating location information about an operator + and the operation built from it. + + m_operator_loc is the location of the operator + m_combined_loc is the location of the compound expression. + + For example, given "a && b" the, operator location is: + a && b + ^~ + and the combined location is: + a && b + ~~^~~~ + Capturing this information allows for class binary_op_rich_location + to provide detailed information about e.g. type mismatches in binary + operations where enough location information is available: + + arg_0 op arg_1 + ~~~~~ ^~ ~~~~~ + | | + | arg1 type + arg0 type + + falling back to just showing the combined location: + + arg_0 op arg_1 + ~~~~~~^~~~~~~~ + + where it is not. */ + +class op_location_t +{ +public: + location_t m_operator_loc; + location_t m_combined_loc; + + /* 1-argument ctor, for constructing from a combined location. */ + op_location_t (location_t combined_loc) + : m_operator_loc (UNKNOWN_LOCATION), m_combined_loc (combined_loc) + {} + + /* 2-argument ctor, for distinguishing between the operator's location + and the combined location. */ + op_location_t (location_t operator_loc, location_t combined_loc) + : m_operator_loc (operator_loc), m_combined_loc (combined_loc) + {} + + /* Implicitly convert back to a location_t, using the combined location. */ + operator location_t () const { return m_combined_loc; } +}; + #endif /* GCC_TREE_H */