?? c-decl.c
字號:
else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl) != 0 && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == 0 && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0) { /* Prototype decl follows defn w/o prototype. */ warning_with_decl (newdecl, "prototype for `%s'"); warning_with_decl (olddecl, "follows non-prototype definition here"); } /* These bits are logically part of the type. */ if (pedantic && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl) || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))) warning_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl"); } } if (TREE_CODE (olddecl) == TREE_CODE (newdecl)) { int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0); /* Copy all the DECL_... slots specified in the new decl except for any that we copy here from the old type. */ if (types_match) { tree oldtype = TREE_TYPE (olddecl); /* Merge the data types specified in the two decls. */ TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = commontype (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); /* Lay the type out, unless already done. */ if (oldtype != TREE_TYPE (newdecl)) { if (TREE_TYPE (newdecl) != error_mark_node) layout_type (TREE_TYPE (newdecl)); if (TREE_CODE (newdecl) != FUNCTION_DECL && TREE_CODE (newdecl) != TYPE_DECL && TREE_CODE (newdecl) != CONST_DECL) layout_decl (newdecl, 0); } else { /* Since the type is OLDDECL's, make OLDDECL's size go with. */ DECL_SIZE (newdecl) = DECL_SIZE (olddecl); DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl); if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); } /* Merge the type qualifiers. */ if (TREE_READONLY (newdecl)) TREE_READONLY (olddecl) = 1; if (TREE_THIS_VOLATILE (newdecl)) TREE_THIS_VOLATILE (olddecl) = 1; /* Merge the initialization information. */ if (DECL_INITIAL (newdecl) == 0) DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); /* Keep the old rtl since we can safely use it. */ DECL_RTL (newdecl) = DECL_RTL (olddecl); } /* If cannot merge, then use the new type and qualifiers, and don't preserve the old rtl. */ else { TREE_TYPE (olddecl) = TREE_TYPE (newdecl); TREE_READONLY (olddecl) = TREE_READONLY (newdecl); TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl); TREE_VOLATILE (olddecl) = TREE_VOLATILE (newdecl); } /* Merge the storage class information. */ if (TREE_EXTERNAL (newdecl)) { TREE_STATIC (newdecl) = TREE_STATIC (olddecl); TREE_EXTERNAL (newdecl) = TREE_EXTERNAL (olddecl); /* For functions, static overrides non-static. */ if (TREE_CODE (newdecl) == FUNCTION_DECL) { TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); /* This is since we don't automatically copy the attributes of NEWDECL into OLDDECL. */ TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); /* If this clears `static', clear it in the identifier too. */ if (! TREE_PUBLIC (olddecl)) TREE_PUBLIC (DECL_NAME (olddecl)) = 0; } else TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); } else { TREE_STATIC (olddecl) = TREE_STATIC (newdecl); TREE_EXTERNAL (olddecl) = 0; TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); } /* If either decl says `inline', this fn is inline, unless its definition was passed already. */ if (TREE_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) TREE_INLINE (olddecl) = 1; /* If redeclaring a builtin function, and not a definition, it stays built in. Also preserve various other info from the definition. */ if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition) { DECL_SET_FUNCTION_CODE (newdecl, DECL_FUNCTION_CODE (olddecl)); DECL_RESULT (newdecl) = DECL_RESULT (olddecl); DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl); DECL_RESULT_TYPE (newdecl) = DECL_RESULT_TYPE (olddecl); DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl); } /* Don't lose track of having output OLDDECL as GDB symbol. */ DECL_BLOCK_SYMTAB_ADDRESS (newdecl) = DECL_BLOCK_SYMTAB_ADDRESS (olddecl); bcopy ((char *) newdecl + sizeof (struct tree_common), (char *) olddecl + sizeof (struct tree_common), sizeof (struct tree_decl) - sizeof (struct tree_common)); return 1; } /* New decl is completely inconsistent with the old one => tell caller to replace the old one. */ return 0;}/* Record a decl-node X as belonging to the current lexical scope. Check for errors (such as an incompatible declaration for the same name already seen in the same scope). Returns either X or an old decl for the same name. If an old decl is returned, it may have been smashed to agree with what X says. */treepushdecl (x) tree x;{ register tree t; register tree name = DECL_NAME (x); register struct binding_level *b = current_binding_level; if (name) { char *file; int line; t = lookup_name_current_level (name); if (t != 0 && t == error_mark_node) /* error_mark_node is 0 for a while during initialization! */ { t = 0; error_with_decl (x, "`%s' used prior to declaration"); } if (t != 0) { file = DECL_SOURCE_FILE (t); line = DECL_SOURCE_LINE (t); } if (t != 0 && duplicate_decls (x, t)) { /* If this decl is `static' and an implicit decl was seen previously, warn. But don't complain if -traditional, since traditional compilers don't complain. */ if (!flag_traditional && TREE_PUBLIC (name) && ! TREE_PUBLIC (x) && ! TREE_EXTERNAL (x) /* We used to warn also for explicit extern followed by static, but sometimes you need to do it that way. */ && IDENTIFIER_IMPLICIT_DECL (name) != 0) { warning ("`%s' was declared implicitly `extern' and later `static'", IDENTIFIER_POINTER (name)); warning_with_file_and_line (file, line, "previous declaration of `%s'", IDENTIFIER_POINTER (name)); } return t; } /* If declaring a type as a typedef, and the type has no known typedef name, install this TYPE_DECL as its typedef name. */ if (TREE_CODE (x) == TYPE_DECL) if (TYPE_NAME (TREE_TYPE (x)) == 0) TYPE_NAME (TREE_TYPE (x)) = x; /* Multiple external decls of the same identifier ought to match. */ if (TREE_EXTERNAL (x) && IDENTIFIER_GLOBAL_VALUE (name) != 0 && (TREE_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name)) || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name)))) { if (! comptypes (TREE_TYPE (x), TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)))) { warning_with_decl (x, "type mismatch with previous external decl"); warning_with_decl (IDENTIFIER_GLOBAL_VALUE (name), "previous external decl of `%s'"); } } /* In PCC-compatibility mode, extern decls of vars with no current decl take effect at top level no matter where they are. */ if (flag_traditional && TREE_EXTERNAL (x) && lookup_name (name) == 0) { tree type = TREE_TYPE (x); /* But don't do this if the type contains temporary nodes. */ while (type) { if (! TREE_PERMANENT (type)) { warning_with_decl (x, "Type of `extern' decl is not global"); break; } else if (TREE_CODE (type) == FUNCTION_TYPE && TYPE_ARG_TYPES (type) != 0) /* The types might not be truly local, but the list of arg types certainly is temporary. Since prototypes are nontraditional, ok not to do the traditional thing. */ break; type = TREE_TYPE (type); } if (type == 0) b = global_binding_level; } /* This name is new in its binding level. Install the new declaration and return it. */ if (b == global_binding_level) { /* Install a global value. */ /* If the first global decl has external linkage, warn if we later see static one. */ if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x)) TREE_PUBLIC (name) = 1; IDENTIFIER_GLOBAL_VALUE (name) = x; /* Don't forget if the function was used via an implicit decl. */ if (IDENTIFIER_IMPLICIT_DECL (name) && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name))) TREE_USED (x) = 1, TREE_USED (name) = 1; /* Don't forget if its address was taken in that way. */ if (IDENTIFIER_IMPLICIT_DECL (name) && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name))) TREE_ADDRESSABLE (x) = 1; /* Warn about mismatches against previous implicit decl. */ if (IDENTIFIER_IMPLICIT_DECL (name) != 0 /* If this real decl matches the implicit, don't complain. */ && ! (TREE_CODE (x) == FUNCTION_DECL && TREE_TYPE (TREE_TYPE (x)) == integer_type_node)) warning ("`%s' was previously implicitly declared to return `int'", IDENTIFIER_POINTER (name)); /* If this decl is `static' and an `extern' was seen previously, that is erroneous. */ if (TREE_PUBLIC (name) && ! TREE_PUBLIC (x) && ! TREE_EXTERNAL (x)) { if (IDENTIFIER_IMPLICIT_DECL (name)) warning ("`%s' was declared implicitly `extern' and later `static'", IDENTIFIER_POINTER (name)); else warning ("`%s' was declared `extern' and later `static'", IDENTIFIER_POINTER (name)); } } else { /* Here to install a non-global value. */ tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name); IDENTIFIER_LOCAL_VALUE (name) = x; /* If this is an extern function declaration, see if we have a global definition for the function. */ if (oldlocal == 0 && oldglobal != 0 && TREE_CODE (x) == FUNCTION_DECL && TREE_CODE (oldglobal) == FUNCTION_DECL) { /* We have one. Their types must agree. */ if (! comptypes (TREE_TYPE (x), TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)))) warning_with_decl (x, "local declaration of `%s' doesn't match global one"); /* If the global one is inline, make the local one inline. */ else if (TREE_INLINE (oldglobal) || DECL_FUNCTION_CODE (oldglobal) != NOT_BUILT_IN || (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != 0 && TYPE_ARG_TYPES (TREE_TYPE (x)) == 0)) IDENTIFIER_LOCAL_VALUE (name) = oldglobal; } /* If we have a local external declaration, and no file-scope declaration has yet been seen, then if we later have a file-scope decl it must not be static. */ if (oldlocal == 0 && oldglobal == 0 && TREE_EXTERNAL (x) && TREE_PUBLIC (x)) { TREE_PUBLIC (name) = 1; } /* Warn if shadowing an argument at the top level of the body. */ if (oldlocal != 0 && !TREE_EXTERNAL (x) && TREE_CODE (oldlocal) == PARM_DECL && TREE_CODE (x) != PARM_DECL && current_binding_level->level_chain->parm_flag) warning ("declaration of `%s' shadows a parameter", IDENTIFIER_POINTER (name)); /* Maybe warn if shadowing something else. */ else if (warn_shadow && !TREE_EXTERNAL (x) /* No shadow warnings for vars made for inlining. */ && !TREE_INLINE (x)) { char *warnstring = 0; if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL) warnstring = "declaration of `%s' shadows a parameter"; else if (oldlocal != 0) warnstring = "declaration of `%s' shadows previous local"; else if (IDENTIFIER_GLOBAL_VALUE (name) != 0) warnstring = "declaration of `%s' shadows global declaration"; if (warnstring) warning (warnstring, IDENTIFIER_POINTER (name)); } /* If storing a local value, there may already be one (inherited). If so, record it for restoration when this binding level ends. */ if (oldlocal != 0) b->shadowed = tree_cons (name, oldlocal, b->shadowed); } /* Keep count of variables in this level with incomplete type. */ if (TYPE_SIZE (TREE_TYPE (x)) == 0) ++b->n_incomplete; } /* Put decls on list in reverse order. We will reverse them later if necessary. */ TREE_CHAIN (x) = b->names; b->names = x; return x;}/* Generate an implicit declaration for identifier FUNCTIONID as a function of type int (). Print a warning if appropriate. */treeimplicitly_declare (functionid) tree functionid;{ register tree decl; /* Save the decl permanently so we can warn if definition follows. */#if 0 /* A temporary implicit decl causes a crash in pushdecl. In 1.38, fix pushdecl. */ if (flag_traditional || !warn_implicit || current_binding_level == global_binding_level)#endif end_temporary_allocation (); /* We used to reuse an old implicit decl here, but this loses with inline functions because it can clobber the saved decl chains. *//* if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0) decl = IDENTIFIER_IMPLICIT_DECL (functionid); else */ decl = build_decl (FUNCTION_DECL, functionid, default_function_type); TREE_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; /* ANSI standard says implicit declarations are in the innermost block. So we record the decl in the standard fashion. If flag_traditional is set, pushdecl does it top-level. */ pushdecl (decl); rest_of_decl_compilation (decl, 0, 0, 0); if (warn_implicit /* Only one warning per identifier. */ && IDENTIFIER_IMPLICIT_DECL (functionid) == 0) warning ("implicit declaration of function `%s'", IDENTIFIER_POINTER (functionid)); IDENTIFIER_IMPLICIT_DECL (functionid) = decl;#if 0 if (flag_traditional || ! warn_implicit || current_binding_level == global_binding_level)#endif resume_temporary_allocation ();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -