aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2008-04-02 20:42:53 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2008-04-02 20:42:53 +0100
commit93d45d9eda934cf8d9ab3e4e4c81fce9ed994a07 (patch)
treef70286f28df6c1a7f1cb8695448540d74ba1f396 /libcpp
parente6b69d0e5667a210ed70b677de4778f6f50396a4 (diff)
downloadgcc-93d45d9eda934cf8d9ab3e4e4c81fce9ed994a07.zip
gcc-93d45d9eda934cf8d9ab3e4e4c81fce9ed994a07.tar.gz
gcc-93d45d9eda934cf8d9ab3e4e4c81fce9ed994a07.tar.bz2
cppopts.texi (-dU): Document.
gcc: * doc/cppopts.texi (-dU): Document. * c-common.h (flag_dump_macros): Update comment. * c-opts.c (handle_OPT_d): Handle -dU. * c-ppoutput.c (macro_queue, define_queue, undef_queue, dump_queued_macros, cb_used_define, cb_used_undef): New. (init_pp_output): Handle -dU. (cb_line_change): Call dump_queued_macros. * toplev.c (decode_d_option): Accept -dU as preprocessor option. gcc/testsuite: * gcc.dg/cpp/cmdlne-dU-1.c, gcc.dg/cpp/cmdlne-dU-2.c, gcc.dg/cpp/cmdlne-dU-3.c, gcc.dg/cpp/cmdlne-dU-4.c, gcc.dg/cpp/cmdlne-dU-5.c, gcc.dg/cpp/cmdlne-dU-6.c, gcc.dg/cpp/cmdlne-dU-7.c, gcc.dg/cpp/cmdlne-dU-8.c, gcc.dg/cpp/cmdlne-dU-9.c, gcc.dg/cpp/cmdlne-dU-10.c, gcc.dg/cpp/cmdlne-dU-11.c, gcc.dg/cpp/cmdlne-dU-12.c, gcc.dg/cpp/cmdlne-dU-13.c, gcc.dg/cpp/cmdlne-dU-14.c, gcc.dg/cpp/cmdlne-dU-15.c, gcc.dg/cpp/cmdlne-dU-16.c, gcc.dg/cpp/cmdlne-dU-17.c, gcc.dg/cpp/cmdlne-dU-18.c, gcc.dg/cpp/cmdlne-dU-19.c, gcc.dg/cpp/cmdlne-dU-20.c, gcc.dg/cpp/cmdlne-dU-21.c, gcc.dg/cpp/cmdlne-dU-22.c: New tests. libcpp: * include/cpplib.h (struct cpp_callbacks): Add used_define, used_undef and before_define. (NODE_USED): Define. * directives.c (do_define, do_undef, undefine_macros, do_ifdef, do_ifndef, cpp_pop_definition): Handle new flag and use new callbacks. * expr.c (parse_defined): Handle new flag and use new callbacks. * macro.c (enter_macro_context, _cpp_free_definition): Handle new flag and use new callbacks. From-SVN: r133847
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog12
-rw-r--r--libcpp/directives.c45
-rw-r--r--libcpp/expr.c14
-rw-r--r--libcpp/include/cpplib.h9
-rw-r--r--libcpp/macro.c16
5 files changed, 92 insertions, 4 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index e8719d9..f5c623d 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,15 @@
+2008-04-02 Joseph Myers <joseph@codesourcery.com>
+
+ * include/cpplib.h (struct cpp_callbacks): Add used_define,
+ used_undef and before_define.
+ (NODE_USED): Define.
+ * directives.c (do_define, do_undef, undefine_macros, do_ifdef,
+ do_ifndef, cpp_pop_definition): Handle new flag and use new
+ callbacks.
+ * expr.c (parse_defined): Handle new flag and use new callbacks.
+ * macro.c (enter_macro_context, _cpp_free_definition): Handle new
+ flag and use new callbacks.
+
2008-04-01 Jakub Jelinek <jakub@redhat.com>
PR pch/13675
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 249a232..0ca1117 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -559,9 +559,14 @@ do_define (cpp_reader *pfile)
pfile->state.save_comments =
! CPP_OPTION (pfile, discard_comments_in_macro_exp);
+ if (pfile->cb.before_define)
+ pfile->cb.before_define (pfile);
+
if (_cpp_create_definition (pfile, node))
if (pfile->cb.define)
pfile->cb.define (pfile, pfile->directive_line, node);
+
+ node->flags &= ~NODE_USED;
}
}
@@ -573,6 +578,9 @@ do_undef (cpp_reader *pfile)
if (node)
{
+ if (pfile->cb.before_define)
+ pfile->cb.before_define (pfile);
+
if (pfile->cb.undef)
pfile->cb.undef (pfile, pfile->directive_line, node);
@@ -603,7 +611,7 @@ undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h,
/* Body of _cpp_free_definition inlined here for speed.
Macros and assertions no longer have anything to free. */
h->type = NT_VOID;
- h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED);
+ h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
return 1;
}
@@ -1638,12 +1646,26 @@ do_ifdef (cpp_reader *pfile)
if (! pfile->state.skipping)
{
- const cpp_hashnode *node = lex_macro_node (pfile, false);
+ cpp_hashnode *node = lex_macro_node (pfile, false);
if (node)
{
skip = node->type != NT_MACRO;
_cpp_mark_macro_used (node);
+ if (!(node->flags & NODE_USED))
+ {
+ node->flags |= NODE_USED;
+ if (node->type == NT_MACRO)
+ {
+ if (pfile->cb.used_define)
+ pfile->cb.used_define (pfile, pfile->directive_line, node);
+ }
+ else
+ {
+ if (pfile->cb.used_undef)
+ pfile->cb.used_undef (pfile, pfile->directive_line, node);
+ }
+ }
check_eol (pfile);
}
}
@@ -1656,7 +1678,7 @@ static void
do_ifndef (cpp_reader *pfile)
{
int skip = 1;
- const cpp_hashnode *node = 0;
+ cpp_hashnode *node = 0;
if (! pfile->state.skipping)
{
@@ -1666,6 +1688,20 @@ do_ifndef (cpp_reader *pfile)
{
skip = node->type == NT_MACRO;
_cpp_mark_macro_used (node);
+ if (!(node->flags & NODE_USED))
+ {
+ node->flags |= NODE_USED;
+ if (node->type == NT_MACRO)
+ {
+ if (pfile->cb.used_define)
+ pfile->cb.used_define (pfile, pfile->directive_line, node);
+ }
+ else
+ {
+ if (pfile->cb.used_undef)
+ pfile->cb.used_undef (pfile, pfile->directive_line, node);
+ }
+ }
check_eol (pfile);
}
}
@@ -2145,6 +2181,9 @@ cpp_pop_definition (cpp_reader *pfile, const char *str, cpp_macro *dfn)
if (node == NULL)
return;
+ if (pfile->cb.before_define)
+ pfile->cb.before_define (pfile);
+
if (node->type == NT_MACRO)
{
if (pfile->cb.undef)
diff --git a/libcpp/expr.c b/libcpp/expr.c
index 9df7533..9e89dd9 100644
--- a/libcpp/expr.c
+++ b/libcpp/expr.c
@@ -637,6 +637,20 @@ parse_defined (cpp_reader *pfile)
"this use of \"defined\" may not be portable");
_cpp_mark_macro_used (node);
+ if (!(node->flags & NODE_USED))
+ {
+ node->flags |= NODE_USED;
+ if (node->type == NT_MACRO)
+ {
+ if (pfile->cb.used_define)
+ pfile->cb.used_define (pfile, pfile->directive_line, node);
+ }
+ else
+ {
+ if (pfile->cb.used_undef)
+ pfile->cb.used_undef (pfile, pfile->directive_line, node);
+ }
+ }
/* A possible controlling macro of the form #if !defined ().
_cpp_parse_expr checks there was no other junk on the line. */
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index e205be7..84de0e0 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -480,6 +480,14 @@ struct cpp_callbacks
This callback receives the translated message. */
void (*error) (cpp_reader *, int, const char *, va_list *)
ATTRIBUTE_FPTR_PRINTF(3,0);
+
+ /* Callbacks for when a macro is expanded, or tested (whether
+ defined or not at the time) in #ifdef, #ifndef or "defined". */
+ void (*used_define) (cpp_reader *, unsigned int, cpp_hashnode *);
+ void (*used_undef) (cpp_reader *, unsigned int, cpp_hashnode *);
+ /* Called before #define and #undef or other macro definition
+ changes are processed. */
+ void (*before_define) (cpp_reader *);
};
/* Chain of directories to look for include files in. */
@@ -537,6 +545,7 @@ extern const char *progname;
#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */
#define NODE_DISABLED (1 << 5) /* A disabled macro. */
#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */
+#define NODE_USED (1 << 7) /* Dumped with -dU. */
/* Different flavors of hash node. */
enum node_type
diff --git a/libcpp/macro.c b/libcpp/macro.c
index fd624b1..587b948 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -815,6 +815,13 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
pfile->state.angled_headers = false;
+ if ((node->flags & NODE_BUILTIN) && !(node->flags & NODE_USED))
+ {
+ node->flags |= NODE_USED;
+ if (pfile->cb.used_define)
+ pfile->cb.used_define (pfile, pfile->directive_line, node);
+ }
+
/* Handle standard macros. */
if (! (node->flags & NODE_BUILTIN))
{
@@ -854,6 +861,13 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
/* Disable the macro within its expansion. */
node->flags |= NODE_DISABLED;
+ if (!(node->flags & NODE_USED))
+ {
+ node->flags |= NODE_USED;
+ if (pfile->cb.used_define)
+ pfile->cb.used_define (pfile, pfile->directive_line, node);
+ }
+
macro->used = 1;
if (macro->paramc == 0)
@@ -1393,7 +1407,7 @@ _cpp_free_definition (cpp_hashnode *h)
/* Macros and assertions no longer have anything to free. */
h->type = NT_VOID;
/* Clear builtin flag in case of redefinition. */
- h->flags &= ~(NODE_BUILTIN | NODE_DISABLED);
+ h->flags &= ~(NODE_BUILTIN | NODE_DISABLED | NODE_USED);
}
/* Save parameter NODE to the parameter list of macro MACRO. Returns