/* The cp_lexer_* routines mediate between the lexer proper (in libcpp
and c-lex.c) and the C++ parser. */
+/* A token's value and its associated deferred access checks and
+ qualifying scope. */
+
+struct tree_check GTY(())
+{
+ /* The value associated with the token. */
+ tree value;
+ /* The checks that have been associated with value. */
+ VEC (deferred_access_check, gc)* checks;
+ /* The token's qualifying scope (used when it is a
+ CPP_NESTED_NAME_SPECIFIER). */
+ tree qualifying_scope;
+};
+
/* A C++ token. */
typedef struct cp_token GTY (())
/* The input file stack index at which this token was found. */
unsigned input_file_stack_index : INPUT_FILE_STACK_BITS;
/* The value associated with this token, if any. */
- tree value;
+ union cp_token_value {
+ /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID. */
+ struct tree_check* GTY((tag ("1"))) tree_check_value;
+ /* Use for all other tokens. */
+ tree GTY((tag ("0"))) value;
+ } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u;
/* The location at which this token was found. */
location_t location;
} cp_token;
static const cp_token eof_token =
{
- CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, 0, false, 0, NULL_TREE,
+ CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, 0, false, 0, { NULL },
#if USE_MAPPED_LOCATION
0
#else
/* Get a new token from the preprocessor. */
token->type
- = c_lex_with_flags (&token->value, &token->location, &token->flags);
+ = c_lex_with_flags (&token->u.value, &token->location, &token->flags);
token->input_file_stack_index = input_file_stack_tick;
token->keyword = RID_MAX;
token->pragma_kind = PRAGMA_NONE;
/* Check to see if this token is a keyword. */
if (token->type == CPP_NAME)
{
- if (C_IS_RESERVED_WORD (token->value))
+ if (C_IS_RESERVED_WORD (token->u.value))
{
/* Mark this token as a keyword. */
token->type = CPP_KEYWORD;
/* Record which keyword. */
- token->keyword = C_RID_CODE (token->value);
+ token->keyword = C_RID_CODE (token->u.value);
/* Update the value. Some keywords are mapped to particular
entities, rather than simply having the value of the
corresponding IDENTIFIER_NODE. For example, `__const' is
mapped to `const'. */
- token->value = ridpointers[token->keyword];
+ token->u.value = ridpointers[token->keyword];
}
else
{
else if (token->type == CPP_AT_NAME)
{
token->type = CPP_KEYWORD;
- switch (C_RID_CODE (token->value))
+ switch (C_RID_CODE (token->u.value))
{
/* Map 'class' to '@class', 'private' to '@private', etc. */
case RID_CLASS: token->keyword = RID_AT_CLASS; break;
case RID_THROW: token->keyword = RID_AT_THROW; break;
case RID_TRY: token->keyword = RID_AT_TRY; break;
case RID_CATCH: token->keyword = RID_AT_CATCH; break;
- default: token->keyword = C_RID_CODE (token->value);
+ default: token->keyword = C_RID_CODE (token->u.value);
}
}
else if (token->type == CPP_PRAGMA)
{
/* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
- token->pragma_kind = TREE_INT_CST_LOW (token->value);
- token->value = NULL;
+ token->pragma_kind = TREE_INT_CST_LOW (token->u.value);
+ token->u.value = NULL_TREE;
}
}
gcc_assert (tok != &eof_token);
tok->type = CPP_PURGED;
tok->location = UNKNOWN_LOCATION;
- tok->value = NULL_TREE;
+ tok->u.value = NULL_TREE;
tok->keyword = RID_MAX;
do
{
tok->type = CPP_PURGED;
tok->location = UNKNOWN_LOCATION;
- tok->value = NULL_TREE;
+ tok->u.value = NULL_TREE;
tok->keyword = RID_MAX;
}
}
case CPP_KEYWORD:
/* Some keywords have a value that is not an IDENTIFIER_NODE.
For example, `struct' is mapped to an INTEGER_CST. */
- if (TREE_CODE (token->value) != IDENTIFIER_NODE)
+ if (TREE_CODE (token->u.value) != IDENTIFIER_NODE)
break;
/* else fall through */
case CPP_NAME:
- fputs (IDENTIFIER_POINTER (token->value), stream);
+ fputs (IDENTIFIER_POINTER (token->u.value), stream);
break;
case CPP_STRING:
case CPP_WSTRING:
- fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->value));
+ fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value));
break;
default:
/* Declarators [gram.dcl.decl] */
static tree cp_parser_init_declarator
- (cp_parser *, cp_decl_specifier_seq *, tree, bool, bool, int, bool *);
+ (cp_parser *, cp_decl_specifier_seq *, VEC (deferred_access_check,gc)*, bool, bool, int, bool *);
static cp_declarator *cp_parser_declarator
(cp_parser *, cp_parser_declarator_kind, int *, bool *, bool);
static cp_declarator *cp_parser_direct_declarator
static void cp_parser_template_declaration_after_export
(cp_parser *, bool);
static void cp_parser_perform_template_parameter_access_checks
- (tree);
+ (VEC (deferred_access_check,gc)*);
static tree cp_parser_single_declaration
- (cp_parser *, tree, bool, bool *);
+ (cp_parser *, VEC (deferred_access_check,gc)*, bool, bool *);
static tree cp_parser_functional_cast
(cp_parser *, tree);
static tree cp_parser_save_member_function_body
CPP_KEYWORD, keywords are treated like
identifiers. */
(token->type == CPP_KEYWORD ? CPP_NAME : token->type),
- token->value);
+ token->u.value);
}
}
/* Look for the identifier. */
token = cp_parser_require (parser, CPP_NAME, "identifier");
/* Return the value. */
- return token ? token->value : error_mark_node;
+ return token ? token->u.value : error_mark_node;
}
/* Parse a sequence of adjacent string constants. Returns a
{
cp_lexer_consume_token (parser->lexer);
- str.text = (const unsigned char *)TREE_STRING_POINTER (tok->value);
- str.len = TREE_STRING_LENGTH (tok->value);
+ str.text = (const unsigned char *)TREE_STRING_POINTER (tok->u.value);
+ str.len = TREE_STRING_LENGTH (tok->u.value);
count = 1;
if (tok->type == CPP_WSTRING)
wide = true;
{
cp_lexer_consume_token (parser->lexer);
count++;
- str.text = (unsigned char *)TREE_STRING_POINTER (tok->value);
- str.len = TREE_STRING_LENGTH (tok->value);
+ str.text = (unsigned char *)TREE_STRING_POINTER (tok->u.value);
+ str.len = TREE_STRING_LENGTH (tok->u.value);
if (tok->type == CPP_WSTRING)
wide = true;
/* Floating-point literals are only allowed in an integral
constant expression if they are cast to an integral or
enumeration type. */
- if (TREE_CODE (token->value) == REAL_CST
+ if (TREE_CODE (token->u.value) == REAL_CST
&& parser->integral_constant_expression_p
&& pedantic)
{
cp_parser_non_integral_constant_expression
(parser, "floating-point literal");
}
- return token->value;
+ return token->u.value;
case CPP_STRING:
case CPP_WSTRING:
Consume the token. */
token = cp_lexer_consume_token (parser->lexer);
/* Look up the name. */
- return finish_fname (token->value);
+ return finish_fname (token->u.value);
case RID_VA_ARG:
{
&& token->type == CPP_NAME
&& (cp_lexer_peek_nth_token (parser->lexer, 2)->type
== CPP_OPEN_PAREN)
- && constructor_name_p (token->value, scope))
+ && constructor_name_p (token->u.value, scope))
{
cp_lexer_consume_token (parser->lexer);
return build_nt (BIT_NOT_EXPR, scope);
tree decl;
tree ambiguous_decls;
- decl = cp_parser_lookup_name (parser, token->value,
+ decl = cp_parser_lookup_name (parser, token->u.value,
none_type,
/*is_template=*/false,
/*is_namespace=*/false,
else if (ambiguous_decls)
{
error ("reference to %qD is ambiguous",
- token->value);
+ token->u.value);
print_candidates (ambiguous_decls);
decl = error_mark_node;
}
else
cp_parser_name_lookup_error
- (parser, token->value, decl,
+ (parser, token->u.value, decl,
"is not a class or namespace");
}
parser->scope = error_mark_node;
if (success && start)
{
cp_token *token;
- tree access_checks;
token = cp_lexer_token_at (parser->lexer, start);
/* Reset the contents of the START token. */
token->type = CPP_NESTED_NAME_SPECIFIER;
/* Retrieve any deferred checks. Do not pop this access checks yet
so the memory will not be reclaimed during token replacing below. */
- access_checks = get_deferred_access_checks ();
- token->value = build_tree_list (copy_list (access_checks),
- parser->scope);
- TREE_TYPE (token->value) = parser->qualifying_scope;
+ token->u.tree_check_value = GGC_CNEW (struct tree_check);
+ token->u.tree_check_value->value = parser->scope;
+ token->u.tree_check_value->checks = get_deferred_access_checks ();
+ token->u.tree_check_value->qualifying_scope =
+ parser->qualifying_scope;
token->keyword = RID_MAX;
/* Purge all subsequent tokens. */
/* Consume the identifier. */
token = cp_lexer_consume_token (parser->lexer);
/* Save the identifier. */
- identifier = token->value;
+ identifier = token->u.value;
}
else
{
/* Parse the init-declarator. */
decl = cp_parser_init_declarator (parser, &decl_specifiers,
- /*checks=*/NULL_TREE,
+ /*checks=*/NULL,
function_definition_allowed_p,
/*member_p=*/false,
declares_class_or_enum,
case RID_MUTABLE:
case RID_THREAD:
/* Consume the token. */
- return cp_lexer_consume_token (parser->lexer)->value;
+ return cp_lexer_consume_token (parser->lexer)->u.value;
default:
return NULL_TREE;
}
/* Consume the token. */
- return cp_lexer_consume_token (parser->lexer)->value;
+ return cp_lexer_consume_token (parser->lexer)->u.value;
}
/* Parse a linkage-specification.
bool check_dependency_p,
bool is_declaration)
{
+ int i;
tree template;
tree arguments;
tree template_id;
cp_token_position start_of_id = 0;
- tree access_check = NULL_TREE;
+ deferred_access_check *chk;
+ VEC (deferred_access_check,gc) *access_check;
cp_token *next_token, *next_token_2;
bool is_identifier;
next_token = cp_lexer_peek_token (parser->lexer);
if (next_token->type == CPP_TEMPLATE_ID)
{
- tree value;
- tree check;
+ struct tree_check *check_value;
/* Get the stored value. */
- value = cp_lexer_consume_token (parser->lexer)->value;
+ check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
/* Perform any access checks that were deferred. */
- for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
- perform_or_defer_access_check (TREE_PURPOSE (check),
- TREE_VALUE (check),
- TREE_VALUE (check));
+ access_check = check_value->checks;
+ if (access_check)
+ {
+ for (i = 0 ;
+ VEC_iterate (deferred_access_check, access_check, i, chk) ;
+ ++i)
+ {
+ perform_or_defer_access_check (chk->binfo,
+ chk->decl,
+ chk->diag_decl);
+ }
+ }
/* Return the stored value. */
- return TREE_VALUE (value);
+ return check_value->value;
}
/* Avoid performing name lookup if there is no possibility of
template_id = lookup_template_function (template, arguments);
}
- /* Retrieve any deferred checks. Do not pop this access checks yet
- so the memory will not be reclaimed during token replacing below. */
- access_check = get_deferred_access_checks ();
-
/* If parsing tentatively, replace the sequence of tokens that makes
up the template-id with a CPP_TEMPLATE_ID token. That way,
should we re-parse the token stream, we will not have to repeat
/* Reset the contents of the START_OF_ID token. */
token->type = CPP_TEMPLATE_ID;
- token->value = build_tree_list (access_check, template_id);
+ /* Retrieve any deferred checks. Do not pop this access checks yet
+ so the memory will not be reclaimed during token replacing below. */
+ token->u.tree_check_value = GGC_CNEW (struct tree_check);
+ token->u.tree_check_value->value = template_id;
+ token->u.tree_check_value->checks = get_deferred_access_checks ();
token->keyword = RID_MAX;
/* Purge all subsequent tokens. */
else
/* Parse the dependent declaration. */
cp_parser_single_declaration (parser,
- /*checks=*/NULL_TREE,
+ /*checks=*/NULL,
/*member_p=*/false,
/*friend_p=*/NULL);
/* We're done with the specialization. */
++decl_specs->specs[(int)ds];
decl_specs->any_specifiers_p = true;
}
- return cp_lexer_consume_token (parser->lexer)->value;
+ return cp_lexer_consume_token (parser->lexer)->u.value;
}
/* If we do not already have a type-specifier, assume we are looking
decl_specs->any_specifiers_p = true;
/* Consume the token. */
- id = cp_lexer_consume_token (parser->lexer)->value;
+ id = cp_lexer_consume_token (parser->lexer)->u.value;
/* There is no valid C++ program where a non-template type is
followed by a "<". That usually indicates that the user thought
static tree
cp_parser_init_declarator (cp_parser* parser,
cp_decl_specifier_seq *decl_specifiers,
- tree checks,
+ VEC (deferred_access_check,gc)* checks,
bool function_definition_allowed_p,
bool member_p,
int declares_class_or_enum,
if (pedantic)
pedwarn ("ISO C++ does not allow designated initializers");
/* Consume the identifier. */
- identifier = cp_lexer_consume_token (parser->lexer)->value;
+ identifier = cp_lexer_consume_token (parser->lexer)->u.value;
/* Consume the `:'. */
cp_lexer_consume_token (parser->lexer);
}
/* Consume the access-specifier. */
cp_lexer_consume_token (parser->lexer);
/* Remember which access-specifier is active. */
- current_access_specifier = token->value;
+ current_access_specifier = token->u.value;
/* Look for the `:'. */
cp_parser_require (parser, CPP_COLON, "`:'");
break;
/* Save away the identifier that indicates which attribute
this is. */
- identifier = token->value;
+ identifier = token->u.value;
attribute = build_tree_list (identifier, NULL_TREE);
/* Peek at the next token. */
cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
{
tree decl = NULL_TREE;
- tree checks;
+ VEC (deferred_access_check,gc) *checks;
tree parameter_list;
bool friend_p = false;
bool need_lang_pop;
get_deferred_access_checks. */
static void
-cp_parser_perform_template_parameter_access_checks (tree checks)
+cp_parser_perform_template_parameter_access_checks (VEC (deferred_access_check,gc)* checks)
{
++processing_template_parmlist;
perform_access_checks (checks);
static tree
cp_parser_single_declaration (cp_parser* parser,
- tree checks,
+ VEC (deferred_access_check,gc)* checks,
bool member_p,
bool* friend_p)
{
static void
cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
{
- tree value;
- tree check;
+ int i;
+ struct tree_check *check_value;
+ deferred_access_check *chk;
+ VEC (deferred_access_check,gc) *checks;
/* Get the stored value. */
- value = cp_lexer_consume_token (parser->lexer)->value;
+ check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
/* Perform any access checks that were deferred. */
- for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
- perform_or_defer_access_check (TREE_PURPOSE (check),
- TREE_VALUE (check),
- TREE_VALUE (check));
+ checks = check_value->checks;
+ if (checks)
+ {
+ for (i = 0 ;
+ VEC_iterate (deferred_access_check, checks, i, chk) ;
+ ++i)
+ {
+ perform_or_defer_access_check (chk->binfo,
+ chk->decl,
+ chk->diag_decl);
+ }
+ }
/* Set the scope from the stored value. */
- parser->scope = TREE_VALUE (value);
- parser->qualifying_scope = TREE_TYPE (value);
+ parser->scope = check_value->value;
+ parser->qualifying_scope = check_value->qualifying_scope;
parser->object_scope = NULL_TREE;
}
case CPP_OBJC_STRING:
kwd = cp_lexer_consume_token (parser->lexer);
- return objc_build_string_object (kwd->value);
+ return objc_build_string_object (kwd->u.value);
case CPP_KEYWORD:
switch (kwd->keyword)
break;
}
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->value);
+ error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
tree quals = NULL_TREE, node;
cp_token *token = cp_lexer_peek_token (parser->lexer);
- node = token->value;
+ node = token->u.value;
while (node && TREE_CODE (node) == IDENTIFIER_NODE
&& (node == ridpointers [(int) RID_IN]
quals = tree_cons (NULL_TREE, node, quals);
cp_lexer_consume_token (parser->lexer);
token = cp_lexer_peek_token (parser->lexer);
- node = token->value;
+ node = token->u.value;
}
return quals;
case CPP_OR_EQ: return get_identifier ("or_eq");
case CPP_XOR: return get_identifier ("xor");
case CPP_XOR_EQ: return get_identifier ("xor_eq");
- default: return token->value;
+ default: return token->u.value;
}
}
cp_parser_objc_end_implementation (parser);
break;
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->value);
+ error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
}
case RID_AT_THROW:
return cp_parser_objc_throw_statement (parser);
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->value);
+ error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
result = PRAGMA_OMP_CLAUSE_PRIVATE;
else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->value;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
switch (p[0])
return list;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->value;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
switch (p[0])
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->value;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
switch (p[0])
}
else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->value;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
if (strcmp (p, "sections") == 0)
{
cp_lexer_get_preprocessor_token (NULL, first_token);
if (first_token->type == CPP_STRING)
{
- name = first_token->value;
+ name = first_token->u.value;
cp_lexer_get_preprocessor_token (NULL, first_token);
if (first_token->type != CPP_PRAGMA_EOL)
tok = cp_lexer_peek_token (the_parser->lexer);
ret = tok->type;
- *value = tok->value;
+ *value = tok->u.value;
if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
ret = CPP_EOF;
2. When a declaration such as a type, or a variable, is encountered,
the function `perform_or_defer_access_check' is called. It
- maintains a TREE_LIST of all deferred checks.
+ maintains a VEC of all deferred checks.
3. The global `current_class_type' or `current_function_decl' is then
setup by the parser. `enforce_access' relies on these information
4. Upon exiting the context mentioned in step 1,
`perform_deferred_access_checks' is called to check all declaration
- stored in the TREE_LIST. `pop_deferring_access_checks' is then
+ stored in the VEC. `pop_deferring_access_checks' is then
called to restore the previous access checking mode.
In case of parsing error, we simply call `pop_deferring_access_checks'
typedef struct deferred_access GTY(())
{
- /* A TREE_LIST representing name-lookups for which we have deferred
+ /* A VEC representing name-lookups for which we have deferred
checking access controls. We cannot check the accessibility of
names used in a decl-specifier-seq until we know what is being
declared because code like:
A::B* A::f() { return 0; }
- is valid, even though `A::B' is not generally accessible.
-
- The TREE_PURPOSE of each node is the scope used to qualify the
- name being looked up; the TREE_VALUE is the DECL to which the
- name was resolved. */
- tree deferred_access_checks;
+ is valid, even though `A::B' is not generally accessible. */
+ VEC (deferred_access_check,gc)* GTY(()) deferred_access_checks;
/* The current mode of access checks. */
enum deferring_kind deferring_access_checks_kind;
deferred_access *ptr;
ptr = VEC_safe_push (deferred_access, gc, deferred_access_stack, NULL);
- ptr->deferred_access_checks = NULL_TREE;
+ ptr->deferred_access_checks = NULL;
ptr->deferring_access_checks_kind = deferring;
}
}
access occurred; the TREE_VALUE is the declaration named.
*/
-tree
+VEC (deferred_access_check,gc)*
get_deferred_access_checks (void)
{
if (deferred_access_no_check)
deferred_access_no_check--;
else
{
- tree checks;
+ VEC (deferred_access_check,gc) *checks;
deferred_access *ptr;
checks = (VEC_last (deferred_access, deferred_access_stack)
if (ptr->deferring_access_checks_kind == dk_no_deferred)
{
/* Check access. */
- for (; checks; checks = TREE_CHAIN (checks))
- enforce_access (TREE_PURPOSE (checks),
- TREE_VALUE (checks), TREE_VALUE (checks));
+ perform_access_checks (checks);
}
else
{
/* Merge with parent. */
- tree next;
- tree original = ptr->deferred_access_checks;
+ int i, j;
+ deferred_access_check *chk, *probe;
- for (; checks; checks = next)
+ for (i = 0 ;
+ VEC_iterate (deferred_access_check, checks, i, chk) ;
+ ++i)
{
- tree probe;
-
- next = TREE_CHAIN (checks);
-
- for (probe = original; probe; probe = TREE_CHAIN (probe))
- if (TREE_VALUE (probe) == TREE_VALUE (checks)
- && TREE_PURPOSE (probe) == TREE_PURPOSE (checks))
- goto found;
+ for (j = 0 ;
+ VEC_iterate (deferred_access_check,
+ ptr->deferred_access_checks, j, probe) ;
+ ++j)
+ {
+ if (probe->binfo == chk->binfo &&
+ probe->decl == chk->decl &&
+ probe->diag_decl == chk->diag_decl)
+ goto found;
+ }
/* Insert into parent's checks. */
- TREE_CHAIN (checks) = ptr->deferred_access_checks;
- ptr->deferred_access_checks = checks;
+ VEC_safe_push (deferred_access_check, gc,
+ ptr->deferred_access_checks, chk);
found:;
}
}
DECL node stored in the TREE_VALUE of the node. */
void
-perform_access_checks (tree checks)
+perform_access_checks (VEC (deferred_access_check,gc)* checks)
{
- while (checks)
- {
- enforce_access (TREE_PURPOSE (checks),
- TREE_VALUE (checks), TREE_VALUE (checks));
- checks = TREE_CHAIN (checks);
- }
+ int i;
+ deferred_access_check *chk;
+
+ if (!checks)
+ return;
+
+ for (i = 0 ; VEC_iterate (deferred_access_check, checks, i, chk) ; ++i)
+ enforce_access (chk->binfo, chk->decl, chk->diag_decl);
}
/* Perform the deferred access checks.
void
perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
{
- tree check;
+ int i;
deferred_access *ptr;
+ deferred_access_check *chk;
+ deferred_access_check *new_access;
+
/* Exit if we are in a context that no access checking is performed.
*/
}
/* See if we are already going to perform this check. */
- for (check = ptr->deferred_access_checks;
- check;
- check = TREE_CHAIN (check))
- if (TREE_VALUE (check) == decl && TREE_PURPOSE (check) == binfo)
- return;
+ for (i = 0 ;
+ VEC_iterate (deferred_access_check,
+ ptr->deferred_access_checks, i, chk) ;
+ ++i)
+ {
+ if (chk->decl == decl && chk->binfo == binfo &&
+ chk->diag_decl == diag_decl)
+ {
+ return;
+ }
+ }
/* If not, record the check. */
- ptr->deferred_access_checks
- = tree_cons (binfo, decl, ptr->deferred_access_checks);
+ new_access =
+ VEC_safe_push (deferred_access_check, gc,
+ ptr->deferred_access_checks, 0);
+ new_access->binfo = binfo;
+ new_access->decl = decl;
+ new_access->diag_decl = diag_decl;
}
/* Returns nonzero if the current statement is a full expression,