您的位置:首页 > 其它

Studying note of GCC-3.4.6 source (32)

2010-04-21 09:25 183 查看
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 };

551 struct save_macro_data
552 {
553 struct save_macro_item *macros;
554 size_t count;
555 char **saved_pragmas;
556 };

Note line 595 in cpp_prepare_state, count is 64 for new created buffer.

112 void
113 cpp_forall_identifiers (cpp_reader *pfile, cpp_cb cb, void *v) in cpppch.c
114 {
115 /* We don't need a proxy since the hash table's identifier comes
116 first in cpp_hashnode. */
117 ht_forall (pfile->hash_table, (ht_cb) cb, v);
118 }

209 void
210 ht_forall (hash_table *table, ht_cb cb, const void *v) in hashtable.c
211 {
212 hashnode *p, *limit;
213
214 p = table->entries;
215 limit = p + table->nslots;
216 do
217 if (*p)
218 {
219 if ((*cb) (table->pfile, *p, v) == 0)
220 break;
221 }
222 while (++p < limit);
223 }

Below HT_STR and HT_LEN just access str and len field of ht_identifier of cpp_hashnode. Remember that ht_identifier is the major body of cpp_hashnode and the regular node in hashtable.

561 static int in cpppch.c
562 save_macros (cpp_reader *r ATTRIBUTE_UNUSED, cpp_hashnode *h, void *data_p)
563 {
564 struct save_macro_data *data = (struct save_macro_data *)data_p;
565 if (h->type != NT_VOID
566 && (h->flags & NODE_BUILTIN) == 0)
567 {
568 cpp_hashnode *save;
569 if (data->count == ARRAY_SIZE (data->macros->macs))
570 {
571 struct save_macro_item *d = data->macros;
572 data->macros = xmalloc (sizeof (struct save_macro_item));
573 data->macros->next = d;
574 data->count = 0;
575 }
576 save = data->macros->macs + data->count;
577 data->count++;
578 memcpy (save, h, sizeof (struct cpp_hashnode));
579 HT_STR (&save->ident) = xmemdup (HT_STR (HT_NODE (save)),
580 HT_LEN (HT_NODE (save)),
581 HT_LEN (HT_NODE (save)) + 1);
582 }
583 return 1;
584 }
4.1.3.1.2.1.1. #pragma directive in peprocessing
Following paragraphs are extracted from [6] about #pargma directive
The #pragma directive is the method specified by the C standard for providing additional information to the compiler, beyond what is conveyed in the language itself. Three forms of this directive (commonly known as pragmas) are specified by the 1999 C standard. A C compiler is free to attach any meaning it likes to other pragmas.
GCC has historically preferred to use extension to the syntax of the language, such as __attribute__, for this purpose. However, GCC does define a few pragmas of its own. These mostly have effects on the entire translation unit or souce file.
In GCC version 3, all GNU-defined, supported pragmas have been gvien a GCC prefix. This is in line with the STDC prefix on all pragmas defined by C9. For backward compatibility, pragmas which were recoginzed by previous versions are still recognized without the GCC prefix, but that usage is deprecated. Some older pragmas are deprecated in their entirety. They are not recognized with the GCC prefix.
C99 introduces the _Pragma operator. This feature addresses a major problem with #pragma: being a directive, it cannot be produced as the result of macro expansion.
Its syntax is _Pragma (string-literal), where string-literal can be either a normal or wide character string literal. It is destringized, by replacing all ‘//’ with a single ‘/’ and all ‘/”’ with a ‘”’. The result is then processed as if it had appeared as the right hand side of a #pragma directive. For example,
_Pragma (“GCC dependency /”parse.y/””)
Has the same effect as #pragma GCC dependency “parse.y”. The same effect could be achieved using macros, for example
#define DO_PRAGMA(x) _Pragma (#x)
DO_PRAGMA (GCC dependency “parse.y”)
The standard is unclear on where a _pragma operator can appear. The preprocessor does not accept it within a preprocessing conditional directive like #if. To be safe, you are probably best keeping it out of directives other than #define, and putting it on a line of its own.
The pragmas are meaningful to the preprocessor are:

#pragma GCC dependency
#pragma GCC dependency allows you to check the relative dates of the current file and another file. If the other file is more recent than the current file, a warning is issued. This is useful if the current file is derived from the other file, and should be regenerated. The other file is searched for using the normal include search path. Optional trailing text can be used to give more information in the warning message.
#pragma GCC dependency “parse.y”
#pramga GCC dependency “/usr/include/time.h” rerun fuxincludes

#pragma GCC poison
Sometimes, there is an identifier that you want to remove completely from your program, and make sure that is never creeps back in. To enforce this, you can poison the identifier with this pragma. #pragma GCC poison is followed by a list of identifiers to poison. If any of those identifiers appears anywhere in the source after the directive, it is a hard error. For exmaple,
#pragma GCC poison printf sprintf fprintf
sprintf (some_string, “hello”);
Will produce an error.
If a poisoned identifier appears as part of the expansion of a macro which was defined before the identifier was poisoned, it will not cause an error. This lets you poison an identifier without worrying about system headers defining macros that use it. For example,
#define strrchr rindex
#pragma GCC poison rindex
strrchr (someth_string, ‘h’);
will not produce an error.

#pragma GCC system_header
This pragma takes no arguments. It causes the rest of the code in the current file to be treated as if it came from as system header.
1095 char **
1096 _cpp_save_pragma_names (cpp_reader *pfile) in cpplib.c
1097 {
1098 int ct = count_registered_pragmas (pfile->pragmas);
1099 char **result = xnewvec (char *, ct);
1100 (void) save_registered_pragmas (pfile->pragmas, result);
1101 return result;
1102 }

1062 static int
1063 count_registered_pragmas (struct pragma_entry *pe) in cpplib.c
1064 {
1065 int ct = 0;
1066 for (; pe != NULL; pe = pe->next)
1067 {
1068 if (pe->is_nspace)
1069 ct += count_registered_pragmas (pe->u.space);
1070 ct++;
1071 }
1072 return ct;
1073 }

1078 static char **
1079 save_registered_pragmas (struct pragma_entry *pe, char **sd)
1080 {
1081 for (; pe != NULL; pe = pe->next)
1082 {
1083 if (pe->is_nspace)
1084 sd = save_registered_pragmas (pe->u.space, sd);
1085 *sd++ = xmemdup (HT_STR (&pe->pragma->ident),
1086 HT_LEN (&pe->pragma->ident),
1087 HT_LEN (&pe->pragma->ident) + 1);
1088 }
1089 return sd;
1090 }

In above examples, GCC forms the space part in pe->u.space at line 1069, within which there are dependency, poison and system_header. save_registered_paragmas, co-operated with count_registered_pragmas, saves this pragmas tree into the chain constructed with objects of save_macro_data.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: