public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 2/2] gcc symbol database
@ 2012-05-28  8:41 Yunfeng ZHANG
       [not found] ` <CA+dUcj0wRSjkThO84zPRBkg9784F-3kNsrOpMQnJoAExfYx5fw@mail.gmail.com>
  0 siblings, 1 reply; 3+ messages in thread
From: Yunfeng ZHANG @ 2012-05-28  8:41 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dodji Seketeli, Joseph S. Myers, Dave Korn, Tom Tromey

diff -upr .pc/symdb_enhance_plugin/gcc/c-family/c-common.h
gcc/c-family/c-common.h
--- .pc/symdb_enhance_plugin/gcc/c-family/c-common.h    2011-12-21
04:44:13.000000000 +0800
+++ gcc/c-family/c-common.h    2012-05-25 14:56:56.776263281 +0800
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.
 #include "splay-tree.h"
 #include "cpplib.h"
 #include "ggc.h"
+#include "c-pragma.h"

 /* In order for the format checking to accept the C frontend
    diagnostic framework extensions, you must include this file before
@@ -1116,4 +1117,43 @@ struct GTY(()) tree_userdef_literal {

 extern tree build_userdef_literal (tree suffix_id, tree value, tree
num_string);

+/* The following local token type is used.  */
+
+/* A keyword.  */
+#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
+
+/* More information about the type of a CPP_NAME token.  */
+typedef enum c_id_kind {
+  /* An ordinary identifier.  */
+  C_ID_ID,
+  /* An identifier declared as a typedef name.  */
+  C_ID_TYPENAME,
+  /* An identifier declared as an Objective-C class name.  */
+  C_ID_CLASSNAME,
+  /* An address space identifier.  */
+  C_ID_ADDRSPACE,
+  /* Not an identifier.  */
+  C_ID_NONE
+} c_id_kind;
+
+/* A single C token after string literal concatenation and conversion
+   of preprocessing tokens to tokens.  */
+typedef struct GTY (()) c_token {
+  /* The kind of token.  */
+  ENUM_BITFIELD (cpp_ttype) type : 8;
+  /* If this token is a CPP_NAME, this value indicates whether also
+     declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
+  ENUM_BITFIELD (c_id_kind) id_kind : 8;
+  /* If this token is a keyword, this value indicates which keyword.
+     Otherwise, this value is RID_MAX.  */
+  ENUM_BITFIELD (rid) keyword : 8;
+  /* If this token is a CPP_PRAGMA, this indicates the pragma that
+     was seen.  Otherwise it is PRAGMA_NONE.  */
+  ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
+  /* The value associated with this token, if any.  */
+  tree value;
+  /* The location at which this token was found.  */
+  location_t location;
+} c_token;
+
 #endif /* ! GCC_C_COMMON_H */
diff -upr .pc/symdb_enhance_plugin/gcc/c-family/c-lex.c gcc/c-family/c-lex.c
--- .pc/symdb_enhance_plugin/gcc/c-family/c-lex.c    2011-10-27
03:31:16.000000000 +0800
+++ gcc/c-family/c-lex.c    2012-05-25 14:56:56.767134882 +0800
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.
 #include "splay-tree.h"
 #include "debug.h"
 #include "target.h"
+#include "plugin.h"

 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
@@ -380,6 +381,7 @@ c_lex_with_flags (tree *value, location_
         case CPP_STRING32:
         case CPP_UTF8STRING:
           type = lex_string (tok, value, true, true);
+          tok = NULL;
           break;

         case CPP_NAME:
@@ -481,6 +483,7 @@ c_lex_with_flags (tree *value, location_
     {
       type = lex_string (tok, value, false,
                  (lex_flags & C_LEX_STRING_NO_TRANSLATE) == 0);
+      tok = NULL;
       break;
     }
       *value = build_string (tok->val.str.len, (const char *)
tok->val.str.text);
@@ -515,6 +518,7 @@ c_lex_with_flags (tree *value, location_
     }

   timevar_pop (TV_CPP);
+  invoke_plugin_callbacks (PLUGIN_CPP_TOKEN, (cpp_token*) tok);

   return type;
 }
diff -upr .pc/symdb_enhance_plugin/gcc/c-parser.c gcc/c-parser.c
--- .pc/symdb_enhance_plugin/gcc/c-parser.c    2011-12-21
04:44:13.000000000 +0800
+++ gcc/c-parser.c    2012-05-25 14:56:56.772261126 +0800
@@ -121,45 +121,6 @@ c_parse_init (void)
    C++).  It would then be possible to share more of the C and C++
    lexer code, if desired.  */

-/* The following local token type is used.  */
-
-/* A keyword.  */
-#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
-
-/* More information about the type of a CPP_NAME token.  */
-typedef enum c_id_kind {
-  /* An ordinary identifier.  */
-  C_ID_ID,
-  /* An identifier declared as a typedef name.  */
-  C_ID_TYPENAME,
-  /* An identifier declared as an Objective-C class name.  */
-  C_ID_CLASSNAME,
-  /* An address space identifier.  */
-  C_ID_ADDRSPACE,
-  /* Not an identifier.  */
-  C_ID_NONE
-} c_id_kind;
-
-/* A single C token after string literal concatenation and conversion
-   of preprocessing tokens to tokens.  */
-typedef struct GTY (()) c_token {
-  /* The kind of token.  */
-  ENUM_BITFIELD (cpp_ttype) type : 8;
-  /* If this token is a CPP_NAME, this value indicates whether also
-     declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
-  ENUM_BITFIELD (c_id_kind) id_kind : 8;
-  /* If this token is a keyword, this value indicates which keyword.
-     Otherwise, this value is RID_MAX.  */
-  ENUM_BITFIELD (rid) keyword : 8;
-  /* If this token is a CPP_PRAGMA, this indicates the pragma that
-     was seen.  Otherwise it is PRAGMA_NONE.  */
-  ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
-  /* The location at which this token was found.  */
-  location_t location;
-  /* The value associated with this token, if any.  */
-  tree value;
-} c_token;
-
 /* A parser structure recording information about the state and
    context of parsing.  Includes lexer information with up to two
    tokens of look-ahead; more are not needed for C.  */
@@ -388,6 +349,7 @@ c_lex_one_token (c_parser *parser, c_tok
       break;
     }
   timevar_pop (TV_LEX);
+  invoke_plugin_callbacks (PLUGIN_C_TOKEN, token);
 }

 /* Return a pointer to the next token from PARSER, reading it in if
@@ -1360,6 +1322,7 @@ c_parser_external_declaration (c_parser
      an @interface or @protocol with prefix attributes).  We can
      only tell which after parsing the declaration specifiers, if
      any, and the first declarator.  */
+      invoke_plugin_callbacks (PLUGIN_EXTERN_DECL, NULL);
       c_parser_declaration_or_fndef (parser, true, true, true, false,
true, NULL);
       break;
     }
@@ -1488,6 +1451,11 @@ c_parser_declaration_or_fndef (c_parser
       return;
     }
   finish_declspecs (specs);
+  {
+    void* pair[2]; pair[0] = specs; pair[1] = (void*) parser->tokens_avail;
+    if (!nested)
+      invoke_plugin_callbacks (PLUGIN_EXTERN_DECLSPECS, pair);
+  }
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     {
       if (empty_ok)
@@ -1622,6 +1590,11 @@ c_parser_declaration_or_fndef (c_parser
     {
       tree asm_name = NULL_TREE;
       tree postfix_attrs = NULL_TREE;
+      {
+        void* pair[2]; pair[0] = specs; pair[1] = declarator;
+        if (!nested)
+          invoke_plugin_callbacks (PLUGIN_EXTERN_VAR, pair);
+      }
       if (!diagnosed_no_specs && !specs->declspecs_seen_p)
         {
           diagnosed_no_specs = true;
@@ -1748,11 +1721,15 @@ c_parser_declaration_or_fndef (c_parser
      declarator with a nonempty identifier list in a definition;
      and postfix attributes have never been accepted here in
      function definitions either.  */
+      if (!nested)
+        invoke_plugin_callbacks (PLUGIN_EXTERN_FUNC_OLD_PARAM, NULL);
       while (c_parser_next_token_is_not (parser, CPP_EOF)
          && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
     c_parser_declaration_or_fndef (parser, false, false, false,
                        true, false, NULL);
       store_parm_decls ();
+      if (!nested)
+        invoke_plugin_callbacks (PLUGIN_EXTERN_FUNC, declarator);
       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
     = c_parser_peek_token (parser)->location;
       fnbody = c_parser_compound_statement (parser);
@@ -2266,6 +2243,7 @@ c_parser_enum_specifier (c_parser *parse
         }
       token = c_parser_peek_token (parser);
       enum_id = token->value;
+      invoke_plugin_callbacks (PLUGIN_ENUM_SPECIFIER, enum_id);
       /* Set the location in case we create a decl now.  */
       c_parser_set_source_position_from_token (token);
       decl_loc = value_loc = token->location;
@@ -6865,6 +6843,7 @@ c_parser_postfix_expression_after_primar
       break;
     case CPP_OPEN_PAREN:
       /* Function call.  */
+      invoke_plugin_callbacks (PLUGIN_CALL_FUNCTION, expr.value);
       c_parser_consume_token (parser);
       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
         exprlist = NULL;
diff -upr .pc/symdb_enhance_plugin/gcc/doc/plugins.texi gcc/doc/plugins.texi
--- .pc/symdb_enhance_plugin/gcc/doc/plugins.texi    2011-08-11
23:57:38.000000000 +0800
+++ gcc/doc/plugins.texi    2012-05-25 14:56:56.775216761 +0800
@@ -184,6 +184,23 @@ enum plugin_event
   PLUGIN_EARLY_GIMPLE_PASSES_END,
   /* Called when a pass is first instantiated.  */
   PLUGIN_NEW_PASS,
+  PLUGIN_CPP_TOKEN,                /* Called when GCC gets a cpp token. */
+  PLUGIN_C_TOKEN,                  /* Called when GCC gets a c token. */
+  /* An extern declaration (file-scope) is encounted. */
+  PLUGIN_EXTERN_DECL,
+  /* Cooperate PLUGIN_EXTERN_FUNC to parse a function with old-style parameter
+   * declaration. */
+  PLUGIN_EXTERN_FUNC_OLD_PARAM,
+  /* An extern function definition is parsed. */
+  PLUGIN_EXTERN_FUNC,
+  /* An extern variable definition is parsed. */
+  PLUGIN_EXTERN_VAR,
+  /* An extern declaration specifier definition is parsed. */
+  PLUGIN_EXTERN_DECLSPECS,
+  /* A function is called. */
+  PLUGIN_CALL_FUNCTION,
+  /* An enum specifier is parsed. */
+  PLUGIN_ENUM_SPECIFIER,

   PLUGIN_EVENT_FIRST_DYNAMIC    /* Dummy event used for indexing callback
                                    array.  */
diff -upr .pc/symdb_enhance_plugin/gcc/plugin.c gcc/plugin.c
--- .pc/symdb_enhance_plugin/gcc/plugin.c    2011-10-19 21:20:22.000000000 +0800
+++ gcc/plugin.c    2012-05-25 14:56:56.774266369 +0800
@@ -439,6 +439,15 @@ register_callback (const char *plugin_na
       case PLUGIN_EARLY_GIMPLE_PASSES_START:
       case PLUGIN_EARLY_GIMPLE_PASSES_END:
       case PLUGIN_NEW_PASS:
+      case PLUGIN_CPP_TOKEN:
+      case PLUGIN_C_TOKEN:
+      case PLUGIN_EXTERN_DECL:
+      case PLUGIN_EXTERN_FUNC_OLD_PARAM:
+      case PLUGIN_EXTERN_FUNC:
+      case PLUGIN_EXTERN_VAR:
+      case PLUGIN_EXTERN_DECLSPECS:
+      case PLUGIN_CALL_FUNCTION:
+      case PLUGIN_ENUM_SPECIFIER:
         {
           struct callback_info *new_callback;
           if (!callback)
@@ -516,6 +525,15 @@ invoke_plugin_callbacks_full (int event,
       case PLUGIN_EARLY_GIMPLE_PASSES_START:
       case PLUGIN_EARLY_GIMPLE_PASSES_END:
       case PLUGIN_NEW_PASS:
+      case PLUGIN_CPP_TOKEN:
+      case PLUGIN_C_TOKEN:
+      case PLUGIN_EXTERN_DECL:
+      case PLUGIN_EXTERN_FUNC_OLD_PARAM:
+      case PLUGIN_EXTERN_FUNC:
+      case PLUGIN_EXTERN_VAR:
+      case PLUGIN_EXTERN_DECLSPECS:
+      case PLUGIN_CALL_FUNCTION:
+      case PLUGIN_ENUM_SPECIFIER:
         {
           /* Iterate over every callback registered with this event and
              call it.  */
diff -upr .pc/symdb_enhance_plugin/gcc/plugin.def gcc/plugin.def
--- .pc/symdb_enhance_plugin/gcc/plugin.def    2011-08-11
23:57:38.000000000 +0800
+++ gcc/plugin.def    2012-05-25 14:56:56.766145511 +0800
@@ -92,6 +92,34 @@ DEFEVENT (PLUGIN_EARLY_GIMPLE_PASSES_END
 /* Called when a pass is first instantiated.  */
 DEFEVENT (PLUGIN_NEW_PASS)

+/* Called when a cpp token is extracted.  */
+DEFEVENT (PLUGIN_CPP_TOKEN)
+
+/* Called when a c token is extracted.  */
+DEFEVENT (PLUGIN_C_TOKEN)
+
+/* An extern declaration (file-scope) is encounted. */
+DEFEVENT (PLUGIN_EXTERN_DECL)
+
+/* Cooperate PLUGIN_EXTERN_FUNC to parse a function with old-style parameter
+ * declaration. */
+DEFEVENT (PLUGIN_EXTERN_FUNC_OLD_PARAM)
+
+/* Called when an extern function definition is parsed. */
+DEFEVENT (PLUGIN_EXTERN_FUNC)
+
+/* Called when an extern variable definition is parsed. */
+DEFEVENT (PLUGIN_EXTERN_VAR)
+
+/* An extern declaration specifier definition is parsed. */
+DEFEVENT (PLUGIN_EXTERN_DECLSPECS)
+
+/* A function is called. */
+DEFEVENT (PLUGIN_CALL_FUNCTION)
+
+/* Called when an enum specifier is parsed. */
+DEFEVENT (PLUGIN_ENUM_SPECIFIER)
+
 /* After the hard-coded events above, plugins can dynamically allocate events
    at run time.
    PLUGIN_EVENT_FIRST_DYNAMIC only appears as last enum element.  */

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] gcc symbol database
       [not found] ` <CA+dUcj0wRSjkThO84zPRBkg9784F-3kNsrOpMQnJoAExfYx5fw@mail.gmail.com>
