Studying note of GCC-3.4.6 source (34)

来源:互联网 发布:档案数字化软件 编辑:程序博客网 时间:2024/05/21 17:31

4.1.3.1.2.1.4.              Read in macro defintions

In rest of PCH file, it contains detail of definition of macros. By this information, we can insert those defintions in cpp_reader now. In PCH file, every definition begins with macrodef_struct as following

 

38    struct macrodef_struct                                                                                in cpppch.c

39    {

40      unsigned int definition_length;

41      unsigned short name_length;

42      unsigned short flags;

43    };

 

Notice that name_length above is included by definition_length.

 

cpp_read_state (continue)

 

654      old_state = r->state;

655   

656      r->state.in_directive = 1;

657      r->state.prevent_expansion = 1;

658      r->state.angled_headers = 0;

659   

660     /* Read in the identifiers that must be defined.  */

661      for (;;)

662      {

663        cpp_hashnode *h;

664         

665        if (fread (&m, sizeof (m), 1, f) != 1)

666          goto error;

667         

668        if (m.name_length == 0)

669          break;

670   

671        if (defnlen < m.definition_length + 1)

672        {

673          defnlen = m.definition_length + 256;

674          defn = xrealloc (defn, defnlen);

675        }

676   

677        if (fread (defn, 1, m.definition_length, f) != m.definition_length)

678          goto error;

679        defn[m.definition_length] = '/n';

680         

681        h = cpp_lookup (r, defn, m.name_length);

682   

683        if (h->type == NT_MACRO)

684          _cpp_free_definition (h);

685        if (m.flags & NODE_POISONED)

686          h->flags |= NODE_POISONED | NODE_DIAGNOSTIC;

687        else if (m.name_length != m.definition_length)

688        {

689          if (cpp_push_buffer (r, defn + m.name_length,

690                           m.definition_length - m.name_length, true)

691                               != NULL)

692          {

693            _cpp_clean_line (r);

694            if (!_cpp_create_definition (r, h))

695              abort ();

696            _cpp_pop_buffer (r);

697          }

698          else

699            abort ();

700        }

701      }

702   

703      r->state = old_state;

704      r->line = saved_line;

705      free (defn);

706      defn = NULL;

707   

708      if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL)

709          != 0)

710        goto error;

711    

712      return 0;

713     

714    error:

715      cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");

716      return -1;

717    }

 

Above at line 683, if the macro has been defined already, this old definition should be covered. Function cpp_free_definition first clears this definition.

 

1227 void

1228 _cpp_free_definition (cpp_hashnode *h)                                               in cppmacro.c

1229 {

1230   /* Macros and assertions no longer have anything to free.  */

1231   h->type = NT_VOID;

1232   /* Clear builtin flag in case of redefinition.  */

1233   h->flags &= ~(NODE_BUILTIN | NODE_DISABLED);

1234 }

4.1.3.1.2.1.4.1.        Prepare buffer

At line 638, if name_length is not equal to definition_length, it means it’s followed by a body. First it needs prepare buffer for the following handling. See that buffer_ob of cpp_reader is type of obstack – it manages the memory by itself.

 

1928 cpp_buffer *

1929 cpp_push_buffer (cpp_reader *pfile, const uchar *buffer, size_t len,             in cpplib.c

1930       int from_stage3)

1931   {

1932     cpp_buffer *new = xobnew (&pfile->buffer_ob, cpp_buffer);

1933  

1934     /* Clears, amongst other things, if_stack and mi_cmacro.  */

1935     memset (new, 0, sizeof (cpp_buffer));

1936  

1937     new->next_line = new->buf = buffer;

1938     new->rlimit = buffer + len;

1939     new->from_stage3 = from_stage3;

1940     new->prev = pfile->buffer;

1941     new->need_line = true;

1942  

1943     pfile->buffer = new;

1944     return new;

1945   }

 

The buffer is defined by cpp_buffer as below. Notice that one definition will be associated with one cpp_buffer as we see here.

 

268  struct cpp_buffer                                                                                in cpphash.h

