@@ -629,6 +629,68 @@ static get_char_t skip_macros(parser_t *p)
629
629
return PARSER_EOF ;
630
630
}
631
631
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
+
632
694
/* Parse an integer value.
633
695
* Since the Linux kernel does not support floats or doubles, only decimal,
634
696
* octal, and hexadecimal formats are handled.
@@ -743,6 +805,47 @@ static get_char_t parse_identifier(parser_t *restrict p,
743
805
}
744
806
}
745
807
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
+
746
849
/* Process escape sequences at the end of a string literal.
747
850
* Transformations:
748
851
* "foo\n" becomes "foo"
@@ -1112,7 +1215,7 @@ static get_token_action_t get_token_actions[] = {
1112
1215
['|' ] = parse_op ,
1113
1216
['&' ] = parse_op ,
1114
1217
['-' ] = parse_minus ,
1115
- ['a' ] = parse_identifier ,
1218
+ ['a' ] = parse_inline_asm ,
1116
1219
['b' ] = parse_identifier ,
1117
1220
['c' ] = parse_identifier ,
1118
1221
['d' ] = parse_identifier ,
@@ -1164,7 +1267,7 @@ static get_token_action_t get_token_actions[] = {
1164
1267
['X' ] = parse_identifier ,
1165
1268
['Y' ] = parse_identifier ,
1166
1269
['Z' ] = parse_identifier ,
1167
- ['_' ] = parse_identifier ,
1270
+ ['_' ] = parse_inline_asm_underscore ,
1168
1271
['"' ] = parse_literal_string ,
1169
1272
['\'' ] = parse_literal_char ,
1170
1273
['\\' ] = parse_backslash ,
0 commit comments