📄 decl.c
字号:
BWAHAHAAHAHahhahahahaah. No, no, no, said the little chicken. Look at the pretty struct named_label_list. See the pretty struct with the pretty named fields that describe what they do. See the pretty lack of gratuitous casts. Notice the code got a lot cleaner. Used only for jumps to as-yet undefined labels, since jumps to defined labels can have their validity checked by stmt.c. */static struct named_label_list *named_label_uses = NULL;/* A list of objects which have constructors or destructors which reside in the global scope. The decl is stored in the TREE_VALUE slot and the initializer is stored in the TREE_PURPOSE slot. */tree static_aggregates;/* -- end of C++ *//* Two expressions that are constants with value zero. The first is of type `int', the second of type `void *'. */tree integer_zero_node;tree null_pointer_node;/* The value for __null (NULL), namely, a zero of an integer type with the same number of bits as a pointer. */tree null_node;/* A node for the integer constants 1, 2, and 3. */tree integer_one_node, integer_two_node, integer_three_node;/* While defining an enum type, this is 1 plus the last enumerator constant value. */static tree enum_next_value;/* Nonzero means that there was overflow computing enum_next_value. */static int enum_overflow;/* Parsing a function declarator leaves a list of parameter names or a chain or parameter decls here. */tree last_function_parms;/* Parsing a function declarator leaves here a chain of structure and enum types declared in the parmlist. */static tree last_function_parm_tags;/* After parsing the declarator that starts a function definition, `start_function' puts here the list of parameter names or chain of decls. `store_parm_decls' finds it here. */static tree current_function_parms;/* Similar, for last_function_parm_tags. */static tree current_function_parm_tags;/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function that have names. Here so we can clear out their names' definitions at the end of the function. */static tree named_labels;/* 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;/* 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;/* The name of the anonymous namespace, throughout this translation unit. */tree anonymous_namespace_name;/* 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. Thus, to see whether a name is bound in the current scope, it is not enough to look in the CURRENT_BINDING_LEVEL. You should use lookup_name_current_level instead. *//* 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. There may be OVERLOADs on this list, too, but they are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */ 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; /* A list of USING_DECL nodes. */ tree usings; /* A list of used namespaces. PURPOSE is the namespace, VALUE the common ancestor with this binding_level's namespace. */ tree using_directives; /* If this binding level is the binding level for a class, then class_shadowed is a TREE_LIST. The TREE_PURPOSE of each node is the name of an entity bound in the class; the TREE_VALUE is the IDENTIFIER_CLASS_VALUE before we entered the class. Thus, when leaving class scope, we can restore the IDENTIFIER_CLASS_VALUE by walking this list. The TREE_TYPE is the DECL bound by this name in the class. */ tree class_shadowed; /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and is used for all binding levels. */ 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. These are stored in a TREE_LIST; the TREE_VALUE is the actual declaration. */ 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 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;/* 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; 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) */}/* Find the innermost enclosing class scope, and reset CLASS_BINDING_LEVEL appropriately. */static voidfind_class_binding_level (){ struct binding_level *level = current_binding_level; while (level && level->parm_flag != 2) level = level->level_chain; if (level && level->parm_flag == 2) class_binding_level = level; else class_binding_level = 0;}static voidpop_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; find_class_binding_level (); }}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; find_class_binding_level ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -