现在的位置: 首页 > 综合 > 正文

Studying note of GCC-3.4.6 source (32)

2013年07月02日 ⁄ 综合 ⁄ 共 6248字 ⁄ 字号 评论关闭
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   

抱歉!评论已关闭.