@ 2012-05-31  1:53   ` Yunfeng ZHANG
  2012-05-31  2:02     ` Yunfeng ZHANG
  0 siblings, 1 reply; 3+ messages in thread
From: Yunfeng ZHANG @ 2012-05-31  1:53 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dodji Seketeli, Joseph S. Myers, Dave Korn, Tom Tromey

[-- Attachment #1: Type: text/plain, Size: 48 bytes --]

Resend ChangeLog and two patches by attachment.

[-- Attachment #2: ChangeLog --]
[-- Type: application/octet-stream, Size: 1928 bytes --]

ChangeLog
-------------------------
libcpp/
2012-05-24  Yunfeng ZHANG <zyf.zeroos@gmail.com>

      * include/cpplib.h (struct cpp_callbacks): Add new callbacks.
      macro_start_expand, macro_end_arg, macro_end_expand, start_directive,
      end_directive, directive_token.
      (cpp_token): Add file_offset field for every token.
      * internal.h (struct _cpp_line_note): Add adjust_offset field to adjust
      new cpp_token::file_offset.
      * directives.c (_cpp_handle_directive): Implement end_directive.
      * macro.c (enter_macro_context): Implement macro_end_arg.
      (cpp_get_token_1): Implement macro_start_expand and macro_end_expand.
      * lex.c (add_line_note): Add offset argument for file offset adjustment.
      (_cpp_clean_line): Using new add_line_note declaration.

gcc/
2012-05-24  Yunfeng ZHANG <zyf.zeroos@gmail.com>

     * plugin.def: New plugin events, one for broadcast new token is arrived,
     another is for new definition notification.
     * c-parser.c: Move c_id_kind/c_token definitions to c-family/c-common.h.
     (c_lex_one_token): Invoke PLUGIN_C_TOKEN callback.
     (c_parser_external_declaration): Invoke PLUGIN_EXTERN_DECL callback.
     (c_parser_declaration_or_fndef): Invoke PLUGIN_EXTERN_DECLSPECS,
     PLUGIN_EXTERN_VAR, PLUGIN_EXTERN_FUNC_OLD_PARAM, PLUGIN_EXTERN_FUNC
     callbacks.
     (c_parser_enum_specifier): Invoke PLUGIN_ENUM_SPECIFIER callback.
     (c_parser_postfix_expression_after_primary): Invoke PLUGIN_CALL_FUNCTION
     callback.
     * plugin.c (register_callback): Handle new plugin events.
     (invoke_plugin_callbacks_full): Likewise.
     * doc/plugins.texi: Document new plugin events.

gcc/c-family/
2012-05-24  Yunfeng ZHANG <zyf.zeroos@gmail.com>
     * c-lex.c: Include plugin.h.
     (c_lex_with_flags): Invoke PLUGIN_CPP_TOKEN callback.
     * c-common.h: Include c-pragma.h. Move c_id_kind/c_token definitions from
     c-parser.c.

[-- Attachment #3: gcc.patch --]
[-- Type: application/octet-stream, Size: 7912 bytes --]

diff -cp .pc/symdb_enhance_plugin/gcc/c-parser.c gcc/c-parser.c
*** .pc/symdb_enhance_plugin/gcc/c-parser.c	Wed Dec 21 04:44:13 2011
--- gcc/c-parser.c	Fri May 25 14:56:56 2012
*************** c_parse_init (void)
*** 121,165 ****
     C++).  It would then be possible to share more of the C and C++
     lexer code, if desired.  */
  
- /* The following local token type is used.  */
- 
- /* A keyword.  */
- #define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
- 
- /* More information about the type of a CPP_NAME token.  */
- typedef enum c_id_kind {
-   /* An ordinary identifier.  */
-   C_ID_ID,
-   /* An identifier declared as a typedef name.  */
-   C_ID_TYPENAME,
-   /* An identifier declared as an Objective-C class name.  */
-   C_ID_CLASSNAME,
-   /* An address space identifier.  */
-   C_ID_ADDRSPACE,
-   /* Not an identifier.  */
-   C_ID_NONE
- } c_id_kind;
- 
- /* A single C token after string literal concatenation and conversion
-    of preprocessing tokens to tokens.  */
- typedef struct GTY (()) c_token {
-   /* The kind of token.  */
-   ENUM_BITFIELD (cpp_ttype) type : 8;
-   /* If this token is a CPP_NAME, this value indicates whether also
-      declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
-   ENUM_BITFIELD (c_id_kind) id_kind : 8;
-   /* If this token is a keyword, this value indicates which keyword.
-      Otherwise, this value is RID_MAX.  */
-   ENUM_BITFIELD (rid) keyword : 8;
-   /* If this token is a CPP_PRAGMA, this indicates the pragma that
-      was seen.  Otherwise it is PRAGMA_NONE.  */
-   ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
-   /* The location at which this token was found.  */
-   location_t location;
-   /* The value associated with this token, if any.  */
-   tree value;
- } c_token;
- 
  /* A parser structure recording information about the state and
     context of parsing.  Includes lexer information with up to two
     tokens of look-ahead; more are not needed for C.  */
--- 121,126 ----
*************** c_lex_one_token (c_parser *parser, c_tok
*** 388,393 ****
--- 349,355 ----
        break;
      }
    timevar_pop (TV_LEX);
+   invoke_plugin_callbacks (PLUGIN_C_TOKEN, token);
  }
  
  /* Return a pointer to the next token from PARSER, reading it in if
*************** c_parser_external_declaration (c_parser 
*** 1360,1365 ****
--- 1322,1328 ----
  	 an @interface or @protocol with prefix attributes).  We can
  	 only tell which after parsing the declaration specifiers, if
  	 any, and the first declarator.  */
+       invoke_plugin_callbacks (PLUGIN_EXTERN_DECL, NULL);
        c_parser_declaration_or_fndef (parser, true, true, true, false, true, NULL);
        break;
      }
