📄 cp-search.c
字号:
basetype_chain = CLASSTYPE_BINFO_AS_LIST (type); TREE_VIA_PUBLIC (basetype_chain) = 1; search_stack = push_search_level (search_stack, &search_obstack); BINFO_VIA_PUBLIC (basetype_path) = 1; BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; binfo = basetype_path; while (1) { tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; /* Process and/or queue base types. */ for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); if (BINFO_FIELDS_MARKED (base_binfo) == 0) { tree btypes; SET_BINFO_FIELDS_MARKED (base_binfo); btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain); TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo); TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo); TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo); obstack_ptr_grow (&search_obstack, btypes); tail += 1; if (tail >= search_stack->limit) my_friendly_abort (98); } } /* Process head of queue, if one exists. */ if (head >= tail) break; basetype_chain = search_stack->first[head++]; basetype_path = TREE_VALUE (basetype_chain); if (TREE_CHAIN (basetype_chain)) BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain)); else BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; binfo = basetype_path; type = BINFO_TYPE (binfo); /* See if we can find NAME in TYPE. If RVAL is nonzero, and we do find NAME in TYPE, verify that such a second sighting is in fact legal. */ if (rval) { tree context = DECL_FIELD_CONTEXT (rval); /* Just another way of finding the same member. */ if (TYPE_BINFO (context) == binfo) { enum visibility_type new_v = compute_visibility (basetype_path, rval); if (this_v != new_v) errstr = "conflicting visibilities to member `%s'"; } /* Same baseclass, maybe different places in the lattice. */ else if (context == type) { errstr = "member `%s' belongs to distinct base classes `%s'"; protect = 2; } else { tree nval = lookup_field_1 (type, name); if (nval && TREE_CODE (nval) != TYPE_DECL && want_type) nval = NULL_TREE; if (nval && binfo != get_binfo (type, DECL_FIELD_CONTEXT (rval), 0)) { /* We found it in other than a baseclass of RVAL's. */ errstr = "request for member `%s' is ambiguous"; protect = 2; } } if (errstr && entry) { tree error_string = my_build_string (errstr); TREE_TYPE (entry) = error_string; } if (errstr && protect) break; } else { rval = lookup_field_1 (type, name); if (rval && TREE_CODE (rval) != TYPE_DECL && want_type) rval = NULL_TREE; if (rval) { if (entry || protect) this_v = compute_visibility (basetype_path, rval); if (entry) TREE_VALUE (entry) = rval; /* These may look ambiguous, but they really are not. */ if (vbase_name_p) break; } } } { tree *tp = search_stack->first; tree *search_tail = tp + tail; /* If this FIELD_DECL defines its own visibility, deal with that. */ if (rval && errstr == 0 && ((protect&1) || entry) && DECL_LANG_SPECIFIC (rval) && DECL_VISIBILITY (rval)) { while (tp < search_tail) { /* If is possible for one of the derived types on the path to have defined special visibility for this field. Look for such declarations and report an error if a conflict is found. */ enum visibility_type new_v; if (this_v != visibility_default) new_v = compute_visibility (TREE_VALUE (*tp), rval); if (this_v != visibility_default && new_v != this_v) { errstr = "conflicting visibilities to member `%s'"; this_v = visibility_default; } own_visibility = new_v; CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (*tp)); tp += 1; } } else { while (tp < search_tail) { CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (*tp)); tp += 1; } } } search_stack = pop_search_level (search_stack); if (errstr == 0) { if (own_visibility == visibility_private) errstr = "member `%s' declared private"; else if (own_visibility == visibility_protected) errstr = "member `%s' declared protected"; else if (this_v == visibility_private) errstr = TREE_PRIVATE (rval) ? "member `%s' is private" : "member `%s' is from private base class"; else if (this_v == visibility_protected) errstr = TREE_PROTECTED (rval) ? "member `%s' is protected" : "member `%s' is from protected base class"; } if (entry) { if (errstr) { tree error_string = my_build_string (errstr); /* Save error message with entry. */ TREE_TYPE (entry) = error_string; } else { /* Mark entry as having no error string. */ TREE_TYPE (entry) = NULL_TREE; } } if (errstr && protect) { error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type)); rval = error_mark_node; } return rval;}/* Try to find NAME inside a nested class. */treelookup_nested_field (name) tree name;{ register tree t; tree id = NULL_TREE; if (TREE_CHAIN (current_class_type)) { /* Climb our way up the nested ladder, seeing if we're trying to modify a field in an enclosing class. If so, we should only be able to modify if it's static. */ for (t = TREE_CHAIN (current_class_type); t && DECL_CONTEXT (t); t = TREE_CHAIN (DECL_CONTEXT (t))) { if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE) break; /* N.B.: lookup_field will do the visibility checking for us */ id = lookup_field (DECL_CONTEXT (t), name, 1, 0); if (id == error_mark_node) continue; if (id != NULL_TREE) { if (TREE_CODE (id) == FIELD_DECL && ! TREE_STATIC (id) && TREE_TYPE (id) != error_mark_node) { error ("assignment to non-static member `%s' of enclosing class `%s'", lang_printable_name (id), IDENTIFIER_POINTER (TYPE_IDENTIFIER (DECL_CONTEXT (t)))); /* Mark this for do_identifier(). It would otherwise claim that the variable was undeclared. */ TREE_TYPE (id) = error_mark_node; } break; } } } return id;}/* TYPE is a class type. Return the index of the fields within the method vector with name NAME, or -1 is no such field exists. */static intlookup_fnfields_1 (type, name) tree type, name;{ register tree method_vec = CLASSTYPE_METHOD_VEC (type); if (method_vec != 0) { register tree *methods = &TREE_VEC_ELT (method_vec, 0); register tree *end = TREE_VEC_END (method_vec);#ifdef GATHER_STATISTICS n_calls_lookup_fnfields_1++;#endif if (*methods && name == constructor_name (type)) return 0; while (++methods != end) {#ifdef GATHER_STATISTICS n_outer_fields_searched++;#endif if (DECL_NAME (*methods) == name) break; } if (methods != end) return methods - &TREE_VEC_ELT (method_vec, 0); } return -1;}/* Starting from BASETYPE, return a TREE_BASELINK-like object which gives the following information (in a list): TREE_TYPE: list of basetypes needed to get to... TREE_VALUE: list of all functions in of given type which have name NAME. No visibility information is computed by this function, other then to adorn the list of basetypes with TREE_VIA_PUBLIC. If FIND_AMBIGUOUS is non-zero, then if we find two ways to get to the same member function, both those ways are found, and the caller must know what to do about this. */treelookup_fnfields (basetype_path, name, find_ambiguous) tree basetype_path, name; int find_ambiguous;{ int head = 0, tail = 0; tree type, rval, rvals = NULL_TREE; tree entry, binfo, basetype_chain; /* For now, don't try this. */ int protect = find_ambiguous; /* Things for memoization. */ char *errstr = 0; /* Set this to nonzero if we don't know how to compute accurate error messages for visibility. */ int index = MEMOIZED_HASH_FN (name); binfo = basetype_path; type = BINFO_TYPE (basetype_path); if (CLASSTYPE_MTABLE_ENTRY (type)) { tree tem = MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index); while (tem && TREE_PURPOSE (tem) != name) { memoized_fields_searched[1]++; tem = TREE_CHAIN (tem); } if (tem) { if (protect && TREE_TYPE (tem)) { error (TREE_STRING_POINTER (TREE_TYPE (tem)), IDENTIFIER_POINTER (name), TYPE_NAME_STRING (DECL_CLASS_CONTEXT (TREE_VALUE (TREE_VALUE (tem))))); return error_mark_node; } if (TREE_VALUE (tem) == NULL_TREE) { memoized_fast_rejects[1] += 1; return NULL_TREE; } else { /* Want to return this, but we must make sure that visibility information is consistent. */ tree baselink = TREE_VALUE (tem); tree memoized_basetypes = TREE_PURPOSE (baselink); tree these_basetypes = basetype_path; while (memoized_basetypes && these_basetypes) { memoized_fields_searched[1]++; if (TREE_VALUE (memoized_basetypes) != these_basetypes) break; memoized_basetypes = TREE_CHAIN (memoized_basetypes); these_basetypes = BINFO_INHERITANCE_CHAIN (these_basetypes); } /* The following statement is true only when both are NULL. */ if (memoized_basetypes == these_basetypes) { memoized_fast_finds[1] += 1; return TREE_VALUE (tem); } /* else, we must re-find this field by hand. */ baselink = tree_cons (basetype_path, TREE_VALUE (baselink), TREE_CHAIN (baselink)); return baselink; } } }#ifdef GATHER_STATISTICS n_calls_lookup_fnfields++;#endif if (protect && flag_memoize_lookups && ! global_bindings_p ()) entry = make_memoized_table_entry (type, name, 1); else entry = 0; index = lookup_fnfields_1 (type, name); if (index >= 0) { rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index); rvals = my_tree_cons (basetype_path, rval, NULL_TREE); if (BINFO_BASETYPES (binfo) && CLASSTYPE_BASELINK_VEC (type)) TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index); if (entry) { TREE_VALUE (entry) = rvals; TREE_TYPE (entry) = NULL_TREE; } if (errstr && protect) { error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type)); return error_mark_node; } return rvals; } rval = NULL_TREE; basetype_chain = CLASSTYPE_BINFO_AS_LIST (type); TREE_VIA_PUBLIC (basetype_chain) = 1; search_stack = push_search_level (search_stack, &search_obstack); BINFO_VIA_PUBLIC (basetype_path) = 1; BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; binfo = basetype_path; while (1) { tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; /* Process and/or queue base types. */ for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); if (BINFO_FIELDS_MARKED (base_binfo) == 0) { tree btypes; SET_BINFO_FIELDS_MARKED (base_binfo); btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain); TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo); TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo); TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo); obstack_ptr_grow (&search_obstack, btypes); tail += 1; if (tail >= search_stack->limit) my_friendly_abort (99); } } /* Process head of queue, if one exists. */ if (head >= tail) break; basetype_chain = search_stack->first[head++]; basetype_path = TREE_VALUE (basetype_chain); if (TREE_CHAIN (basetype_chain)) BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain)); else BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; binfo = basetype_path; type = BINFO_TYPE (binfo); /* See if we can find NAME in TYPE. If RVAL is nonzero, and we do find NAME in TYPE, verify that such a second sighting is in fact legal. */ if (rval) { tree context = DECL_CLASS_CONTEXT (rval); /* Just another way of finding the same member. */ if (TYPE_BINFO (context) == binfo) ; /* Same baseclass, maybe different places in the lattice. */ else if (context == type) { if (TREE_VIA_VIRTUAL (TREE_PURPOSE (rvals))) if (TREE_VIA_VIRTUAL (binfo)) ; else errstr = "member `%s' belongs to virtual and non-virtual baseclasses `%s'";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -