libcpp: add callback for comment-handling
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 5 Jun 2017 20:53:06 +0000 (20:53 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Mon, 5 Jun 2017 20:53:06 +0000 (20:53 +0000)
gcc/testsuite/ChangeLog:
* g++.dg/plugin/comment_plugin.c: New test plugin.
* g++.dg/plugin/comments-1.C: New test file.
* g++.dg/plugin/plugin.exp (plugin_test_list): Add the above.

libcpp/ChangeLog:
* include/cpplib.h (struct cpp_callbacks): Add "comment"
callback.
* lex.c (_cpp_lex_direct): Call the comment callback if non-NULL.

From-SVN: r248901

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/plugin/comment_plugin.c [new file with mode: 0644]
gcc/testsuite/g++.dg/plugin/comments-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/plugin/plugin.exp
libcpp/ChangeLog
libcpp/include/cpplib.h
libcpp/lex.c

index aa7ee04..f1bb404 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-05  David Malcolm  <dmalcolm@redhat.com>
+
+       * g++.dg/plugin/comment_plugin.c: New test plugin.
+       * g++.dg/plugin/comments-1.C: New test file.
+       * g++.dg/plugin/plugin.exp (plugin_test_list): Add the above.
+
 2017-06-05  Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
        * gcc.misc-tests/gcov-1a.c: New test.
diff --git a/gcc/testsuite/g++.dg/plugin/comment_plugin.c b/gcc/testsuite/g++.dg/plugin/comment_plugin.c
new file mode 100644 (file)
index 0000000..c3b08e3
--- /dev/null
@@ -0,0 +1,63 @@
+/* Test of cpp_callbacks::comments.  */
+
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "cpplib.h"
+#include "diagnostic.h"
+#include "c-family/c-pragma.h"
+
+int plugin_is_GPL_compatible;
+
+/* Test callback for cpp_callbacks::comments.  */
+
+void
+my_comment_cb (cpp_reader *, source_location loc,
+              const unsigned char *content, size_t len)
+{
+  if (in_system_header_at (loc))
+    return;
+
+  /* CONTENT contains the opening slash-star (or slash-slash),
+     and for C-style comments contains the closing star-slash.  */
+  gcc_assert (len >= 2);
+  gcc_assert (content[0] == '/');
+  gcc_assert (content[1] == '*' || content[1] == '/');
+  bool c_style = (content[1] == '*');
+  if (c_style)
+    {
+      gcc_assert (content[len - 2] == '*');
+      gcc_assert (content[len - 1] == '/');
+    }
+
+  if (c_style)
+    inform (loc, "got C-style comment; length=%i", len);
+  else
+    inform (loc, "got C++-style comment; length=%i", len);
+
+  /* Print the content of the comment.
+     For a C-style comment, the buffer CONTENT contains the opening
+     slash-star and closing star-slash, so we can't directly verify
+     it in the DejaGnu test without adding another comment, which
+     would trigger this callback again.
+     Hence we skip the syntactically-significant parts of the comment
+     when printing it.  */
+  fprintf (stderr, "stripped content of comment: >");
+  /* Avoid printing trailing star-slash.  */
+  if (c_style)
+    len -= 2;
+  for (size_t i = 2; i < len; i++)
+    fputc (content[i], stderr);
+  fprintf (stderr, "<\n");
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+            struct plugin_gcc_version *version)
+{
+  cpp_callbacks *cb = cpp_get_callbacks (parse_in);
+  cb->comment = my_comment_cb;
+
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/plugin/comments-1.C b/gcc/testsuite/g++.dg/plugin/comments-1.C
new file mode 100644 (file)
index 0000000..0821b14
--- /dev/null
@@ -0,0 +1,49 @@
+/* Example of a one-line C-style comment.  */
+#if 0
+{ dg-message "1: got C-style comment; length=45" "" { target *-*-* } .-2 }
+{ dg-begin-multiline-output "" }
+stripped content of comment: > Example of a one-line C-style comment.  <
+{ dg-end-multiline-output "" }
+#endif
+
+     /*Another example of a one-line C-style comment.*/
+#if 0
+{ dg-message "6: got C-style comment; length=50" "" { target *-*-* } .-2 }
+{ dg-begin-multiline-output "" }
+stripped content of comment: >Another example of a one-line C-style comment.<
+{ dg-end-multiline-output "" }
+#endif
+
+/**/
+#if 0
+{ dg-message "1: got C-style comment; length=4" "" { target *-*-* } .-2 }
+{ dg-begin-multiline-output "" }
+stripped content of comment: ><
+{ dg-end-multiline-output "" }
+#endif
+
+/* Example of a
+   multi-line C-style comment.  */
+#if 0
+{ dg-message "1: got C-style comment; length=50" "" { target *-*-* } .-3 }
+{ dg-begin-multiline-output "" }
+stripped content of comment: > Example of a
+   multi-line C-style comment.  <
+{ dg-end-multiline-output "" }
+#endif
+
+// Example of a C++-style comment
+#if 0
+{ dg-message "1: got C\\+\\+-style comment; length=33" "" { target *-*-* } .-2 }
+{ dg-begin-multiline-output "" }
+stripped content of comment: > Example of a C++-style comment<
+{ dg-end-multiline-output "" }
+#endif
+
+//
+#if 0
+{ dg-message "1: got C\\+\\+-style comment; length=2" "" { target *-*-* } .-2 }
+{ dg-begin-multiline-output "" }
+stripped content of comment: ><
+{ dg-end-multiline-output "" }
+#endif
index 94ebe93..e40cba3 100644 (file)
@@ -68,6 +68,7 @@ set plugin_test_list [list \
     { show_template_tree_color_plugin.c \
          show-template-tree-color.C \
          show-template-tree-color-no-elide-type.C } \
+    { comment_plugin.c comments-1.C } \
 ]
 
 foreach plugin_test $plugin_test_list {
index c01ab44..8032d7c 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-05  David Malcolm  <dmalcolm@redhat.com>
+
+       * include/cpplib.h (struct cpp_callbacks): Add "comment"
+       callback.
+       * lex.c (_cpp_lex_direct): Call the comment callback if non-NULL.
+
 2017-05-02  David Malcolm  <dmalcolm@redhat.com>
 
        * include/line-map.h (class rich_location): Update description of
index b843992..66ef4d6 100644 (file)
@@ -609,6 +609,15 @@ struct cpp_callbacks
 
   /* Callback for providing suggestions for misspelled directives.  */
   const char *(*get_suggestion) (cpp_reader *, const char *, const char *const *);
+
+  /* Callback for when a comment is encountered, giving the location
+     of the opening slash, a pointer to the content (which is not
+     necessarily 0-terminated), and the length of the content.
+     The content contains the opening slash-star (or slash-slash),
+     and for C-style comments contains the closing star-slash.  For
+     C++-style comments it does not include the terminating newline.  */
+  void (*comment) (cpp_reader *, source_location, const unsigned char *,
+                  size_t);
 };
 
 #ifdef VMS
index 9edd2a6..40ff801 100644 (file)
@@ -2889,6 +2889,13 @@ _cpp_lex_direct (cpp_reader *pfile)
       if (fallthrough_comment_p (pfile, comment_start))
        fallthrough_comment = true;
 
+      if (pfile->cb.comment)
+       {
+         size_t len = pfile->buffer->cur - comment_start;
+         pfile->cb.comment (pfile, result->src_loc, comment_start - 1,
+                            len + 1);
+       }
+
       if (!pfile->state.save_comments)
        {
          result->flags |= PREV_WHITE;