*************** c_parser_declaration_or_fndef (c_parser 
*** 1488,1493 ****
--- 1451,1461 ----
        return;
      }
    finish_declspecs (specs);
+   {
+     void* pair[2]; pair[0] = specs; pair[1] = (void*) parser->tokens_avail;
+     if (!nested)
+       invoke_plugin_callbacks (PLUGIN_EXTERN_DECLSPECS, pair);
+   }
    if (c_parser_next_token_is (parser, CPP_SEMICOLON))
      {
        if (empty_ok)
*************** c_parser_declaration_or_fndef (c_parser 
*** 1622,1627 ****
--- 1590,1600 ----
  	{
  	  tree asm_name = NULL_TREE;
  	  tree postfix_attrs = NULL_TREE;
+ 	  {
+ 	    void* pair[2]; pair[0] = specs; pair[1] = declarator;
+         if (!nested)
+           invoke_plugin_callbacks (PLUGIN_EXTERN_VAR, pair);
+ 	  }
  	  if (!diagnosed_no_specs && !specs->declspecs_seen_p)
  	    {
  	      diagnosed_no_specs = true;
*************** c_parser_declaration_or_fndef (c_parser 
*** 1748,1758 ****
--- 1721,1735 ----
  	 declarator with a nonempty identifier list in a definition;
  	 and postfix attributes have never been accepted here in
  	 function definitions either.  */
+       if (!nested)
+         invoke_plugin_callbacks (PLUGIN_EXTERN_FUNC_OLD_PARAM, NULL);
        while (c_parser_next_token_is_not (parser, CPP_EOF)
  	     && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
  	c_parser_declaration_or_fndef (parser, false, false, false,
  				       true, false, NULL);
        store_parm_decls ();
+       if (!nested)
+         invoke_plugin_callbacks (PLUGIN_EXTERN_FUNC, declarator);
        DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
  	= c_parser_peek_token (parser)->location;
        fnbody = c_parser_compound_statement (parser);
*************** c_parser_enum_specifier (c_parser *parse
*** 2266,2271 ****
--- 2243,2249 ----
  	    }
  	  token = c_parser_peek_token (parser);
  	  enum_id = token->value;
+       invoke_plugin_callbacks (PLUGIN_ENUM_SPECIFIER, enum_id);
  	  /* Set the location in case we create a decl now.  */
  	  c_parser_set_source_position_from_token (token);
  	  decl_loc = value_loc = token->location;
*************** c_parser_postfix_expression_after_primar
*** 6865,6870 ****
--- 6843,6849 ----
  	  break;
  	case CPP_OPEN_PAREN:
  	  /* Function call.  */
+       invoke_plugin_callbacks (PLUGIN_CALL_FUNCTION, expr.value);
  	  c_parser_consume_token (parser);
  	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
  	    exprlist = NULL;
diff -cp .pc/symdb_enhance_plugin/gcc/plugin.c gcc/plugin.c
*** .pc/symdb_enhance_plugin/gcc/plugin.c	Wed Oct 19 21:20:22 2011
--- gcc/plugin.c	Fri May 25 14:56:56 2012
*************** register_callback (const char *plugin_na
*** 439,444 ****
--- 439,453 ----
        case PLUGIN_EARLY_GIMPLE_PASSES_START:
        case PLUGIN_EARLY_GIMPLE_PASSES_END:
        case PLUGIN_NEW_PASS:
+       case PLUGIN_CPP_TOKEN:
+       case PLUGIN_C_TOKEN:
+       case PLUGIN_EXTERN_DECL:
+       case PLUGIN_EXTERN_FUNC_OLD_PARAM:
+       case PLUGIN_EXTERN_FUNC:
+       case PLUGIN_EXTERN_VAR:
+       case PLUGIN_EXTERN_DECLSPECS:
+       case PLUGIN_CALL_FUNCTION:
+       case PLUGIN_ENUM_SPECIFIER:
          {
            struct callback_info *new_callback;
            if (!callback)
*************** invoke_plugin_callbacks_full (int event,
*** 516,521 ****
--- 525,539 ----
        case PLUGIN_EARLY_GIMPLE_PASSES_START:
        case PLUGIN_EARLY_GIMPLE_PASSES_END:
        case PLUGIN_NEW_PASS:
+       case PLUGIN_CPP_TOKEN:
+       case PLUGIN_C_TOKEN:
+       case PLUGIN_EXTERN_DECL:
+       case PLUGIN_EXTERN_FUNC_OLD_PARAM:
+       case PLUGIN_EXTERN_FUNC:
+       case PLUGIN_EXTERN_VAR:
+       case PLUGIN_EXTERN_DECLSPECS:
+       case PLUGIN_CALL_FUNCTION:
+       case PLUGIN_ENUM_SPECIFIER:
          {
            /* Iterate over every callback registered with this event and
               call it.  */
diff -cp .pc/symdb_enhance_plugin/gcc/plugin.def gcc/plugin.def
*** .pc/symdb_enhance_plugin/gcc/plugin.def	Thu Aug 11 23:57:38 2011
--- gcc/plugin.def	Fri May 25 14:56:56 2012
*************** DEFEVENT (PLUGIN_EARLY_GIMPLE_PASSES_END
*** 92,97 ****
--- 92,125 ----
  /* Called when a pass is first instantiated.  */
  DEFEVENT (PLUGIN_NEW_PASS)
  
+ /* Called when a cpp token is extracted.  */
+ DEFEVENT (PLUGIN_CPP_TOKEN)
+ 
+ /* Called when a c token is extracted.  */
+ DEFEVENT (PLUGIN_C_TOKEN)
+ 
+ /* An extern declaration (file-scope) is encounted. */
+ DEFEVENT (PLUGIN_EXTERN_DECL)
+ 
+ /* Cooperate PLUGIN_EXTERN_FUNC to parse a function with old-style parameter
+  * declaration. */
+ DEFEVENT (PLUGIN_EXTERN_FUNC_OLD_PARAM)
+ 
+ /* Called when an extern function definition is parsed. */
+ DEFEVENT (PLUGIN_EXTERN_FUNC)
+ 
+ /* Called when an extern variable definition is parsed. */
+ DEFEVENT (PLUGIN_EXTERN_VAR)
+ 
+ /* An extern declaration specifier definition is parsed. */
+ DEFEVENT (PLUGIN_EXTERN_DECLSPECS)
+ 
+ /* A function is called. */
+ DEFEVENT (PLUGIN_CALL_FUNCTION)
+ 
+ /* Called when an enum specifier is parsed. */
+ DEFEVENT (PLUGIN_ENUM_SPECIFIER)
+ 
  /* After the hard-coded events above, plugins can dynamically allocate events
     at run time.
     PLUGIN_EVENT_FIRST_DYNAMIC only appears as last enum element.  */

[-- Attachment #4: libcpp.patch --]
[-- Type: application/octet-stream, Size: 8719 bytes --]

diff -cp .pc/symdb_enhance_libcpp/libcpp/directives.c libcpp/directives.c
*** .pc/symdb_enhance_libcpp/libcpp/directives.c	Mon Oct 17 17:59:12 2011
--- libcpp/directives.c	Fri May 25 14:56:56 2012
*************** _cpp_handle_directive (cpp_reader *pfile
*** 492,497 ****
--- 492,499 ----
    else if (skip == 0)
      _cpp_backup_tokens (pfile, 1);
  
+   if (pfile->cb.end_directive)
+     pfile->cb.end_directive (pfile);
    end_directive (pfile, skip);
    if (was_parsing_args && !pfile->state.in_deferred_pragma)
      {
diff -cp .pc/symdb_enhance_libcpp/libcpp/internal.h libcpp/internal.h
*** .pc/symdb_enhance_libcpp/libcpp/internal.h	Mon Jan  9 16:48:43 2012
--- libcpp/internal.h	Fri May 25 14:56:56 2012
*************** struct _cpp_line_note
*** 291,296 ****
--- 291,301 ----
       intervening space, 0 represents a note that has already been handled,
       and anything else is invalid.  */
    unsigned int type;
+ 
+   /* file offset adjustment is recorded by add_line_note to adjust
+    * cpp_token::file_offset. The case is when some spaces are left after an
+    * escaped newline `\', cpp_token::file_offset becomes inexact. */
+   const unsigned char *adjust_offset;
  };
  
  /* Represents the contents of a file cpplib has read in.  */
diff -cp .pc/symdb_enhance_libcpp/libcpp/lex.c libcpp/lex.c
*** .pc/symdb_enhance_libcpp/libcpp/lex.c	Thu Dec  8 06:05:59 2011
--- libcpp/lex.c	Fri May 25 14:56:56 2012
*************** static const struct token_spelling token
*** 51,57 ****
  #define TOKEN_SPELL(token) (token_spellings[(token)->type].category)
  #define TOKEN_NAME(token) (token_spellings[(token)->type].name)
  
! static void add_line_note (cpp_buffer *, const uchar *, unsigned int);
  static int skip_line_comment (cpp_reader *);
  static void skip_whitespace (cpp_reader *, cppchar_t);
  static void lex_string (cpp_reader *, cpp_token *, const uchar *);
--- 51,58 ----
  #define TOKEN_SPELL(token) (token_spellings[(token)->type].category)
  #define TOKEN_NAME(token) (token_spellings[(token)->type].name)
  
! static void add_line_note (cpp_buffer *, const uchar *, unsigned int,
! 			   const uchar *);
  static int skip_line_comment (cpp_reader *);
  static void skip_whitespace (cpp_reader *, cppchar_t);
  static void lex_string (cpp_reader *, cpp_token *, const uchar *);
*************** cpp_ideq (const cpp_token *token, const 
*** 82,88 ****
  /* Record a note TYPE at byte POS into the current cleaned logical
     line.  */
  static void
! add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type)
  {
    if (buffer->notes_used == buffer->notes_cap)
      {
--- 83,90 ----
  /* Record a note TYPE at byte POS into the current cleaned logical
     line.  */
  static void
! add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type,
! 	       const uchar * offset)
  {
    if (buffer->notes_used == buffer->notes_cap)
      {
*************** add_line_note (cpp_buffer *buffer, const
*** 93,98 ****
--- 95,101 ----
  
    buffer->notes[buffer->notes_used].pos = pos;
    buffer->notes[buffer->notes_used].type = type;
+   buffer->notes[buffer->notes_used].adjust_offset = offset;
    buffer->notes_used++;
  }
  
*************** _cpp_clean_line (cpp_reader *pfile)
*** 689,695 ****
  		{
  		  /* Have a trigraph.  We may or may not have to convert
  		     it.  Add a line note regardless, for -Wtrigraphs.  */
! 		  add_line_note (buffer, s, s[2]);
  		  if (CPP_OPTION (pfile, trigraphs))
  		    {
  		      /* We do, and that means we have to switch to the
--- 692,698 ----
  		{
  		  /* Have a trigraph.  We may or may not have to convert
  		     it.  Add a line note regardless, for -Wtrigraphs.  */
! 		  add_line_note (buffer, s, s[2], 0);
  		  if (CPP_OPTION (pfile, trigraphs))
  		    {
  		      /* We do, and that means we have to switch to the
*************** _cpp_clean_line (cpp_reader *pfile)
*** 734,740 ****
  
        /* Have an escaped newline; process it and proceed to
  	 the slow path.  */
!       add_line_note (buffer, p - 1, p != d ? ' ' : '\\');
        d = p - 2;
        buffer->next_line = p - 1;
  
--- 737,743 ----
  
        /* Have an escaped newline; process it and proceed to
  	 the slow path.  */
!       add_line_note (buffer, p - 1, p != d ? ' ' : '\\', s + 1);
        d = p - 2;
        buffer->next_line = p - 1;
  
*************** _cpp_clean_line (cpp_reader *pfile)
*** 759,772 ****
  	      if (p == buffer->next_line || p[-1] != '\\')
  		break;
  
! 	      add_line_note (buffer, p - 1, p != d ? ' ': '\\');
  	      d = p - 2;
  	      buffer->next_line = p - 1;
  	    }
  	  else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
  	    {
  	      /* Add a note regardless, for the benefit of -Wtrigraphs.  */
! 	      add_line_note (buffer, d, s[2]);
  	      if (CPP_OPTION (pfile, trigraphs))
  		{
  		  *d = _cpp_trigraph_map[s[2]];
--- 762,775 ----
  	      if (p == buffer->next_line || p[-1] != '\\')
  		break;
  
! 	      add_line_note (buffer, p - 1, p != d ? ' ': '\\', s + 1);
  	      d = p - 2;
  	      buffer->next_line = p - 1;
  	    }
  	  else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
  	    {
  	      /* Add a note regardless, for the benefit of -Wtrigraphs.  */
! 	      add_line_note (buffer, d, s[2], 0);
  	      if (CPP_OPTION (pfile, trigraphs))
  		{
  		  *d = _cpp_trigraph_map[s[2]];
*************** _cpp_clean_line (cpp_reader *pfile)
*** 789,795 ****
   done:
    *d = '\n';
    /* A sentinel note that should never be processed.  */
!   add_line_note (buffer, d + 1, '\n');
    buffer->next_line = s + 1;
  }
  
--- 792,798 ----
   done:
    *d = '\n';
    /* A sentinel note that should never be processed.  */
!   add_line_note (buffer, d + 1, '\n', s + 1);
    buffer->next_line = s + 1;
  }
  
*************** _cpp_lex_token (cpp_reader *pfile)
*** 1886,1891 ****
--- 1889,1896 ----
  		 handles the directive as normal.  */
  	      && pfile->state.parsing_args != 1)
  	    {
+ 	      if (pfile->cb.start_directive)
+ 		pfile->cb.start_directive (pfile, result);
  	      if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
  		{
  		  if (pfile->directive_result.type == CPP_PADDING)
*************** _cpp_lex_direct (cpp_reader *pfile)
*** 2032,2037 ****
--- 2037,2053 ----
        _cpp_process_line_notes (pfile, false);
        result->src_loc = pfile->line_table->highest_line;
      }
+   if (buffer->cur_note != 0)
+     {
+       int index = buffer->cur_note - 1;
+       result->file_offset = buffer->cur - buffer->buf;
+       result->file_offset +=
+ 	buffer->notes[index].adjust_offset - buffer->notes[index].pos;
+     }
+   else
+     {
+       result->file_offset = buffer->cur - buffer->buf;
+     }
    c = *buffer->cur++;
  
    if (pfile->forced_token_location_p)
*************** _cpp_lex_direct (cpp_reader *pfile)
*** 2346,2351 ****
--- 2362,2369 ----
        break;
      }
  
+   if (pfile->cb.directive_token)
+     pfile->cb.directive_token (pfile, result);
    return result;
  }
  
diff -cp .pc/symdb_enhance_libcpp/libcpp/macro.c libcpp/macro.c
*** .pc/symdb_enhance_libcpp/libcpp/macro.c	Mon Jan  9 22:15:25 2012
--- libcpp/macro.c	Fri May 25 14:56:56 2012
*************** enter_macro_context (cpp_reader *pfile, 
*** 1029,1037 ****
--- 1029,1041 ----
  	      if (pragma_buff)
  		_cpp_release_buff (pfile, pragma_buff);
  
+ 	      if (pfile->cb.macro_end_arg)
+ 		pfile->cb.macro_end_arg (pfile, true);
  	      return 0;
  	    }
  
+ 	  if (pfile->cb.macro_end_arg)
+ 	    pfile->cb.macro_end_arg (pfile, false);
  	  if (macro->paramc > 0)
  	    replace_args (pfile, node, macro,
  			  (macro_arg *) buff->base,
*************** cpp_get_token_1 (cpp_reader *pfile, sour
*** 2263,2268 ****
--- 2267,2274 ----
  	  if (pfile->context->c.macro)
  	    ++num_expanded_macros_counter;
  	  _cpp_pop_context (pfile);
+ 	  if (pfile->cb.macro_end_expand)
+ 	    pfile->cb.macro_end_expand (pfile);
  	  if (pfile->state.in_directive)
  	    continue;
  	  result = &pfile->avoid_paste;
*************** cpp_get_token_1 (cpp_reader *pfile, sour
*** 2321,2328 ****
  		}
  	    }
  	  else
! 	    ret = enter_macro_context (pfile, node, result, 
! 				       virt_loc);
  	  if (ret)
   	    {
  	      if (pfile->state.in_directive || ret == 2)
--- 2327,2340 ----
  		}
  	    }
  	  else
!   	    {
!  	      if (pfile->cb.macro_start_expand)
!  		pfile->cb.macro_start_expand (pfile, result, node);
!  	  ret = enter_macro_context (pfile, node, result, virt_loc);
!      if (ret == 0 && pfile->cb.macro_end_expand)
!        /* macro expansion is canceled. */
!        pfile->cb.macro_end_expand (pfile);
!  	    }
  	  if (ret)
   	    {
  	      if (pfile->state.in_directive || ret == 2)

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] gcc symbol database
  2012-05-31  1:53   ` Yunfeng ZHANG
@ 2012-05-31  2:02     ` Yunfeng ZHANG
  0 siblings, 0 replies; 3+ messages in thread
From: Yunfeng ZHANG @ 2012-05-31  2:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dodji Seketeli, Joseph S. Myers, Dave Korn, Tom Tromey

[-- Attachment #1: Type: text/plain, Size: 134 bytes --]

Resend ChangeLog and two patches by attachment. Patches using `diff
-upr' based on quilt internal data .pc/XX and original directory.

[-- Attachment #2: ChangeLog --]
[-- Type: application/octet-stream, Size: 1928 bytes --]

ChangeLog
-------------------------
libcpp/
2012-05-24  Yunfeng ZHANG <zyf.zeroos@gmail.com>

      * include/cpplib.h (struct cpp_callbacks): Add new callbacks.
      macro_start_expand, macro_end_arg, macro_end_expand, start_directive,
      end_directive, directive_token.
      (cpp_token): Add file_offset field for every token.
      * internal.h (struct _cpp_line_note): Add adjust_offset field to adjust
      new cpp_token::file_offset.
      * directives.c (_cpp_handle_directive): Implement end_directive.
      * macro.c (enter_macro_context): Implement macro_end_arg.
      (cpp_get_token_1): Implement macro_start_expand and macro_end_expand.
      * lex.c (add_line_note): Add offset argument for file offset adjustment.
      (_cpp_clean_line): Using new add_line_note declaration.

gcc/
2012-05-24  Yunfeng ZHANG <zyf.zeroos@gmail.com>

     * plugin.def: New plugin events, one for broadcast new token is arrived,
     another is for new definition notification.
     * c-parser.c: Move c_id_kind/c_token definitions to c-family/c-common.h.
     (c_lex_one_token): Invoke PLUGIN_C_TOKEN callback.
     (c_parser_external_declaration): Invoke PLUGIN_EXTERN_DECL callback.
     (c_parser_declaration_or_fndef): Invoke PLUGIN_EXTERN_DECLSPECS,
     PLUGIN_EXTERN_VAR, PLUGIN_EXTERN_FUNC_OLD_PARAM, PLUGIN_EXTERN_FUNC
     callbacks.
     (c_parser_enum_specifier): Invoke PLUGIN_ENUM_SPECIFIER callback.
     (c_parser_postfix_expression_after_primary): Invoke PLUGIN_CALL_FUNCTION
     callback.
     * plugin.c (register_callback): Handle new plugin events.
     (invoke_plugin_callbacks_full): Likewise.
     * doc/plugins.texi: Document new plugin events.

gcc/c-family/
2012-05-24  Yunfeng ZHANG <zyf.zeroos@gmail.com>
     * c-lex.c: Include plugin.h.
     (c_lex_with_flags): Invoke PLUGIN_CPP_TOKEN callback.
     * c-common.h: Include c-pragma.h. Move c_id_kind/c_token definitions from
     c-parser.c.

[-- Attachment #3: gcc.patch --]
[-- Type: application/octet-stream, Size: 11950 bytes --]

diff -upr .pc/symdb_enhance_plugin/gcc/c-family/c-common.h gcc/c-family/c-common.h
--- .pc/symdb_enhance_plugin/gcc/c-family/c-common.h	2011-12-21 04:44:13.000000000 +0800
+++ gcc/c-family/c-common.h	2012-05-25 14:56:56.776263281 +0800
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  
 #include "splay-tree.h"
 #include "cpplib.h"
 #include "ggc.h"
+#include "c-pragma.h"
 
 /* In order for the format checking to accept the C frontend
    diagnostic framework extensions, you must include this file before
@@ -1116,4 +1117,43 @@ struct GTY(()) tree_userdef_literal {
 
 extern tree build_userdef_literal (tree suffix_id, tree value, tree num_string);
 
+/* The following local token type is used.  */
+
+/* A keyword.  */
+#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
+
+/* More information about the type of a CPP_NAME token.  */
+typedef enum c_id_kind {
+  /* An ordinary identifier.  */
+  C_ID_ID,
+  /* An identifier declared as a typedef name.  */
+  C_ID_TYPENAME,
+  /* An identifier declared as an Objective-C class name.  */
+  C_ID_CLASSNAME,
+  /* An address space identifier.  */
+  C_ID_ADDRSPACE,
+  /* Not an identifier.  */
+  C_ID_NONE
+} c_id_kind;
+
+/* A single C token after string literal concatenation and conversion
+   of preprocessing tokens to tokens.  */
+typedef struct GTY (()) c_token {
+  /* The kind of token.  */
+  ENUM_BITFIELD (cpp_ttype) type : 8;
+  /* If this token is a CPP_NAME, this value indicates whether also
+     declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
+  ENUM_BITFIELD (c_id_kind) id_kind : 8;
+  /* If this token is a keyword, this value indicates which keyword.
+     Otherwise, this value is RID_MAX.  */
+  ENUM_BITFIELD (rid) keyword : 8;
+  /* If this token is a CPP_PRAGMA, this indicates the pragma that
+     was seen.  Otherwise it is PRAGMA_NONE.  */
+  ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
+  /* The value associated with this token, if any.  */
+  tree value;
+  /* The location at which this token was found.  */
+  location_t location;
+} c_token;
+
 #endif /* ! GCC_C_COMMON_H */
diff -upr .pc/symdb_enhance_plugin/gcc/c-family/c-lex.c gcc/c-family/c-lex.c
--- .pc/symdb_enhance_plugin/gcc/c-family/c-lex.c	2011-10-27 03:31:16.000000000 +0800
+++ gcc/c-family/c-lex.c	2012-05-25 14:56:56.767134882 +0800
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  
 #include "splay-tree.h"
 #include "debug.h"
 #include "target.h"
+#include "plugin.h"
 
 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
@@ -380,6 +381,7 @@ c_lex_with_flags (tree *value, location_
 	    case CPP_STRING32:
 	    case CPP_UTF8STRING:
 	      type = lex_string (tok, value, true, true);
+		  tok = NULL;
 	      break;
 
 	    case CPP_NAME:
@@ -481,6 +483,7 @@ c_lex_with_flags (tree *value, location_
 	{
 	  type = lex_string (tok, value, false,
 			     (lex_flags & C_LEX_STRING_NO_TRANSLATE) == 0);
+	  tok = NULL;
 	  break;
 	}
       *value = build_string (tok->val.str.len, (const char *) tok->val.str.text);
@@ -515,6 +518,7 @@ c_lex_with_flags (tree *value, location_
     }
 
   timevar_pop (TV_CPP);
+  invoke_plugin_callbacks (PLUGIN_CPP_TOKEN, (cpp_token*) tok);
 
   return type;
 }
diff -upr .pc/symdb_enhance_plugin/gcc/c-parser.c gcc/c-parser.c
--- .pc/symdb_enhance_plugin/gcc/c-parser.c	2011-12-21 04:44:13.000000000 +0800
+++ gcc/c-parser.c	2012-05-25 14:56:56.772261126 +0800
@@ -121,45 +121,6 @@ c_parse_init (void)
    C++).  It would then be possible to share more of the C and C++
    lexer code, if desired.  */
 
-/* The following local token type is used.  */
-
-/* A keyword.  */
-#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
-
-/* More information about the type of a CPP_NAME token.  */
-typedef enum c_id_kind {
-  /* An ordinary identifier.  */
-  C_ID_ID,
-  /* An identifier declared as a typedef name.  */
-  C_ID_TYPENAME,
-  /* An identifier declared as an Objective-C class name.  */
-  C_ID_CLASSNAME,
-  /* An address space identifier.  */
-  C_ID_ADDRSPACE,
-  /* Not an identifier.  */
-  C_ID_NONE
-} c_id_kind;
-
-/* A single C token after string literal concatenation and conversion
-   of preprocessing tokens to tokens.  */
-typedef struct GTY (()) c_token {
-  /* The kind of token.  */
-  ENUM_BITFIELD (cpp_ttype) type : 8;
-  /* If this token is a CPP_NAME, this value indicates whether also
-     declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
-  ENUM_BITFIELD (c_id_kind) id_kind : 8;
-  /* If this token is a keyword, this value indicates which keyword.
-     Otherwise, this value is RID_MAX.  */
-  ENUM_BITFIELD (rid) keyword : 8;
-  /* If this token is a CPP_PRAGMA, this indicates the pragma that
-     was seen.  Otherwise it is PRAGMA_NONE.  */
-  ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
-  /* The location at which this token was found.  */
-  location_t location;
-  /* The value associated with this token, if any.  */
-  tree value;
-} c_token;
-
 /* A parser structure recording information about the state and
    context of parsing.  Includes lexer information with up to two
    tokens of look-ahead; more are not needed for C.  */
@@ -388,6 +349,7 @@ c_lex_one_token (c_parser *parser, c_tok
       break;
     }
   timevar_pop (TV_LEX);
+  invoke_plugin_callbacks (PLUGIN_C_TOKEN, token);
 }
 
 /* Return a pointer to the next token from PARSER, reading it in if
@@ -1360,6 +1322,7 @@ c_parser_external_declaration (c_parser 
 	 an @interface or @protocol with prefix attributes).  We can
 	 only tell which after parsing the declaration specifiers, if
 	 any, and the first declarator.  */
+      invoke_plugin_callbacks (PLUGIN_EXTERN_DECL, NULL);
       c_parser_declaration_or_fndef (parser, true, true, true, false, true, NULL);
       break;
     }
@@ -1488,6 +1451,11 @@ c_parser_declaration_or_fndef (c_parser 
       return;
     }
   finish_declspecs (specs);
+  {
+    void* pair[2]; pair[0] = specs; pair[1] = (void*) parser->tokens_avail;
+    if (!nested)
+      invoke_plugin_callbacks (PLUGIN_EXTERN_DECLSPECS, pair);
+  }
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     {
       if (empty_ok)
@@ -1622,6 +1590,11 @@ c_parser_declaration_or_fndef (c_parser 
 	{
 	  tree asm_name = NULL_TREE;
 	  tree postfix_attrs = NULL_TREE;
+	  {
+	    void* pair[2]; pair[0] = specs; pair[1] = declarator;
+        if (!nested)
+          invoke_plugin_callbacks (PLUGIN_EXTERN_VAR, pair);
+	  }
 	  if (!diagnosed_no_specs && !specs->declspecs_seen_p)
 	    {
 	      diagnosed_no_specs = true;
@@ -1748,11 +1721,15 @@ c_parser_declaration_or_fndef (c_parser 
 	 declarator with a nonempty identifier list in a definition;
 	 and postfix attributes have never been accepted here in
 	 function definitions either.  */
+      if (!nested)
+        invoke_plugin_callbacks (PLUGIN_EXTERN_FUNC_OLD_PARAM, NULL);
       while (c_parser_next_token_is_not (parser, CPP_EOF)
 	     && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
 	c_parser_declaration_or_fndef (parser, false, false, false,
 				       true, false, NULL);
       store_parm_decls ();
+      if (!nested)
+        invoke_plugin_callbacks (PLUGIN_EXTERN_FUNC, declarator);
       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
 	= c_parser_peek_token (parser)->location;
       fnbody = c_parser_compound_statement (parser);
@@ -2266,6 +2243,7 @@ c_parser_enum_specifier (c_parser *parse
 	    }
 	  token = c_parser_peek_token (parser);
 	  enum_id = token->value;
+      invoke_plugin_callbacks (PLUGIN_ENUM_SPECIFIER, enum_id);
 	  /* Set the location in case we create a decl now.  */
 	  c_parser_set_source_position_from_token (token);
 	  decl_loc = value_loc = token->location;
@@ -6865,6 +6843,7 @@ c_parser_postfix_expression_after_primar
 	  break;
 	case CPP_OPEN_PAREN:
 	  /* Function call.  */
+      invoke_plugin_callbacks (PLUGIN_CALL_FUNCTION, expr.value);
 	  c_parser_consume_token (parser);
 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
 	    exprlist = NULL;
diff -upr .pc/symdb_enhance_plugin/gcc/doc/plugins.texi gcc/doc/plugins.texi
--- .pc/symdb_enhance_plugin/gcc/doc/plugins.texi	2011-08-11 23:57:38.000000000 +0800
+++ gcc/doc/plugins.texi	2012-05-25 14:56:56.775216761 +0800
@@ -184,6 +184,23 @@ enum plugin_event
   PLUGIN_EARLY_GIMPLE_PASSES_END,
   /* Called when a pass is first instantiated.  */
   PLUGIN_NEW_PASS,
+  PLUGIN_CPP_TOKEN,                /* Called when GCC gets a cpp token. */
+  PLUGIN_C_TOKEN,                  /* Called when GCC gets a c token. */
+  /* An extern declaration (file-scope) is encounted. */
+  PLUGIN_EXTERN_DECL,
+  /* Cooperate PLUGIN_EXTERN_FUNC to parse a function with old-style parameter
+   * declaration. */
+  PLUGIN_EXTERN_FUNC_OLD_PARAM,
+  /* An extern function definition is parsed. */
+  PLUGIN_EXTERN_FUNC,
+  /* An extern variable definition is parsed. */
+  PLUGIN_EXTERN_VAR,
+  /* An extern declaration specifier definition is parsed. */
+  PLUGIN_EXTERN_DECLSPECS,
+  /* A function is called. */
+  PLUGIN_CALL_FUNCTION,
+  /* An enum specifier is parsed. */
+  PLUGIN_ENUM_SPECIFIER,
 
   PLUGIN_EVENT_FIRST_DYNAMIC    /* Dummy event used for indexing callback
                                    array.  */
diff -upr .pc/symdb_enhance_plugin/gcc/plugin.c gcc/plugin.c
--- .pc/symdb_enhance_plugin/gcc/plugin.c	2011-10-19 21:20:22.000000000 +0800
+++ gcc/plugin.c	2012-05-25 14:56:56.774266369 +0800
@@ -439,6 +439,15 @@ register_callback (const char *plugin_na
       case PLUGIN_EARLY_GIMPLE_PASSES_START:
       case PLUGIN_EARLY_GIMPLE_PASSES_END:
       case PLUGIN_NEW_PASS:
+      case PLUGIN_CPP_TOKEN:
+      case PLUGIN_C_TOKEN:
+      case PLUGIN_EXTERN_DECL:
+      case PLUGIN_EXTERN_FUNC_OLD_PARAM:
+      case PLUGIN_EXTERN_FUNC:
+      case PLUGIN_EXTERN_VAR:
+      case PLUGIN_EXTERN_DECLSPECS:
+      case PLUGIN_CALL_FUNCTION:
+      case PLUGIN_ENUM_SPECIFIER:
         {
           struct callback_info *new_callback;
           if (!callback)
@@ -516,6 +525,15 @@ invoke_plugin_callbacks_full (int event,
       case PLUGIN_EARLY_GIMPLE_PASSES_START:
       case PLUGIN_EARLY_GIMPLE_PASSES_END:
       case PLUGIN_NEW_PASS:
+      case PLUGIN_CPP_TOKEN:
+      case PLUGIN_C_TOKEN:
+      case PLUGIN_EXTERN_DECL:
+      case PLUGIN_EXTERN_FUNC_OLD_PARAM:
+      case PLUGIN_EXTERN_FUNC:
+      case PLUGIN_EXTERN_VAR:
+      case PLUGIN_EXTERN_DECLSPECS:
+      case PLUGIN_CALL_FUNCTION:
+      case PLUGIN_ENUM_SPECIFIER:
         {
           /* Iterate over every callback registered with this event and
              call it.  */
diff -upr .pc/symdb_enhance_plugin/gcc/plugin.def gcc/plugin.def
--- .pc/symdb_enhance_plugin/gcc/plugin.def	2011-08-11 23:57:38.000000000 +0800
+++ gcc/plugin.def	2012-05-25 14:56:56.766145511 +0800
@@ -92,6 +92,34 @@ DEFEVENT (PLUGIN_EARLY_GIMPLE_PASSES_END
 /* Called when a pass is first instantiated.  */
 DEFEVENT (PLUGIN_NEW_PASS)
 
+/* Called when a cpp token is extracted.  */
+DEFEVENT (PLUGIN_CPP_TOKEN)
+
+/* Called when a c token is extracted.  */
+DEFEVENT (PLUGIN_C_TOKEN)
+
+/* An extern declaration (file-scope) is encounted. */
+DEFEVENT (PLUGIN_EXTERN_DECL)
+
+/* Cooperate PLUGIN_EXTERN_FUNC to parse a function with old-style parameter
+ * declaration. */
+DEFEVENT (PLUGIN_EXTERN_FUNC_OLD_PARAM)
+
+/* Called when an extern function definition is parsed. */
+DEFEVENT (PLUGIN_EXTERN_FUNC)
+
+/* Called when an extern variable definition is parsed. */
+DEFEVENT (PLUGIN_EXTERN_VAR)
+
+/* An extern declaration specifier definition is parsed. */
+DEFEVENT (PLUGIN_EXTERN_DECLSPECS)
+
+/* A function is called. */
+DEFEVENT (PLUGIN_CALL_FUNCTION)
+
+/* Called when an enum specifier is parsed. */
+DEFEVENT (PLUGIN_ENUM_SPECIFIER)
+
 /* After the hard-coded events above, plugins can dynamically allocate events
    at run time.
    PLUGIN_EVENT_FIRST_DYNAMIC only appears as last enum element.  */

[-- Attachment #4: libcpp.patch --]
[-- Type: application/octet-stream, Size: 8821 bytes --]

diff -upr .pc/symdb_enhance_libcpp/libcpp/directives.c libcpp/directives.c
--- .pc/symdb_enhance_libcpp/libcpp/directives.c	2011-10-17 17:59:12.000000000 +0800
+++ libcpp/directives.c	2012-05-25 14:56:56.751134781 +0800
@@ -492,6 +492,8 @@ _cpp_handle_directive (cpp_reader *pfile
   else if (skip == 0)
     _cpp_backup_tokens (pfile, 1);
 
+  if (pfile->cb.end_directive)
+    pfile->cb.end_directive (pfile);
   end_directive (pfile, skip);
   if (was_parsing_args && !pfile->state.in_deferred_pragma)
     {
diff -upr .pc/symdb_enhance_libcpp/libcpp/include/cpplib.h libcpp/include/cpplib.h
--- .pc/symdb_enhance_libcpp/libcpp/include/cpplib.h	2011-12-21 04:44:13.000000000 +0800
+++ libcpp/include/cpplib.h	2012-05-25 14:56:56.745507332 +0800
@@ -218,10 +218,10 @@ struct GTY(()) cpp_identifier {
        node;
 };
 
-/* A preprocessing token.  This has been carefully packed and should
-   occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts.  */
+/* A preprocessing token. */
 struct GTY(()) cpp_token {
   source_location src_loc;	/* Location of first char of token.  */
+  int file_offset;
   ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT;  /* token type */
   unsigned short flags;		/* flags - see above */
 
@@ -522,6 +522,24 @@ struct cpp_callbacks
      be expanded.  */
   cpp_hashnode * (*macro_to_expand) (cpp_reader *, const cpp_token *);
 
+  /* macro_{start/end}_expand are called when gcc starts to expand macro, note
+   * if A macro includes B macro, the pair is called multiple times. */
+  void (*macro_start_expand) (cpp_reader *, const cpp_token *,
+		  const cpp_hashnode *);
+  void (*macro_end_expand) (cpp_reader *);
+  /* Called when a function-like macro stops collecting macro parameters,
+   * cancel = true, macro expansion is canceled. */
+  void (*macro_end_arg) (cpp_reader *, bool cancel);
+  /* The pair is called when cpp directive (starting from `#', such as
+   * `#define', `#endif' etc) is encountered and reaches end. */
+  void (*start_directive) (cpp_reader *, const cpp_token*);
+  void (*end_directive) (cpp_reader *);
+  /* The more powerful function getting token than cpp_get_token. Here, name
+   * directive_token maybe makes you confused, it's named from
+   * libcpp/lex.c:_cpp_lex_direct, there isn't relationship between
+   * directive_token and {start, end}_directive above. */
+  void (*directive_token) (cpp_reader *, const cpp_token*);
+
   /* Called to emit a diagnostic.  This callback receives the
      translated message.  */
   bool (*error) (cpp_reader *, int, int, source_location, unsigned int,
diff -upr .pc/symdb_enhance_libcpp/libcpp/internal.h libcpp/internal.h
--- .pc/symdb_enhance_libcpp/libcpp/internal.h	2012-01-09 16:48:43.000000000 +0800
+++ libcpp/internal.h	2012-05-25 14:56:56.752132995 +0800
@@ -291,6 +291,11 @@ struct _cpp_line_note
      intervening space, 0 represents a note that has already been handled,
      and anything else is invalid.  */
   unsigned int type;
+
+  /* file offset adjustment is recorded by add_line_note to adjust
+   * cpp_token::file_offset. The case is when some spaces are left after an
+   * escaped newline `\', cpp_token::file_offset becomes inexact. */
+  const unsigned char *adjust_offset;
 };
 
 /* Represents the contents of a file cpplib has read in.  */
diff -upr .pc/symdb_enhance_libcpp/libcpp/lex.c libcpp/lex.c
--- .pc/symdb_enhance_libcpp/libcpp/lex.c	2011-12-08 06:05:59.000000000 +0800
+++ libcpp/lex.c	2012-05-25 14:56:56.747508973 +0800
@@ -51,7 +51,8 @@ static const struct token_spelling token
 #define TOKEN_SPELL(token) (token_spellings[(token)->type].category)
 #define TOKEN_NAME(token) (token_spellings[(token)->type].name)
 
-static void add_line_note (cpp_buffer *, const uchar *, unsigned int);
+static void add_line_note (cpp_buffer *, const uchar *, unsigned int,
+			   const uchar *);
 static int skip_line_comment (cpp_reader *);
 static void skip_whitespace (cpp_reader *, cppchar_t);
 static void lex_string (cpp_reader *, cpp_token *, const uchar *);
@@ -82,7 +83,8 @@ cpp_ideq (const cpp_token *token, const 
 /* Record a note TYPE at byte POS into the current cleaned logical
    line.  */
 static void
-add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type)
+add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type,
+	       const uchar * offset)
 {
   if (buffer->notes_used == buffer->notes_cap)
     {
@@ -93,6 +95,7 @@ add_line_note (cpp_buffer *buffer, const
 
   buffer->notes[buffer->notes_used].pos = pos;
   buffer->notes[buffer->notes_used].type = type;
+  buffer->notes[buffer->notes_used].adjust_offset = offset;
   buffer->notes_used++;
 }
 
@@ -689,7 +692,7 @@ _cpp_clean_line (cpp_reader *pfile)
 		{
 		  /* Have a trigraph.  We may or may not have to convert
 		     it.  Add a line note regardless, for -Wtrigraphs.  */
-		  add_line_note (buffer, s, s[2]);
+		  add_line_note (buffer, s, s[2], 0);
 		  if (CPP_OPTION (pfile, trigraphs))
 		    {
 		      /* We do, and that means we have to switch to the
@@ -734,7 +737,7 @@ _cpp_clean_line (cpp_reader *pfile)
 
       /* Have an escaped newline; process it and proceed to
 	 the slow path.  */
-      add_line_note (buffer, p - 1, p != d ? ' ' : '\\');
+      add_line_note (buffer, p - 1, p != d ? ' ' : '\\', s + 1);
       d = p - 2;
       buffer->next_line = p - 1;
 
@@ -759,14 +762,14 @@ _cpp_clean_line (cpp_reader *pfile)
 	      if (p == buffer->next_line || p[-1] != '\\')
 		break;
 
-	      add_line_note (buffer, p - 1, p != d ? ' ': '\\');
+	      add_line_note (buffer, p - 1, p != d ? ' ': '\\', s + 1);
 	      d = p - 2;
 	      buffer->next_line = p - 1;
 	    }
 	  else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
 	    {
 	      /* Add a note regardless, for the benefit of -Wtrigraphs.  */
-	      add_line_note (buffer, d, s[2]);
+	      add_line_note (buffer, d, s[2], 0);
 	      if (CPP_OPTION (pfile, trigraphs))
 		{
 		  *d = _cpp_trigraph_map[s[2]];
@@ -789,7 +792,7 @@ _cpp_clean_line (cpp_reader *pfile)
  done:
   *d = '\n';
   /* A sentinel note that should never be processed.  */
-  add_line_note (buffer, d + 1, '\n');
+  add_line_note (buffer, d + 1, '\n', s + 1);
   buffer->next_line = s + 1;
 }
 
@@ -1886,6 +1889,8 @@ _cpp_lex_token (cpp_reader *pfile)
 		 handles the directive as normal.  */
 	      && pfile->state.parsing_args != 1)
 	    {
+	      if (pfile->cb.start_directive)
+		pfile->cb.start_directive (pfile, result);
 	      if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
 		{
 		  if (pfile->directive_result.type == CPP_PADDING)
@@ -2032,6 +2037,17 @@ _cpp_lex_direct (cpp_reader *pfile)
       _cpp_process_line_notes (pfile, false);
       result->src_loc = pfile->line_table->highest_line;
     }
+  if (buffer->cur_note != 0)
+    {
+      int index = buffer->cur_note - 1;
+      result->file_offset = buffer->cur - buffer->buf;
+      result->file_offset +=
+	buffer->notes[index].adjust_offset - buffer->notes[index].pos;
+    }
+  else
+    {
+      result->file_offset = buffer->cur - buffer->buf;
+    }
   c = *buffer->cur++;
 
   if (pfile->forced_token_location_p)
@@ -2346,6 +2362,8 @@ _cpp_lex_direct (cpp_reader *pfile)
       break;
     }
 
+  if (pfile->cb.directive_token)
+    pfile->cb.directive_token (pfile, result);
   return result;
 }
 
diff -upr .pc/symdb_enhance_libcpp/libcpp/macro.c libcpp/macro.c
--- .pc/symdb_enhance_libcpp/libcpp/macro.c	2012-01-09 22:15:25.000000000 +0800
+++ libcpp/macro.c	2012-05-25 14:56:56.749508416 +0800
@@ -1029,9 +1029,13 @@ enter_macro_context (cpp_reader *pfile, 
 	      if (pragma_buff)
 		_cpp_release_buff (pfile, pragma_buff);
 
+	      if (pfile->cb.macro_end_arg)
+		pfile->cb.macro_end_arg (pfile, true);
 	      return 0;
 	    }
 
+	  if (pfile->cb.macro_end_arg)
+	    pfile->cb.macro_end_arg (pfile, false);
 	  if (macro->paramc > 0)
 	    replace_args (pfile, node, macro,
 			  (macro_arg *) buff->base,
@@ -2263,6 +2267,8 @@ cpp_get_token_1 (cpp_reader *pfile, sour
 	  if (pfile->context->c.macro)
 	    ++num_expanded_macros_counter;
 	  _cpp_pop_context (pfile);
+	  if (pfile->cb.macro_end_expand)
+	    pfile->cb.macro_end_expand (pfile);
 	  if (pfile->state.in_directive)
 	    continue;
 	  result = &pfile->avoid_paste;
@@ -2321,8 +2327,14 @@ cpp_get_token_1 (cpp_reader *pfile, sour
 		}
 	    }
 	  else
-	    ret = enter_macro_context (pfile, node, result, 
-				       virt_loc);
+  	    {
+ 	      if (pfile->cb.macro_start_expand)
+ 		pfile->cb.macro_start_expand (pfile, result, node);
+ 	  ret = enter_macro_context (pfile, node, result, virt_loc);
+     if (ret == 0 && pfile->cb.macro_end_expand)
+       /* macro expansion is canceled. */
+       pfile->cb.macro_end_expand (pfile);
+ 	    }
 	  if (ret)
  	    {
 	      if (pfile->state.in_directive || ret == 2)

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-05-31  2:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-28  8:41 [PATCH 2/2] gcc symbol database Yunfeng ZHANG
     [not found] ` <CA+dUcj0wRSjkThO84zPRBkg9784F-3kNsrOpMQnJoAExfYx5fw@mail.gmail.com>
2012-05-31  1:53   ` Yunfeng ZHANG
2012-05-31  2:02     ` Yunfeng ZHANG

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).