269  {

270    const uchar *cur;              /* Current location.  */

271    const uchar *line_base;     /* Start of current physical line.  */

272    const uchar *next_line;     /* Start of to-be-cleaned logical line.  */

273 

274    const uchar *buf;              /* Entire character buffer.  */

275    const uchar *rlimit;          /* Writable byte at end of file.  */

276 

277    _cpp_line_note *notes;      /* Array of notes.  */

278    unsigned int cur_note;       /* Next note to process.  */

279    unsigned int notes_used;    /* Number of notes.  */

280    unsigned int notes_cap;     /* Size of allocated array.  */

281 

282    struct cpp_buffer *prev;

283 

284    /* Pointer into the file table; non-NULL if this is a file buffer.

285      Used for include_next and to record control macros.  */

286    struct _cpp_file *file;

287 

288    /* Value of if_stack at start of this file.

289      Used to prohibit unmatched #endif (etc) in an include file.  */

290    struct if_stack *if_stack;

291 

292   /* True if we need to get the next clean line.  */

293    bool need_line;

294 

295    /* True if we have already warned about C++ comments in this file.

296      The warning happens only for C89 extended mode with -pedantic on,

297      or for -Wtraditional, and only once per file (otherwise it would

298      be far too noisy).  */

299    unsigned char warned_cplusplus_comments;

300 

301    /* True if we don't process trigraphs and escaped newlines. True

302      for preprocessed input, command line directives, and _Pragma

303      buffers.  */

304    unsigned char from_stage3;

305 

306    /* At EOF, a buffer is automatically popped. If RETURN_AT_EOF is

307      true, a CPP_EOF token is then returned. Otherwise, the next

308      token from the enclosing buffer is returned.  */

309    unsigned int return_at_eof : 1;

310 

311     /* The directory of the this buffer's file. Its NAME member is not

312      allocated, so we don't need to worry about freeing it.  */

313    struct cpp_dir dir;

314 

315    /* Used for buffer overlays by cpptrad.c.  */

316    const uchar *saved_cur, *saved_rlimit;

317  };

4.1.3.1.2.1.4.2.        Fetch line number of definition

Notice that in cpp_push_buffer, we claim that the buffer is used not for processing trigraphs and escaped newlines. So in _cpp_clean_line, it just goes ahead from the beginning of definition (deinifiton_lengthname_length) till arriving line endings.

 

103    void

104    _cpp_clean_line (cpp_reader *pfile)                                                          in cpplex.c

105    {

106      cpp_buffer *buffer;

107      const uchar *s;

108      uchar c, *d, *p;

109   

110       buffer = pfile->buffer;

111       buffer->cur_note = buffer->notes_used = 0;

112       buffer->cur = buffer->line_base = buffer->next_line;

113       buffer->need_line = false;

114       s = buffer->next_line - 1;

115    

116       if (!buffer->from_stage3)

117       {

         

204      }

205      else

206      {

207        do

208          s++;

209        while (*s != '/n' && *s != '/r');

210        d = (uchar *) s;

211    

212        /* Handle DOS line endings.  */

213        if (*s == '/r' && s != buffer->rlimit && s[1] == '/n')

214          s++;

215      }

216   

217    done:

218      *d = '/n';

219      /* A sentinel note that should never be processed.  */

220      add_line_note (buffer, d + 1, '/n');

221      buffer->next_line = s + 1;

222    }

 

When we return from this function, cur and next_line point out the literal string of definition. The line endding is also remarked by _cpp_line_note.

 

85      static void

86      add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type)              in cpplex.c

87      {

88        if (buffer->notes_used == buffer->notes_cap)

89        {

90          buffer->notes_cap = buffer->notes_cap * 2 + 200;

91          buffer->notes = xrealloc (buffer->notes,

92                                buffer->notes_cap * sizeof (_cpp_line_note));

93        }

94     

95        buffer->notes[buffer->notes_used].pos = pos;

96        buffer->notes[buffer->notes_used].type = type;

97        buffer->notes_used++;

98      }

 

256    struct _cpp_line_note                                                                               in cpphash.h

257    {

258      /* Location in the clean line the note refers to.  */

259      const uchar *pos;

260   

261      /* Type of note. The 9 'from' trigraph characters represent those

262        trigraphs, '//' an escaped newline, ' ' an escaped newline with

263        intervening space, and anything else is invalid.  */

264      unsigned int type;

265    };

 

Struct cpp_macro is the place to create macro definition. It has definition as following.

 

88      struct cpp_macro                                                                                     in cpphash.h

89      {

90        /* Parameters, if any.  */

91        cpp_hashnode **params;

92     

93        /* Replacement tokens (ISO) or replacement text (traditional). See

94          comment at top of cpptrad.c for how traditional function-like

95          macros are encoded.  */

96        union

97        {

98          cpp_token *tokens;

99          const uchar *text;

100      } exp;

101   

102     /* Definition line number.  */

103      fileline line;

104   

105      /* Number of tokens in expansion, or bytes for traditional macros.  */

106      unsigned int count;

107   

108      /* Number of parameters.  */

109      unsigned short paramc;

110    

111      /* If a function-like macro.  */

112       unsigned int fun_like : 1;

113    

114       /* If a variadic macro.  */

115       unsigned int variadic : 1;

116    

117       /* If macro defined in system header.  */

118       unsigned int syshdr   : 1;

119    

120     /* Nonzero if it has been expanded or had its existence tested.  */

121      unsigned int used     : 1;

122    };

