According to [6], header file included by –include option is included before any header file included in source file, but this header file should be handled after file specified by –macro being handled. If multiple ‘-include’ options are given, the files are included in the order they appear on the command line.
finish_options (continue)
1466 include_cursor = 0;
1467 push_command_line_include ();
1468 }
First at line 1466 abve, include_cursor is set as 0, means no –include option has been handled among delayed options. Note that in below, if we read in a header specified by an –include option, we return at line 1480, leaving unhandled –include options within deferred_opts.
1471 static void
1472 push_command_line_include (void) in c-opts.c
1473 {
1474 while (include_cursor < deferred_count)
1475 {
1476 struct deferred_opt *opt = &deferred_opts[include_cursor++];
1477
1478 if (! cpp_opts->preprocessed && opt->code == OPT_include
1479 && cpp_push_include (parse_in, opt->arg))
1480 return;
1481 }
1482
1483 if (include_cursor == deferred_count)
1484 {
1485 include_cursor++;
1486 /* -Wunused-macros should only warn about macros defined hereafter. */
1487 cpp_opts->warn_unused_macros = warn_unused_macros;
1488 /* Restore the line map from <command line>. */
1489 if (! cpp_opts->preprocessed)
1490 cpp_change_file (parse_in, LC_RENAME, main_input_filename);
1491
1492 /* Set this here so the client can change the option if it wishes,
1493 and after stacking the main file so we don't trace the main file. */
1494 cpp_get_line_maps (parse_in)->trace_includes
1495 = cpp_opts->print_include_names;
1496 }
1497 }
So how to realize include multiple header files included by –include option? The answer starts at cb_file_change. In cb_file_change, there is code as below:
1509 if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map)))
1510 push_command_line_include ();
And at line 1158 in c_common_post_options, cb_file_change is assigned to hook file_change in field cb of cpp_reader, which is invoked in _cpp_do_file_change. And before that, in the function, linemap_add is called to add an line_map into map list in cpp_reader to record the file change.
If it is the finish of file readin, for example, the header file included by –include option here, then _cpp_pop_buffer is called by _cpp_get_fresh_line. _cpp_pop_buffer has following definition.
1949 void
1950 _cpp_pop_buffer (cpp_reader *pfile) in cpplib.c
1951 {
1952 cpp_buffer *buffer = pfile->buffer;
1953 struct _cpp_file *inc = buffer->file;
1954 struct if_stack *ifs;
1955
1956 /* Walk back up the conditional stack till we reach its level at
1957 entry to this file, issuing error messages. */
1958 for (ifs = buffer->if_stack; ifs; ifs = ifs->next)
1959 cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0,
1960 "unterminated #%s", dtable[ifs->type].name);
1961
1962 /* In case of a missing #endif. */
1963 pfile->state.skipping = 0;
1964
1965 /* _cpp_do_file_change expects pfile->buffer to be the new one. */
1966 pfile->buffer = buffer->prev;
1967
1968 free (buffer->notes);
1969
1970 /* Free the buffer object now; we may want to push a new buffer
1971 in _cpp_push_next_include_file. */
1972 obstack_free (&pfile->buffer_ob, buffer);
1973
1974 if (inc)
1975 {
1976 _cpp_pop_file_buffer (pfile, inc);
1977
1978 _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
1979 }
1980 }
Above at line 1953, buffer->file is only set in _cpp_stack_file, to stand for the major readin buffer of the file, and other buffers added in during the file processing (for example, in do_pragma), are created upon obstack, neither setting field file, nor releasing manually.
So for our header file included by –include option, the created line_map meets condition at line 1509, causes push_command_line_include tries to include next header files. Note at line 1479, cpp_push_include invokes _cpp_stack_include (refers to Stack the file (exclude PCH file)). Cyclizing in this way, till all header files included by –include options are handled.
If given option –output-pch, the header file besides being compiled, PCH file (pre-compiled header file) will also be generated. In this option, the name of the PCH file is specified and saved in variable pch_file. Here pch_init will prepare the head for will being generated PCH file.
108 void
109 pch_init (void) in c-pch.c
110 {
111 FILE *f;
112 struct c_pch_validity v;
113 void *target_validity;
114 static const char partial_pch[IDENT_LENGTH] = "gpcWrite";
115 unsigned int current_flags_info = 0;
116
117 if (! pch_file)
118 return;
119
120 if (flag_unit_at_a_time)
121 current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
122
123 f = fopen (pch_file, "w+b");
124 if (f == NULL)
125 fatal_error ("can't create precompiled header %s: %m", pch_file);
126 pch_outfile = f;
127
128 if (strlen (host_machine) > 255 || strlen (target_machine) > 255
129 || strlen (version_string) > 255)
130 abort ();
131
132 v.host_machine_length = strlen (host_machine);
133 v.target_machine_length = strlen (target_machine);
134 v.version_length = strlen (version_string);
135 v.debug_info_type = write_symbols;
136 v.flags_info = current_flags_info;
137 v.pch_init = &pch_init;
138 target_validity = targetm.get_pch_validity (&v.target_data_length);
139
140 if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
141 || fwrite (&v, sizeof (v), 1, f) != 1
142 || fwrite (host_machine, v.host_machine_length, 1, f) != 1
143 || fwrite (target_machine, v.target_machine_length, 1, f) != 1
144 || fwrite (version_string, v.version_length, 1, f) != 1
145 || fwrite (target_validity, v.target_data_length, 1, f) != 1)
146 fatal_error ("can't write to %s: %m", pch_file);
147
148 /* We need to be able to re-read the output. */
149 /* The driver always provides a valid -o option. */
150 if (asm_file_name == NULL
151 || strcmp (asm_file_name, "-") == 0)
152 fatal_error ("`%s' is not a valid output file", asm_file_name);
153
154 asm_file_startpos = ftell (asm_out_file);
155
156 /* Let the debugging format deal with the PCHness. */
157 (*debug_hooks->handle_pch) (0);
158
159 cpp_save_state (parse_in, f);
160 }
As we have seen, c_pch_validity describes the structure of PCH file, refers to figure pch file layout for detail. At line 138, hook get_pch_validity will generate target data for the PCH file. Here, this hook routes the invocation to default_get_pch_validity.
4069 void *
4070 default_get_pch_validity (size_t *len) in toplev.c
4071 {
4072 #ifdef TARGET_OPTIONS
4073 size_t i;
4074 #endif
4075 char *result, *r;
4076
4077 *len = sizeof (target_flags) + 2;
4078 #ifdef TARGET_OPTIONS
4079 for (i = 0; i < ARRAY_SIZE (target_options); i++)
4080 {
4081 *len += 1;
4082 if (*target_options[i].variable)
4083 *len += strlen (*target_options[i].variable);
4084 }
4085 #endif
4086
4087 result = r = xmalloc (*len);
4088 r[0] = flag_pic;
4089 r[1] = flag_pie;
4090 r += 2;
4091 memcpy (r, &target_flags, sizeof (target_flags));
4092 r += sizeof (target_flags);
4093
4094 #ifdef TARGET_OPTIONS
4095 for (i = 0; i < ARRAY_SIZE (target_options); i++)
4096 {
4097 const char *str = *target_options[i].variable;
4098 size_t l;
4099 if (! str)
4100 str = "";
4101 l = strlen (str) + 1;
4102 memcpy (r, str, l);
4103 r += l;
4104 }
4105 #endif
4106
4107 return result;
4108 }
The content of target_options can refer to section Initializing options related to target, while the layout of target data segment in PCH file can refer to figure Layout of target data of PCH file.
Below function saves the current definitions of the parse_in for dependency checking purposes. It executes before handling the first source file. At that time parse_in contains definitions added by finish_options (it includes builtin deifnitions and user definition via –D or -U option). Here argument f is the file handle opened for PCH file specified by –output-pch in pch_file.
192 int
193 cpp_save_state (cpp_reader *r, FILE *f) in cpppch.c
194 {
195 /* Save the list of non-void identifiers for the dependency checking. */
196 r->savedstate = xmalloc (sizeof (struct cpp_savedstate));
197 r->savedstate->definedhash = htab_create (100, cpp_string_hash,
198 cpp_string_eq, NULL);
199 cpp_forall_identifiers (r, save_idents, r->savedstate);
200
201 /* Write out the list of defined identifiers. */
202 cpp_forall_identifiers (r, write_macdef, f);
203
204 return 0;
205 }
Struct cpp_savestate has following definition. Slot definedhash is the hash table to hold the name of definitions.
103 struct cpp_savedstate in cpppch.c
104 {
105 /* A hash table of the defined identifiers. */
106 htab_t definedhash;
107 /* The size of the definitions of those identifiers (the size of
108 'definedstrs'). */
109 size_t hashsize;
110 /* Number of definitions */
111 size_t n_defs;
112 /* Array of definitions. In cpp_write_pch_deps it is used for sorting. */
113 cpp_hashnode **defs;
114 /* Space for the next definition. Definitions are null-terminated
115 strings. */
116 unsigned char *definedstrs;
117 };
Routine cpp_forall_identifiers iterates the hash_table of parse_in which is the hash table for identifiers. As we have seen in previous section, the node of the hash table can be explained in two way, one into tree node, the other into cpp_hashnode which is passed as argument hn below. Note that last argument of htab_find_slot at line 134 is INSERT, it will add an empty node for absent identifier automatically.
122 static int
123 save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
124 {
125 struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
126
127 if (hn->type != NT_VOID)
128 {
129 struct cpp_string news;
130 void **slot;
131
132 news.len = NODE_LEN (hn);
133 news.text= NODE_NAME (hn);
134 slot = htab_find_slot (ss->definedhash, &news, INSERT);
135 if (*slot == NULL)
136 {
137 struct cpp_string *sp;
138 unsigned char *text;
139
140 sp = xmalloc (sizeof (struct cpp_string));
141 *slot = sp;
142
143 sp->len = NODE_LEN (hn);
144 sp->text = text = xmalloc (NODE_LEN (hn));
145 memcpy (text, NODE_NAME (hn), NODE_LEN (hn));
146 }
147 }
148
149 return 1;
150 }
In first iteration, we get all names of the identifiers. In second iteration, we record all macro definitions. Note, as we are still under preprocessing, in the view of preprocessor, nodes are of three kinds: NT_VOID, NT_MACRO, and NT_ASSERTION.
48 static int
49 write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) in cpppch.c
50 {
51 FILE *f = (FILE *) file_p;
52 switch (hn->type)
53 {
54 case NT_VOID:
55 if (! (hn->flags & NODE_POISONED))
56 return 1;
57
58 case NT_MACRO:
59 if ((hn->flags & NODE_BUILTIN))
60 return 1;
61
62 {
63 struct macrodef_struct s;
64 const unsigned char *defn;
65
66 s.name_length = NODE_LEN (hn);
67 s.flags = hn->flags & NODE_POISONED;
68
69 if (hn->type == NT_MACRO)
70 {
71 defn = cpp_macro_definition (pfile, hn);
72 s.definition_length = ustrlen (defn);
73 }
74 else
75 {
76 defn = NODE_NAME (hn);
77 s.definition_length = s.name_length;
78 }
79
80 if (fwrite (&s, sizeof (s), 1, f) != 1
81 || fwrite (defn, 1, s.definition_length, f) != s.definition_length)
82 {
83 cpp_errno (pfile, CPP_DL_ERROR,
84 "while writing precompiled header");
85 return 0;
86 }
87 }
88 return 1;
89
90 case NT_ASSERTION:
91 /* Not currently implemented. */
92 return 1;
93
94 default:
95 abort ();
96 }
97 }
The macro definition is recorded in slot of cpp_macro within hashnode and field macro_buffer of cpp_reader. The content written into the PCH file is what we read from PCH file as section Read in macro defintions reveals.
1605 const unsigned char *
1606 cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) in cppmacro.c
1607 {
1608 unsigned int i, len;
1609 const cpp_macro *macro = node->value.macro;
1610 unsigned char *buffer;
1611
1612 if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN))
1613 {
1614 cpp_error (pfile, CPP_DL_ICE,
1615 "invalid hash type %d in cpp_macro_definition", node->type);
1616 return 0;
1617 }
1618
1619 /* Calculate length. */
1620 len = NODE_LEN (node) + 2; /* ' ' and NUL. */
1621 if (macro->fun_like)
1622 {
1623 len += 4; /* "()" plus possible final ".." of named
1624 varargs (we have + 1 below). */
1625 for (i = 0; i < macro->paramc; i++)
1626 len += NODE_LEN (macro->params[i]) + 1; /* "," */
1627 }
1628
1629 /* This should match below where we fill in the buffer. */
1630 if (CPP_OPTION (pfile, traditional))
1631 len += _cpp_replacement_text_len (macro);
1632 else
1633 {
1634 for (i = 0; i < macro->count; i++)
1635 {
1636 cpp_token *token = ¯o->exp.tokens[i];
1637
1638 if (token->type == CPP_MACRO_ARG)
1639 len += NODE_LEN (macro->params[token->val.arg_no - 1]);
1640 else
1641 len += cpp_token_len (token);
1642
1643 if (token->flags & STRINGIFY_ARG)
1644 len++; /* "#" */
1645 if (token->flags & PASTE_LEFT)
1646 len += 3; /* " ##" */
1647 if (token->flags & PREV_WHITE)
1648 len++; /* " " */
1649 }
1650 }
1651
1652 if (len > pfile->macro_buffer_len)
1653 {
1654 pfile->macro_buffer = xrealloc (pfile->macro_buffer, len);
1655 pfile->macro_buffer_len = len;
1656 }
1657
1658 /* Fill in the buffer. Start with the macro name. */
1659 buffer = pfile->macro_buffer;
1660 memcpy (buffer, NODE_NAME (node), NODE_LEN (node));
1661 buffer += NODE_LEN (node);
1662
1663 /* Parameter names. */
1664 if (macro->fun_like)
1665 {
1666 *buffer++ = '(';
1667 for (i = 0; i < macro->paramc; i++)
1668 {
1669 cpp_hashnode *param = macro->params[i];
1670
1671 if (param != pfile->spec_nodes.n__VA_ARGS__)
1672 {
1673 memcpy (buffer, NODE_NAME (param), NODE_LEN (param));
1674 buffer += NODE_LEN (param);
1675 }
1676
1677 if (i + 1 < macro->paramc)
1678 /* Don't emit a space after the comma here; we're trying
1679 to emit a Dwarf-friendly definition, and the Dwarf spec
1680 forbids spaces in the argument list. */
1681 *buffer++ = ',';
1682 else if (macro->variadic)
1683 *buffer++ = '.', *buffer++ = '.', *buffer++ = '.';
1684 }
1685 *buffer++ = ')';
1686 }
1687
1688 /* The Dwarf spec requires a space after the macro name, even if the
1689 definition is the empty string. */
1690 *buffer++ = ' ';
1691
1692 if (CPP_OPTION (pfile, traditional))
1693 buffer = _cpp_copy_replacement_text (macro, buffer);
1694 else if (macro->count)
1695 /* Expansion tokens. */
1696 {
1697 for (i = 0; i < macro->count; i++)
1698 {
1699 cpp_token *token = ¯o->exp.tokens[i];
1700
1701 if (token->flags & PREV_WHITE)
1702 *buffer++ = ' ';
1703 if (token->flags & STRINGIFY_ARG)
1704 *buffer++ = '#';
1705
1706 if (token->type == CPP_MACRO_ARG)
1707 {
1708 memcpy (buffer,
1709 NODE_NAME (macro->params[token->val.arg_no - 1]),
1710 NODE_LEN (macro->params[token->val.arg_no - 1]));
1711 buffer += NODE_LEN (macro->params[token->val.arg_no - 1]);
1712 }
1713 else
1714 buffer = cpp_spell_token (pfile, token, buffer);
1715
1716 if (token->flags & PASTE_LEFT)
1717 {
1718 *buffer++ = ' ';
1719 *buffer++ = '#';
1720 *buffer++ = '#';
1721 /* Next has PREV_WHITE; see _cpp_create_definition. */
1722 }
1723 }
1724 }
1725
1726 *buffer = '/0';
1727 return pfile->macro_buffer;
1728 }
The function just walks into the macro definition and first counts the size of buffer needed, then copy the whole definition in macro_buffer slot of cpp_reader, which when returns back write_macrodef is written into the PCH file.