4.1.3.1.2. Read in file
Above at line 439, if the file has been found and opened successfully, _cpp_find_file returns the corresponding _cpp_file object, and refered by pfile->main_file. So at this point, it can begin read in the file content.
cpp_read_main_file (continue)
473 _cpp_stack_file (pfile, pfile->main_file, false);
474
475 /* For foo.i, read the original filename foo.c now, for the benefit
476 of the front ends. */
477 if (CPP_OPTION (pfile, preprocessed))
478 {
479 read_original_filename (pfile);
480 if (!pfile->map)
481 return NULL;
482 fname = pfile->map->to_file;
483 }
484 return fname;
485 }
In below functions, parameter import is true, if the file is included by #import directive. About the #import directive, [6] gives out below explaination.
GNU CPP supports two more ways of indicating that a header file should be read only once. Neither one is as portable as a wrapper ‘#ifdef’, and we recommend you do not use them in new programs. In the Objective-C language, there is a variant of ‘#include’ called ‘#import’ which includes a file, but does so at most once. If you use ‘#import’ instead of ‘#include’, then you don’t need the conditionals inside the header file to prevent multiple inclusion of the cntents. GCC premits the use of ‘#import’ in C and C++ as well as Objective-C. However, it is not in standard Cor C++ and should therefore not be used by portable programs. ‘#import’ is not a well designed feature. It requires the users of a header file to know that it should only be included once. It is much better for the header file’s implementor to write the file so that users don’t need to know this. Using a wrapper ‘#ifndef’ accomplishes this goal. In the present implementation, a single use of ‘#import’ will prevent the file from ever being read again, by either ‘#import’ or ‘#include’. You should not rely on this; do not use both ‘#import’ and ‘#include’ to refer to the same header file. Another way to prevent aheader file from being included more than once is with the ‘#pragma once’ directive. If ‘#pragm once’ is seen when scanning a header file, that file will never be read again, no matter what. ‘#pragma once’ does not have the problems that ‘#import’ does, but it is not recognize by all preprocessors, so you cannot rely on it in a portable program. |
643 bool
644 _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) in cppfiles.c
645 {
646 cpp_buffer *buffer;
647 int sysp;
648
649 if (!should_stack_file (pfile, file, import))
640 return false;
Here, for file included by ‘#import’ directive, once_only, seen_once_only will be set at line 563 below in _cpp_mark_file_once_only, so next time the file read again, it will exit at line 556. Then at line 572 below, it checks if the file has a defined header guard.
549 static bool
550 should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) in cppfiles.c
551 {
552 _cpp_file *f;
553
554 /* Skip once-only files. */
555 if (file->once_only)
556 return false;
557
558 /* We must mark the file once-only if #import now, before header
559 guard checks. Otherwise, undefining the header guard might
560 cause the file to be re-stacked. */
561 if (import)
562 {
563 _cpp_mark_file_once_only (pfile, file);
564
565 /* Don't stack files that have been stacked before. */
566 if (file->stack_count)
567 return false;
568 }
569
570 /* Skip if the file had a header guard and the macro is defined.
571 PCH relies on this appearing before the PCH handler below. */
572 if (file->cmacro && file->cmacro->type == NT_MACRO)
573 return false;
574
575 /* Handle PCH files immediately; don't stack them. */
576 if (include_pch_p (file))
577 {
578 pfile->cb.read_pch (pfile, file->path, file->fd, file->pchname);
579 close (file->fd);
580 file->fd = -1;
581 return false;
582 }
4.1.3.1.2.1. Case of PCH file
Above at line 576, include_pch_p checks the field pch of _cpp_file to see if the file is PCH (precompiled header), this field is set in pch_open_file if the PCH file is validate.
375 void
376 c_common_read_pch (cpp_reader *pfile, const char *name, in c-pch.c
377 int fd, const char *orig_name ATTRIBUTE_UNUSED)
378 {
379 FILE *f;
380 struct c_pch_header h;
381 char *buf;
382 unsigned long written;
383 struct save_macro_data *smd;
384
385 f = fdopen (fd, "rb");
386 if (f == NULL)
387 {
388 cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
389 return;
390 }
391
392 cpp_get_callbacks (parse_in)->valid_pch = NULL;
393
394 if (fread (&h, sizeof (h), 1, f) != 1)
395 {
396 cpp_errno (pfile, CPP_DL_ERROR, "reading");
397 return;
398 }
399
400 buf = xmalloc (16384);
401 for (written = 0; written < h.asm_size; )
402 {
403 long size = h.asm_size - written;
404 if (size > 16384)
405 size = 16384;
406 if (fread (buf, size, 1, f) != 1
407 || fwrite (buf, size, 1, asm_out_file) != 1)
408 cpp_errno (pfile, CPP_DL_ERROR, "reading");
409 written += size;
410 }
411 free (buf);
412
413 cpp_prepare_state (pfile, &smd);
414
415 gt_pch_restore (f);
416
417 if (cpp_read_state (pfile, name, f, smd) != 0)
418 return;
419
420 fclose (f);
421 }
Notice that here fd refers to the already opened validate PCH file, by fdopen at line 385 above, we will continue the reading at postion following target_data in the file. At that positon it should contains c_pch_header which only contains a field asm_size, and it indicates the size of the assemble code of the PCH file. It is written into asm_out_file.
If PCH file only contents assemble code, what is difference between it and library? And how can we use the data structures and functions defined in it? Thus, after the part of assemble code, PCH file also includes the content in form of intermediate tree, after reading in this part and merging into the tree of current compilation unit, PCH file acts exactly as normal header.
589 void
590 cpp_prepare_state (cpp_reader *r, struct save_macro_data **data) in cpppch.c
591 {
592 struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
593
594 d->macros = NULL;
595 d->count = ARRAY_SIZE (d->macros->macs);
596 cpp_forall_identifiers (r, save_macros, d);
597 d->saved_pragmas = _cpp_save_pragma_names (r);
598 *data = d;
599 }
In cpp_reader, it contains field hash_table which is first initialized in _cpp_init_hashtable. In preprocessing stage, it works as hashtable for visible macros in the file. The instance of cpp_reader always stands for current handling file; now as we are handling PCH header file, we need to update the cpp_reader instance, first it needs save the macros seen so far for current file.
546 struct save_macro_item { in cpppch.c
547 struct save_macro_item *next;
548 struct cpp_hashnode macs[64];
549