4.1.3.1.2.1.4.3.        Traditional mode

Before going ahead into macro definition creation, first see the difference between traditional mode and standard mode. [6]

Traditional (pre-stadnard) C preprocessing is rather different from the preprocessing specified by the standard. When GCC is given the ‘-traditional’ option, it attempts to emulate a traditional preprocessor. We do not guarantee that GCC’s behavior under ‘-traditional’ macthes any pre-standard preprocessor exactly.

Traditional mode exists only for backward compatibility. We have not plans to augment it in any way nor will we change it except to fix catastrophic bugs. You should be aware that modern C libraries often have header files which are incompatible with traditional mode.

This is a list of the differences. It may not be complete, and may not correspond exactly to the behavior of either GCC or a true traditional preprocessor.

Ÿ        Traditional macro expansion pays no attention to single-quote or double-quote characters; macro argument symbols are replaced by the argument values even when they appear within apparent string or character constants.

Ÿ        Traditionally, it is permissible for a macro expansion to end in the middle of a string or character constant. The constant continues into the text surrounding the macro call.

Ÿ        However, the end of the line terminates a string or character constant, with no error. (This is a kluge. Traditional mode is commonly used to preprocess things which are not C, and have different comment syntax. Single apostrophes often appear in comments.)

Ÿ        Preprocessing directives are recognized in traditional C only when their leading ‘#’ appears in the first column. There can be no whitespace between the beginning of the line and the ‘#’.

Ÿ        In traditional C, a comment is equivalent to no text at all. (In ISO C, a comment counts as whitespace.) It can be used sort of the same way that ‘##’ is used in ISO C, to paste macro arguments together.

Ÿ        Traditional C does not have the concept of a preprocessing number.

Ÿ        A macro is not suppressed within its own definition, in traditional C. Thus, any macor that is used recursively inevitably causes an error.

Ÿ        The ‘#’ and ‘##’ operators are not available in traditional C.

Ÿ        In traditional C, the text at the end of a macro expansion can run tegother with the text after the macro call, to produce a single token, this is impossible in ISO C.

Ÿ        None of the GNU extensions to the preprocessor are available in traditional mode, with the exception of a partial implementation of assertions, and those may be removed in the future.

Ÿ        A true traditional C preprocessor does not recognize ‘#elif’, ‘#error’, or ‘#pragma’. GCC supports ‘#elif’ and ‘#error’ even in traditional mode, but not ‘#pragma’.

Ÿ        Traditional mode is text-based, not token-based, and comments are stripped after macro expansion. Therefore, ‘/**/’ can be used to paste tokens together provided that there is no whitespace between it and the tokens to be pasted.

Ÿ        Traditional mode preserves the amount and form of whitespace provided by the user. Hard tabs remain hard tabs. This can be useful, e.g. if you are preprocessing a Makefile (which we do not encourage).

You can request warnings about features that did not exist, or worked differently, in traditional C with the ‘-Wtraditional’ option. This works only if you do not specify ‘-traditional’. GCC does not warn about features of ISO C which you must use when you are using a conforming compiler, such as the ‘#’ and ‘##’ operators.

Presently ‘-Wtraditional’ warns about:

Ÿ        Macro parameters that appear within string literals in the macro body. In traditional C macro replacement takes place within string literals, but does not in ISO C.

Ÿ        In traditional C, some preprocessor directives did not exist. Traditional preprocessors would only consider a line to be a directive if the ‘#’ appeared in column 1 on the line. Therefore ‘-Wtraditional’ warns about directives that traditional C understands but would ignore because the ‘#’ does not appear as the first character on the line. It also suggests you hide directives like ‘#pragma’ not understood by traditional C by indenting them. Some traditional implementations would not recognise ‘#elif’, so it suggests avoiding it altogether.

Ÿ        A function-like macro that appears without an argument list. In traditional C this was an error. In ISO C it merely means that the macro is not expanded.

Ÿ        The unary plus operator. This did not exist in traditional C.

Ÿ        The ‘U’ and ‘LL’ integer constant suffixes, which were not available in traditional C. (Traditional C does support the ‘L’ suffix for simple long integer constants.) You are not warned about uses of these suffixes in macros defined in system header. For instance, UINT_MAX may well be defined as 4294967295U, but you will not be warned of you use UINT_MAX.

You can usually avoid the warning, and the related warning about constants which are so large that they are unsigned, by writing the integer constant in question in hexadecimal, with no U suffix. Take care, though, because this gives the wrong result in exotic cases.

 

原创粉丝点击