📄 decl.c
字号:
/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */static tree shadowed_labels;/* The FUNCTION_DECL for the function currently being compiled, or 0 if between functions. */tree current_function_decl;/* Set to 0 at beginning of a function definition, set to 1 if a return statement that specifies a return value is seen. */int current_function_returns_value;/* Set to 0 at beginning of a function definition, set to 1 if a return statement with no argument is seen. */int current_function_returns_null;/* Set to 0 at beginning of a function definition, and whenever a label (case or named) is defined. Set to value of expression returned from function when that value can be transformed into a named return value. */tree current_function_return_value;/* Set to nonzero by `grokdeclarator' for a function whose return type is defaulted, if warnings for this are desired. */static int warn_about_return_type;/* Nonzero means give `double' the same size as `float'. */extern int flag_short_double;/* Nonzero means don't recognize any builtin functions. */extern int flag_no_builtin;/* Nonzero means don't recognize the non-ANSI builtin functions. -ansi sets this. */extern int flag_no_nonansi_builtin;/* Nonzero means enable obscure ANSI features and disable GNU extensions that might cause ANSI-compliant code to be miscompiled. */extern int flag_ansi;/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes) objects. */extern int flag_huge_objects;/* Nonzero if we want to conserve space in the .o files. We do this by putting uninitialized data and runtime initialized data into .common instead of .data at the expense of not flagging multiple definitions. */extern int flag_conserve_space;/* Pointers to the base and current top of the language name stack. */extern tree *current_lang_base, *current_lang_stack;/* C and C++ flags are in decl2.c. *//* Set to 0 at beginning of a constructor, set to 1 if that function does an allocation before referencing its instance variable. */static int current_function_assigns_this;int current_function_just_assigned_this;/* Set to 0 at beginning of a function. Set non-zero when store_parm_decls is called. Don't call store_parm_decls if this flag is non-zero! */int current_function_parms_stored;/* Flag used when debugging spew.c */extern int spew_debug;/* This is a copy of the class_shadowed list of the previous class binding contour when at global scope. It's used to reset IDENTIFIER_CLASS_VALUEs when entering another class scope (i.e. a cache miss). */extern tree previous_class_values;/* A expression of value 0 with the same precision as a sizetype node, but signed. */tree signed_size_zero_node;/* Allocate a level of searching. */staticstruct stack_level *push_decl_level (stack, obstack) struct stack_level *stack; struct obstack *obstack;{ struct stack_level tem; tem.prev = stack; return push_stack_level (obstack, (char *)&tem, sizeof (tem));}/* For each binding contour we allocate a binding_level structure which records the names defined in that contour. Contours include: 0) the global one 1) one for each function definition, where internal declarations of the parameters appear. 2) one for each compound statement, to record its declarations. The current meaning of a name can be found by searching the levels from the current one out to the global one. Off to the side, may be the class_binding_level. This exists only to catch class-local declarations. It is otherwise nonexistent. Also there may be binding levels that catch cleanups that must be run when exceptions occur. *//* Note that the information in the `names' component of the global contour is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */struct binding_level { /* A chain of _DECL nodes for all variables, constants, functions, and typedef types. These are in the reverse of the order supplied. */ tree names; /* A list of structure, union and enum definitions, for looking up tag names. It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name, or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE, or ENUMERAL_TYPE node. C++: the TREE_VALUE nodes can be simple types for component_bindings. */ tree tags; /* For each level, a list of shadowed outer-level local definitions to be restored when this level is popped. Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and whose TREE_VALUE is its old definition (a kind of ..._DECL node). */ tree shadowed; /* Same, for IDENTIFIER_CLASS_VALUE. */ tree class_shadowed; /* Same, for IDENTIFIER_TYPE_VALUE. */ tree type_shadowed; /* For each level (except not the global one), a chain of BLOCK nodes for all the levels that were entered and exited one level down. */ tree blocks; /* The BLOCK node for this level, if one has been preallocated. If 0, the BLOCK is allocated (if needed) when the level is popped. */ tree this_block; /* The binding level which this one is contained in (inherits from). */ struct binding_level *level_chain; /* List of decls in `names' that have incomplete structure or union types. */ tree incomplete; /* List of VAR_DECLS saved from a previous for statement. These would be dead in ANSI-conforming code, but might be referenced in ARM-era code. */ tree dead_vars_from_for; /* 1 for the level that holds the parameters of a function. 2 for the level that holds a class declaration. 3 for levels that hold parameter declarations. */ unsigned parm_flag : 4; /* 1 means make a BLOCK for this level regardless of all else. 2 for temporary binding contours created by the compiler. */ unsigned keep : 3; /* Nonzero if this level "doesn't exist" for tags. */ unsigned tag_transparent : 1; /* Nonzero if this level can safely have additional cleanup-needing variables added to it. */ unsigned more_cleanups_ok : 1; unsigned have_cleanups : 1; /* Nonzero if this level is for storing the decls for template parameters and generic decls; these decls will be discarded and replaced with a TEMPLATE_DECL. */ unsigned pseudo_global : 1; /* This is set for a namespace binding level. */ unsigned namespace_p : 1; /* True if this level is that of a for-statement where we need to worry about ambiguous (ARM or ANSI) scope rules. */ unsigned is_for_scope : 1; /* Two bits left for this word. */#if defined(DEBUG_CP_BINDING_LEVELS) /* Binding depth at which this level began. */ unsigned binding_depth;#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ };#define NULL_BINDING_LEVEL ((struct binding_level *) NULL) /* The (non-class) binding level currently in effect. */static struct binding_level *current_binding_level;/* The binding level of the current class, if any. */static struct binding_level *class_binding_level;/* The current (class or non-class) binding level currently in effect. */#define inner_binding_level \ (class_binding_level ? class_binding_level : current_binding_level)/* A chain of binding_level structures awaiting reuse. */static struct binding_level *free_binding_level;/* The outermost binding level, for names of file scope. This is created when the compiler is started and exists through the entire run. */static struct binding_level *global_binding_level;/* Binding level structures are initialized by copying this one. */static struct binding_level clear_binding_level;/* Nonzero means unconditionally make a BLOCK for the next level pushed. */static int keep_next_level_flag;#if defined(DEBUG_CP_BINDING_LEVELS)static int binding_depth = 0;static int is_class_level = 0;static voidindent (){ register unsigned i; for (i = 0; i < binding_depth*2; i++) putc (' ', stderr);}#endif /* defined(DEBUG_CP_BINDING_LEVELS) */static tree pushdecl_with_scope PROTO((tree, struct binding_level *));static voidpush_binding_level (newlevel, tag_transparent, keep) struct binding_level *newlevel; int tag_transparent, keep;{ /* Add this level to the front of the chain (stack) of levels that are active. */ *newlevel = clear_binding_level; if (class_binding_level) { newlevel->level_chain = class_binding_level; class_binding_level = (struct binding_level *)0; } else { newlevel->level_chain = current_binding_level; } current_binding_level = newlevel; newlevel->tag_transparent = tag_transparent; newlevel->more_cleanups_ok = 1; newlevel->keep = keep;#if defined(DEBUG_CP_BINDING_LEVELS) newlevel->binding_depth = binding_depth; indent (); fprintf (stderr, "push %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", newlevel, lineno); is_class_level = 0; binding_depth++;#endif /* defined(DEBUG_CP_BINDING_LEVELS) */}static voidpop_binding_level (){ if (class_binding_level) current_binding_level = class_binding_level; if (global_binding_level) { /* cannot pop a level, if there are none left to pop. */ if (current_binding_level == global_binding_level) my_friendly_abort (123); } /* Pop the current level, and free the structure for reuse. */#if defined(DEBUG_CP_BINDING_LEVELS) binding_depth--; indent (); fprintf (stderr, "pop %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", current_binding_level, lineno); if (is_class_level != (current_binding_level == class_binding_level)) { indent (); fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); } is_class_level = 0;#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ { register struct binding_level *level = current_binding_level; current_binding_level = current_binding_level->level_chain; level->level_chain = free_binding_level;#if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */ if (level->binding_depth != binding_depth) abort ();#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ free_binding_level = level; class_binding_level = current_binding_level; if (class_binding_level->parm_flag != 2) class_binding_level = 0; while (current_binding_level->parm_flag == 2) current_binding_level = current_binding_level->level_chain; }}static voidsuspend_binding_level (){ if (class_binding_level) current_binding_level = class_binding_level; if (global_binding_level) { /* cannot suspend a level, if there are none left to suspend. */ if (current_binding_level == global_binding_level) my_friendly_abort (123); } /* Suspend the current level. */#if defined(DEBUG_CP_BINDING_LEVELS) binding_depth--; indent (); fprintf (stderr, "suspend %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", current_binding_level, lineno); if (is_class_level != (current_binding_level == class_binding_level)) { indent (); fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); } is_class_level = 0;#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ { current_binding_level = current_binding_level->level_chain; class_binding_level = current_binding_level; if (class_binding_level->parm_flag != 2) class_binding_level = 0; while (current_binding_level->parm_flag == 2) current_binding_level = current_binding_level->level_chain; }}static voidresume_binding_level (b) struct binding_level *b;{ if (class_binding_level) {#if 1 /* These are here because we cannot deal with shadows yet. */ sorry ("cannot resume a namespace inside class"); return;#else b->level_chain = class_binding_level; class_binding_level = (struct binding_level *)0;#endif } else {#if 1 /* These are here because we cannot deal with shadows yet. */ if (b->level_chain != current_binding_level) { sorry ("cannot resume a namespace inside a different namespace"); return; }#endif b->level_chain = current_binding_level; } current_binding_level = b;#if defined(DEBUG_CP_BINDING_LEVELS) b->binding_depth = binding_depth; indent (); fprintf (stderr, "resume %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", b, lineno); is_class_level = 0; binding_depth++;#endif /* defined(DEBUG_CP_BINDING_LEVELS) */}/* Create a new `struct binding_level'. */staticstruct binding_level *make_binding_level (){ /* NOSTRICT */ return (struct binding_level *) xmalloc (sizeof (struct binding_level));}/* Nonzero if we are currently in the global binding level. */intglobal_bindings_p (){ return current_binding_level == global_binding_level;}/* Nonzero if we are currently in a toplevel binding level. This means either the global binding level or a namespace in a toplevel binding level. */inttoplevel_bindings_p (){ struct binding_level *b = current_binding_level; while (1) { if (b == global_binding_level) return 1; if (b->pseudo_global) return 1; if (! b->namespace_p) return 0; b=b->level_chain; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -