📄 c-decl.c
字号:
/* Avoid crashing later. */ define_label (input_filename, lineno, DECL_NAME (TREE_VALUE (link))); } else if (warn_unused && !TREE_USED (TREE_VALUE (link))) warning_with_decl (TREE_VALUE (link), "label `%s' defined but not used"); IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0; /* Delete this element from the list. */ link = TREE_CHAIN (link); if (prev) TREE_CHAIN (prev) = link; else named_labels = link; } else { prev = link; link = TREE_CHAIN (link); } } /* Bring back all the labels that were shadowed. */ for (link = shadowed_labels; link; link = TREE_CHAIN (link)) if (DECL_NAME (TREE_VALUE (link)) != 0) IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = TREE_VALUE (link); named_labels = chainon (named_labels, level->names); shadowed_labels = level->shadowed; /* Pop the current level, and free the structure for reuse. */ label_level_chain = label_level_chain->level_chain; level->level_chain = free_binding_level; free_binding_level = level;}/* Push a definition or a declaration of struct, union or enum tag "name". "type" should be the type node. We assume that the tag "name" is not already defined. Note that the definition may really be just a forward reference. In that case, the TYPE_SIZE will be zero. */voidpushtag (name, type) tree name, type;{ register struct binding_level *b; /* Find the proper binding level for this type tag. */ for (b = current_binding_level; b->tag_transparent; b = b->level_chain) continue; if (name) { /* Record the identifier as the type's name if it has none. */ if (TYPE_NAME (type) == 0) TYPE_NAME (type) = name; } if (b == global_binding_level) b->tags = perm_tree_cons (name, type, b->tags); else b->tags = saveable_tree_cons (name, type, b->tags); /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the tagged type we just added to the current binding level. This fake NULL-named TYPE_DECL node helps dwarfout.c to know when it needs to output a representation of a tagged type, and it also gives us a convenient place to record the "scope start" address for the tagged type. */ TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type));}/* Handle when a new declaration NEWDECL has the same name as an old one OLDDECL in the same binding contour. Prints an error message if appropriate. If safely possible, alter OLDDECL to look like NEWDECL, and return 1. Otherwise, return 0. */static intduplicate_decls (newdecl, olddecl) register tree newdecl, olddecl;{ int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0); tree oldtype = TREE_TYPE (olddecl); tree newtype = TREE_TYPE (newdecl); char *errmsg = 0; if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd') DECL_MACHINE_ATTRIBUTES (newdecl) = DECL_MACHINE_ATTRIBUTES (olddecl); if (TREE_CODE (newtype) == ERROR_MARK || TREE_CODE (oldtype) == ERROR_MARK) types_match = 0; /* New decl is completely inconsistent with the old one => tell caller to replace the old one. This is always an error except in the case of shadowing a builtin. */ if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) { if (TREE_CODE (olddecl) == FUNCTION_DECL && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl))) { /* If you declare a built-in or predefined function name as static, the old definition is overridden, but optionally warn this was a bad choice of name. */ if (!TREE_PUBLIC (newdecl)) { if (!warn_shadow) ; else if (DECL_BUILT_IN (olddecl)) warning_with_decl (newdecl, "shadowing built-in function `%s'"); else warning_with_decl (newdecl, "shadowing library function `%s'"); } /* Likewise, if the built-in is not ansi, then programs can override it even globally without an error. */ else if (! DECL_BUILT_IN (olddecl)) warning_with_decl (newdecl, "library function `%s' declared as non-function"); else if (DECL_BUILT_IN_NONANSI (olddecl)) warning_with_decl (newdecl, "built-in function `%s' declared as non-function"); else warning_with_decl (newdecl, "built-in function `%s' declared as non-function"); } else { error_with_decl (newdecl, "`%s' redeclared as different kind of symbol"); error_with_decl (olddecl, "previous declaration of `%s'"); } return 0; } /* For real parm decl following a forward decl, return 1 so old decl will be reused. */ if (types_match && TREE_CODE (newdecl) == PARM_DECL && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl)) return 1; /* The new declaration is the same kind of object as the old one. The declarations may partially match. Print warnings if they don't match enough. Ultimately, copy most of the information from the new decl to the old one, and keep using the old one. */ if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl && DECL_INITIAL (olddecl) == 0) /* If -traditional, avoid error for redeclaring fcn after implicit decl. */ ; else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_BUILT_IN (olddecl)) { /* A function declaration for a built-in function. */ if (!TREE_PUBLIC (newdecl)) { /* If you declare a built-in function name as static, the built-in definition is overridden, but optionally warn this was a bad choice of name. */ if (warn_shadow) warning_with_decl (newdecl, "shadowing built-in function `%s'"); /* Discard the old built-in function. */ return 0; } else if (!types_match) { /* Accept the return type of the new declaration if same modes. */ tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl)); tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl)); /* Make sure we put the new type in the same obstack as the old ones. If the old types are not both in the same obstack, use the permanent one. */ if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype)) push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype)); else { push_obstacks_nochange (); end_temporary_allocation (); } if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype)) { /* Function types may be shared, so we can't just modify the return type of olddecl's function type. */ tree newtype = build_function_type (newreturntype, TYPE_ARG_TYPES (TREE_TYPE (olddecl))); types_match = comptypes (TREE_TYPE (newdecl), newtype); if (types_match) TREE_TYPE (olddecl) = newtype; } /* Accept harmless mismatch in first argument type also. This is for ffs. */ if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0 && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0 && TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl))) != 0 && TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (olddecl))) != 0 && (TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl)))) == TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (olddecl)))))) { /* Function types may be shared, so we can't just modify the return type of olddecl's function type. */ tree newtype = build_function_type (TREE_TYPE (TREE_TYPE (olddecl)), tree_cons (NULL_TREE, TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (newdecl))), TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (olddecl))))); types_match = comptypes (TREE_TYPE (newdecl), newtype); if (types_match) TREE_TYPE (olddecl) = newtype; } pop_obstacks (); } if (!types_match) { /* If types don't match for a built-in, throw away the built-in. */ warning_with_decl (newdecl, "conflicting types for built-in function `%s'"); return 0; } } else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_SOURCE_LINE (olddecl) == 0) { /* A function declaration for a predeclared function that isn't actually built in. */ if (!TREE_PUBLIC (newdecl)) { /* If you declare it as static, the default definition is overridden. */ return 0; } else if (!types_match) { /* If the types don't match, preserve volatility indication. Later on, we will discard everything else about the default declaration. */ TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); } } /* Permit char *foo () to match void *foo (...) if not pedantic, if one of them came from a system header file. */ else if (!types_match && TREE_CODE (olddecl) == FUNCTION_DECL && TREE_CODE (newdecl) == FUNCTION_DECL && TREE_CODE (TREE_TYPE (oldtype)) == POINTER_TYPE && TREE_CODE (TREE_TYPE (newtype)) == POINTER_TYPE && (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl)) && ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (newtype))) == void_type_node && TYPE_ARG_TYPES (oldtype) == 0 && self_promoting_args_p (TYPE_ARG_TYPES (newtype)) && TREE_TYPE (TREE_TYPE (oldtype)) == char_type_node) || (TREE_TYPE (TREE_TYPE (newtype)) == char_type_node && TYPE_ARG_TYPES (newtype) == 0 && self_promoting_args_p (TYPE_ARG_TYPES (oldtype)) && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node))) { if (pedantic) pedwarn_with_decl (newdecl, "conflicting types for `%s'"); /* Make sure we keep void * as ret type, not char *. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node) TREE_TYPE (newdecl) = newtype = oldtype; /* Set DECL_IN_SYSTEM_HEADER, so that if we see another declaration we will come back here again. */ DECL_IN_SYSTEM_HEADER (newdecl) = 1; } else if (!types_match /* Permit char *foo (int, ...); followed by char *foo (); if not pedantic. */ && ! (TREE_CODE (olddecl) == FUNCTION_DECL && ! pedantic /* Return types must still match. */ && comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype)) && TYPE_ARG_TYPES (newtype) == 0)) { error_with_decl (newdecl, "conflicting types for `%s'"); /* Check for function type mismatch involving an empty arglist vs a nonempty one. */ if (TREE_CODE (olddecl) == FUNCTION_DECL && comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype)) && ((TYPE_ARG_TYPES (oldtype) == 0 && DECL_INITIAL (olddecl) == 0) || (TYPE_ARG_TYPES (newtype) == 0 && DECL_INITIAL (newdecl) == 0))) { /* Classify the problem further. */ register tree t = TYPE_ARG_TYPES (oldtype); if (t == 0) t = TYPE_ARG_TYPES (newtype); for (; t; t = TREE_CHAIN (t)) { register tree type = TREE_VALUE (t); if (TREE_CHAIN (t) == 0 && TYPE_MAIN_VARIANT (type) != void_type_node) { error ("A parameter list with an ellipsis can't match"); error ("an empty parameter name list declaration."); break; } if (TYPE_MAIN_VARIANT (type) == float_type_node || C_PROMOTING_INTEGER_TYPE_P (type)) { error ("An argument type that has a default promotion"); error ("can't match an empty parameter name list declaration."); break; } } } error_with_decl (olddecl, "previous declaration of `%s'"); } else { errmsg = redeclaration_error_message (newdecl, olddecl); if (errmsg) { error_with_decl (newdecl, errmsg); error_with_decl (olddecl, ((DECL_INITIAL (olddecl) && current_binding_level == global_binding_level) ? "`%s' previously defined here" : "`%s' previously declared here")); } else if (TREE_CODE (newdecl) == TYPE_DECL && (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))) { warning_with_decl (newdecl, "redefinition of `%s'"); warning_with_decl (olddecl, ((DECL_INITIAL (olddecl) && current_binding_level == global_binding_level) ? "`%s' previously defined here" : "`%s' previously declared here")); } else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl) != 0 && TYPE_ARG_TYPES (oldtype) == 0 && TYPE_ARG_TYPES (newtype) != 0 && TYPE_ACTUAL_ARG_TYPES (oldtype) != 0) { register tree type, parm; register int nargs; /* Prototype decl follows defn w/o prototype. */ for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype), type = TYPE_ARG_TYPES (newtype), nargs = 1; (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) != void_type_node || TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node); parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++) { if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node) { errmsg = "prototype for `%s' follows and number of arguments"; break; } /* Type for passing arg must be consistent with that declared for the arg. */ if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type)) /* If -traditional, allow `unsigned int' instead of `int' in the prototype. */ && (! (flag_traditional && TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))) { errmsg = "prototype for `%s' follows and argument %d"; break; } } if (errmsg) { error_with_decl (newdecl, errmsg, nargs); error_with_decl (olddecl, "doesn't match non-prototype definition here"); } else { warning_with_decl (newdecl, "prototype for `%s' follows"); warning_with_decl (olddecl, "non-prototype definition here"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -