@@ -629,6 +629,68 @@ static get_char_t skip_macros(parser_t *p)
629629 return PARSER_EOF ;
630630}
631631
632+ static get_char_t skip_inline_asm (parser_t * p , bool underscore )
633+ {
634+ int paren = 0 ;
635+ get_char_t ch ;
636+ 637+ ch = get_char (p );
638+ if (UNLIKELY (ch == PARSER_EOF ))
639+ return ch ;
640+ if (ch != 's' )
641+ goto check_s_failed ;
642+ ch = get_char (p );
643+ if (UNLIKELY (ch == PARSER_EOF ))
644+ return ch ;
645+ if (ch != 'm' )
646+ goto check_m_failed ;
647+ 648+ if (underscore ) {
649+ ch = get_char (p );
650+ if (UNLIKELY (ch == PARSER_EOF ))
651+ return ch ;
652+ if (ch != '_' )
653+ goto not_wrapped ;
654+ ch = get_char (p );
655+ if (UNLIKELY (ch == PARSER_EOF ))
656+ return ch ;
657+ if (ch != '_' )
658+ goto check_underscore_failed ;
659+ }
660+ not_wrapped :
661+ 662+ do {
663+ ch = get_char (p );
664+ if (ch == '\n' ) {
665+ lines ++ ;
666+ lineno ++ ;
667+ continue ;
668+ }
669+ if (ch == '/' ) {
670+ get_char_t ret = skip_comments (p );
671+ if (UNLIKELY (ret == PARSER_EOF ))
672+ return ret ;
673+ /* Continue whether a comment is found or not. */
674+ continue ;
675+ }
676+ if (UNLIKELY (ch == PARSER_EOF ))
677+ return ch ;
678+ /* Increase paren by 1 if ch is '(' and decrease by 1 if ch is ')'. */
679+ ch ^= '(' ; /* This results 0, 1, or other for '(', ')', or other. */
680+ paren += !ch - (ch == 1 );
681+ } while (paren );
682+ return PARSER_COMMENT_FOUND ;
683+ 684+ check_underscore_failed :
685+ unget_char (p );
686+ unget_char (p );
687+ check_m_failed :
688+ unget_char (p );
689+ check_s_failed :
690+ unget_char (p );
691+ return PARSER_OK ;
692+ }
693+ 632694/* Parse an integer value.
633695 * Since the Linux kernel does not support floats or doubles, only decimal,
634696 * octal, and hexadecimal formats are handled.
@@ -743,6 +805,47 @@ static get_char_t parse_identifier(parser_t *restrict p,
743805 }
744806}
745807
808+ /* Parse an potential inline assembly. */
809+ static get_char_t parse_inline_asm (parser_t * restrict p ,
810+ token_t * restrict t ,
811+ get_char_t ch )
812+ {
813+ get_char_t ret = skip_inline_asm (p , false);
814+ 815+ if (ret == PARSER_COMMENT_FOUND ) {
816+ ret |= PARSER_CONTINUE ;
817+ return ret ;
818+ }
819+ if (UNLIKELY (ret == PARSER_EOF ))
820+ return ret ;
821+ 822+ return parse_identifier (p , t , ch );
823+ }
824+ 825+ /* Parse an potential inline assembly wraped with double underscores. */
826+ static get_char_t parse_inline_asm_underscore (parser_t * restrict p ,
827+ token_t * restrict t ,
828+ get_char_t ch )
829+ {
830+ get_char_t ret = get_char (p );
831+ if (ret != '_' ) {
832+ unget_char (p );
833+ return parse_identifier (p , t , ch );
834+ }
835+ if (UNLIKELY (ret == PARSER_EOF ))
836+ return ret ;
837+ ret = skip_inline_asm (p , true);
838+ 839+ if (ret == PARSER_COMMENT_FOUND ) {
840+ ret |= PARSER_CONTINUE ;
841+ return ret ;
842+ }
843+ if (UNLIKELY (ret == PARSER_EOF ))
844+ return ret ;
845+ 846+ return parse_identifier (p , t , ch );
847+ }
848+ 746849/* Process escape sequences at the end of a string literal.
747850 * Transformations:
748851 * "foo\n" becomes "foo"
@@ -1112,7 +1215,7 @@ static get_token_action_t get_token_actions[] = {
11121215 ['|' ] = parse_op ,
11131216 ['&' ] = parse_op ,
11141217 ['-' ] = parse_minus ,
1115- ['a' ] = parse_identifier ,
1218+ ['a' ] = parse_inline_asm ,
11161219 ['b' ] = parse_identifier ,
11171220 ['c' ] = parse_identifier ,
11181221 ['d' ] = parse_identifier ,
@@ -1164,7 +1267,7 @@ static get_token_action_t get_token_actions[] = {
11641267 ['X' ] = parse_identifier ,
11651268 ['Y' ] = parse_identifier ,
11661269 ['Z' ] = parse_identifier ,
1167- ['_' ] = parse_identifier ,
1270+ ['_' ] = parse_inline_asm_underscore ,
11681271 ['"' ] = parse_literal_string ,
11691272 ['\'' ] = parse_literal_char ,
11701273 ['\\' ] = parse_backslash ,
0 commit comments