diff options
author | dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-17 09:59:12 +0000 |
---|---|---|
committer | dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-17 09:59:12 +0000 |
commit | ce70f43356e19c14deb3a89da25ebe89d6cb255a (patch) | |
tree | 372dab78d59e4e58eead8df4f751726cec9b98b4 /libcpp/internal.h | |
parent | 97bfb9ef7f7e4d8e5261385db972ebbffac11c31 (diff) | |
download | gcc-ce70f43356e19c14deb3a89da25ebe89d6cb255a.tar.gz |
Generate virtual locations for tokens
This second instalment uses the infrastructure of the previous patch
to allocate a macro map for each macro expansion and assign a virtual
location to each token resulting from the expansion.
To date when cpp_get_token comes across a token that happens to be a
macro, the macro expander kicks in, expands the macro, pushes the
resulting tokens onto a "token context" and returns a dummy padding
token. The next call to cpp_get_token goes look into the token context
for the next token [which is going to result from the previous macro
expansion] and returns it. If the token is a macro, the macro expander
kicks in and you know the story.
This patch piggy-backs on that macro expansion process, so to speak.
First it modifies the macro expander to make it create a macro map for
each macro expansion. It then allocates a virtual location for each
resulting token. Virtual locations of tokens resulting from macro
expansions are then stored on a special kind of context called an
"expanded tokens context". In other words, in an expanded tokens
context, there are tokens resulting from macro expansion and their
associated virtual locations. cpp_get_token_with_location is modified
to return the virtual location of tokens resulting from macro
expansion. Note that once all tokens from an expanded token context have
been consumed and the context and is freed, the memory used to store the
virtual locations of the tokens held in that context is freed as well.
This helps reducing the overall peak memory consumption.
The client code that was getting macro expansion point location from
cpp_get_token_with_location now gets virtual location from it. Those
virtual locations can in turn be resolved into the different
interesting physical locations thanks to the linemap API exposed by
the previous patch.
Expensive progress. Possibly. So this whole virtual location
allocation business is switched off by default. So by default no
extended token is created. No extended token context is created
either. One has to use -ftrack-macro-expansion to switch this on. This
complicates the code but I believe it can be useful as some of our
friends found out at http://llvm.org/bugs/show_bug.cgi?id=5610
The patch tries to reduce the memory consumption by freeing some token
context memory that was being reused before. I didn't notice any
compilation slow down due to this immediate freeing on my GNU/Linux
system.
As no client code tries to resolve virtual locations to anything but
what was being done before, no new test case has been added.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180082 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp/internal.h')
-rw-r--r-- | libcpp/internal.h | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/libcpp/internal.h b/libcpp/internal.h index 65bfa1db0de..6fb2606c9b8 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -1,6 +1,6 @@ /* Part of CPP library. Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, - 2008, 2009, 2010 Free Software Foundation, Inc. + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -139,6 +139,40 @@ struct tokenrun #define CUR(c) ((c)->u.trad.cur) #define RLIMIT(c) ((c)->u.trad.rlimit) +/* This describes some additional data that is added to the macro + token context of type cpp_context, when -ftrack-macro-expansion is + on. */ +typedef struct +{ + /* The node of the macro we are referring to. */ + cpp_hashnode *macro_node; + /* This buffer contains an array of virtual locations. The virtual + location at index 0 is the virtual location of the token at index + 0 in the current instance of cpp_context; similarly for all the + other virtual locations. */ + source_location *virt_locs; + /* This is a pointer to the current virtual location. This is used + to iterate over the virtual locations while we iterate over the + tokens they belong to. */ + source_location *cur_virt_loc; +} macro_context; + +/* The kind of tokens carried by a cpp_context. */ +enum context_tokens_kind { + /* This is the value of cpp_context::tokens_kind if u.iso.first + contains an instance of cpp_token **. */ + TOKENS_KIND_INDIRECT, + /* This is the value of cpp_context::tokens_kind if u.iso.first + contains an instance of cpp_token *. */ + TOKENS_KIND_DIRECT, + /* This is the value of cpp_context::tokens_kind when the token + context contains tokens resulting from macro expansion. In that + case struct cpp_context::macro points to an instance of struct + macro_context. This is used only when the + -ftrack-macro-expansion flag is on. */ + TOKENS_KIND_EXTENDED +}; + typedef struct cpp_context cpp_context; struct cpp_context { @@ -168,11 +202,24 @@ struct cpp_context When the context is popped, the buffer is released. */ _cpp_buff *buff; - /* For a macro context, the macro node, otherwise NULL. */ - cpp_hashnode *macro; + /* If tokens_kind is TOKEN_KIND_EXTENDED, then (as we thus are in a + macro context) this is a pointer to an instance of macro_context. + Otherwise if tokens_kind is *not* TOKEN_KIND_EXTENDED, then, if + we are in a macro context, this is a pointer to an instance of + cpp_hashnode, representing the name of the macro this context is + for. If we are not in a macro context, then this is just NULL. + Note that when tokens_kind is TOKEN_KIND_EXTENDED, the memory + used by the instance of macro_context pointed to by this member + is de-allocated upon de-allocation of the instance of struct + cpp_context. */ + union + { + macro_context *mc; + cpp_hashnode *macro; + } c; - /* True if utoken element is token, else ptoken. */ - bool direct_p; + /* This determines the type of tokens held by this context. */ + enum context_tokens_kind tokens_kind; }; struct lexer_state @@ -605,6 +652,7 @@ extern cpp_token *_cpp_lex_direct (cpp_reader *); extern int _cpp_equiv_tokens (const cpp_token *, const cpp_token *); extern void _cpp_init_tokenrun (tokenrun *, unsigned int); extern cpp_hashnode *_cpp_lex_identifier (cpp_reader *, const char *); +extern int _cpp_remaining_tokens_num_in_context (cpp_reader *); /* In init.c. */ extern void _cpp_maybe_push_include_file (cpp_reader *); |