C++.sublime-syntax (76083B)
1 %YAML 1.2 2 --- 3 # http://www.sublimetext.com/docs/3/syntax.html 4 name: C++ 5 comment: I don't think anyone uses .hp. .cp tends to be paired with .h. (I could be wrong. :) -- chris 6 file_extensions: 7 - cpp 8 - cc 9 - cp 10 - cxx 11 - c++ 12 - C 13 - h 14 - hh 15 - hpp 16 - hxx 17 - h++ 18 - inl 19 - ipp 20 first_line_match: '-\*- C\+\+ -\*-' 21 scope: source.c++ 22 variables: 23 # number digits 24 dec_digits: '(?:\d(?:[\d'']*\d)?)' 25 26 # number exponents 27 dec_exponent: '(?:[eE][-+]??{{dec_digits}})' 28 hex_exponent: '(?:[pP][-+]??{{dec_digits}})' 29 30 # number suffixes 31 # note: nearly everything can be defined as suffix via `operator` keyword 32 # see: https://en.cppreference.com/w/cpp/numeric/complex/operator%22%22i 33 dec_suffix: '(?:[a-zA-Z_][[:alnum:]_]*|(?=[^[:alnum:]_'']))' 34 hex_suffix: '(?:[g-zG-Z_][[:alnum:]_]*|(?=[^[:alnum:]_'']))' 35 float_suffix: '[fF]' 36 integer_suffix: '[lL]{1,2}[uU]?|[uU][lL]{0,2}' 37 38 identifier: \b[[:alpha:]_][[:alnum:]_]*\b # upper and lowercase 39 macro_identifier: \b[[:upper:]_][[:upper:][:digit:]_]{2,}\b # only uppercase, at least 3 chars 40 path_lookahead: '(?:::\s*)?(?:{{identifier}}\s*::\s*)*(?:template\s+)?{{identifier}}' 41 operator_method_name: '\boperator\s*(?:[-+*/%^&|~!=<>]|[-+*/%^&|=!<>]=|<<=?|>>=?|&&|\|\||\+\+|--|,|->\*?|\(\)|\[\]|""\s*{{identifier}})' 42 casts: 'const_cast|dynamic_cast|reinterpret_cast|static_cast' 43 operator_keywords: 'and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|xor|xor_eq|noexcept' 44 control_keywords: 'break|case|catch|continue|default|do|else|for|goto|if|_Pragma|return|switch|throw|try|while' 45 memory_operators: 'new|delete' 46 basic_types: 'asm|__asm__|auto|bool|_Bool|char|_Complex|double|float|_Imaginary|int|long|short|signed|unsigned|void' 47 before_tag: 'struct|union|enum\s+class|enum\s+struct|enum|class' 48 declspec: '__declspec\(\s*\w+(?:\([^)]+\))?\s*\)' 49 storage_classes: 'static|export|extern|friend|explicit|virtual|register|thread_local' 50 type_qualifier: 'const|constexpr|mutable|typename|volatile' 51 compiler_directive: 'inline|restrict|__restrict__|__restrict' 52 visibility_modifiers: 'private|protected|public' 53 other_keywords: 'typedef|nullptr|{{visibility_modifiers}}|static_assert|sizeof|using|typeid|alignof|alignas|namespace|template' 54 modifiers: '{{storage_classes}}|{{type_qualifier}}|{{compiler_directive}}' 55 non_angle_brackets: '(?=<<|<=)' 56 57 regular: '[^(){}&;*^%=<>-]*' 58 regular_plus: '[^(){}&;*^%=<>-]+' 59 paren_open: (?:\( 60 paren_close: '\))?' 61 generic_open: (?:{{regular_plus}}(?:< 62 generic_close: '>)?)?' 63 balance_parentheses: '{{regular}}{{paren_open}}{{regular}}{{paren_close}}{{regular}}' 64 generic_lookahead: <{{generic_open}}{{generic_open}}{{regular}}{{generic_close}}\s*{{generic_close}}{{balance_parentheses}}> 65 66 data_structures_forward_decl_lookahead: '(\s+{{macro_identifier}})*\s*(:\s*({{path_lookahead}}|{{visibility_modifiers}}|,|\s|<[^;]*>)+)?;' 67 non_func_keywords: 'if|for|switch|while|decltype|sizeof|__declspec|__attribute__|typeid|alignof|alignas|static_assert' 68 69 contexts: 70 main: 71 - include: preprocessor-global 72 - include: global 73 74 ############################################################################# 75 # Reusable contexts 76 # 77 # The follow contexts are currently constructed to be reused in the 78 # Objetive-C++ syntax. They are specifically constructed to not push into 79 # sub-contexts, which ensures that Objective-C++ code isn't accidentally 80 # lexed as plain C++. 81 # 82 # The "unique-*" contexts are additions that C++ makes over C, and thus can 83 # be directly reused in Objective-C++ along with contexts from Objective-C 84 # and C. 85 ############################################################################# 86 87 unique-late-expressions: 88 # This is highlighted after all of the other control keywords 89 # to allow operator overloading to be lexed properly 90 - match: \boperator\b 91 scope: keyword.control.c++ 92 93 unique-modifiers: 94 - match: \b({{modifiers}})\b 95 scope: storage.modifier.c++ 96 97 unique-variables: 98 - match: \bthis\b 99 scope: variable.language.c++ 100 # common C++ instance var naming idiom -- fMemberName 101 - match: '\b(f|m)[[:upper:]]\w*\b' 102 scope: variable.other.readwrite.member.c++ 103 # common C++ instance var naming idiom -- m_member_name 104 - match: '\bm_[[:alnum:]_]+\b' 105 scope: variable.other.readwrite.member.c++ 106 107 unique-constants: 108 - match: \bnullptr\b 109 scope: constant.language.c++ 110 111 unique-keywords: 112 - match: \busing\b 113 scope: keyword.control.c++ 114 - match: \bbreak\b 115 scope: keyword.control.flow.break.c++ 116 - match: \bcontinue\b 117 scope: keyword.control.flow.continue.c++ 118 - match: \bgoto\b 119 scope: keyword.control.flow.goto.c++ 120 - match: \breturn\b 121 scope: keyword.control.flow.return.c++ 122 - match: \bthrow\b 123 scope: keyword.control.flow.throw.c++ 124 - match: \b({{control_keywords}})\b 125 scope: keyword.control.c++ 126 - match: '\bdelete\b(\s*\[\])?|\bnew\b(?!])' 127 scope: keyword.control.c++ 128 - match: \b({{operator_keywords}})\b 129 scope: keyword.operator.word.c++ 130 131 unique-types: 132 - match: \b(char16_t|char32_t|wchar_t|nullptr_t)\b 133 scope: storage.type.c++ 134 - match: \bclass\b 135 scope: storage.type.c++ 136 137 unique-strings: 138 - match: '((?:L|u8|u|U)?R)("([^\(\)\\ ]{0,16})\()' 139 captures: 140 1: storage.type.string.c++ 141 2: punctuation.definition.string.begin.c++ 142 push: 143 - meta_scope: string.quoted.double.c++ 144 - match: '\)\3"' 145 scope: punctuation.definition.string.end.c++ 146 pop: true 147 148 numbers: 149 # https://en.cppreference.com/w/cpp/language/floating_literal 150 151 # decimal floats 152 - match: |- 153 (?x: 154 \b{{dec_digits}} 155 (?: 156 (?: 157 (\.) 158 (?: 159 # 1.1, 1.1e1, 1.1e-1, 1.1f, 1.1e1f, 1.1e-1f, 1.1L, 1.1e1L, 1.1e-1L 160 {{dec_digits}} {{dec_exponent}}? 161 # 1.e1, 1.e-1, 1.e1f, 1.e-1f, 1.e1L, 1.e-1L 162 | {{dec_exponent}} 163 # 1., 1.f, 1.L # but not `..` 164 | (?!\.) 165 ) 166 # 1e1 1e1f 1e1L 167 | {{dec_exponent}} 168 ) ({{dec_suffix}})? 169 # 1f 170 | ({{float_suffix}}) 171 ) 172 # .1, .1e1, .1e-1, .1f, .1e1f, .1e-1f, .1L, .1e1L, .1e-1L 173 | (\.) {{dec_digits}} {{dec_exponent}}? ({{dec_suffix}})? 174 ) 175 scope: constant.numeric.float.decimal.c++ 176 captures: 177 1: punctuation.separator.decimal.c++ 178 2: storage.type.numeric.c++ 179 3: storage.type.numeric.c++ 180 4: punctuation.separator.decimal.c++ 181 5: storage.type.numeric.c++ 182 183 # hexadecimal float (C99) 184 - match: \b0[xX](?=[[:alnum:]_''.]+?[pP]) 185 scope: punctuation.definition.numeric.base.c++ 186 push: 187 - meta_include_prototype: false 188 - meta_scope: constant.numeric.float.hexadecimal.c++ 189 - match: '{{hex_exponent}}' 190 pop: true 191 - match: \. 192 scope: punctuation.separator.decimal.c++ 193 - match: \H 194 scope: invalid.illegal.numeric.digit.c++ 195 196 # https://en.cppreference.com/w/c/language/integer_constant 197 198 # binary integer 199 - match: \b0[bB] 200 scope: punctuation.definition.numeric.base.c++ 201 push: 202 - meta_include_prototype: false 203 - meta_scope: constant.numeric.integer.binary.c++ 204 - include: decimal-suffix 205 - match: '[2-9]' 206 scope: invalid.illegal.numeric.digit.c++ 207 # hexadecimal integer 208 - match: \b0[xX] 209 scope: punctuation.definition.numeric.base.c++ 210 push: 211 - meta_include_prototype: false 212 - meta_scope: constant.numeric.integer.hexadecimal.c++ 213 - include: hexadecimal-suffix 214 # octal integer 215 - match: \b0(?=[\d'']) 216 scope: punctuation.definition.numeric.base.c++ 217 push: 218 - meta_include_prototype: false 219 - meta_scope: constant.numeric.integer.octal.c++ 220 - include: decimal-suffix 221 - match: '[89]' 222 scope: invalid.illegal.numeric.digit.c++ 223 # decimal integer 224 - match: \b\d+ 225 push: 226 - meta_include_prototype: false 227 - meta_scope: constant.numeric.integer.decimal.c++ 228 - include: decimal-suffix 229 230 decimal-suffix: 231 - match: '{{dec_suffix}}' 232 scope: storage.type.numeric.c++ 233 pop: true 234 235 hexadecimal-suffix: 236 - match: '{{hex_suffix}}' 237 scope: storage.type.numeric.c++ 238 pop: true 239 240 identifiers: 241 - match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' 242 captures: 243 1: punctuation.accessor.double-colon.c++ 244 2: punctuation.accessor.double-colon.c++ 245 - match: '(?:(::)\s*)?{{identifier}}' 246 captures: 247 1: punctuation.accessor.double-colon.c++ 248 249 identifier-path-generic: 250 - include: angle-brackets 251 - match: '(?:(::)\s*)?{{identifier}}\s*(?=(<.*>)?\s*(::))\s*' 252 captures: 253 1: punctuation.accessor.double-colon.c++ 254 2: punctuation.accessor.double-colon.c++ 255 256 function-specifiers: 257 - match: \b(const|final|noexcept|override)\b 258 scope: storage.modifier.c++ 259 260 ############################################################################# 261 # The following are C++-specific contexts that should not be reused. This is 262 # because they push into subcontexts and use variables that are C++-specific. 263 ############################################################################# 264 265 ## Common context layout 266 267 global: 268 - match: '(?=\btemplate\b)' 269 push: 270 - include: template 271 - match: (?=\S) 272 set: global-modifier 273 - include: using-namespace 274 - include: namespace 275 - include: keywords-angle-brackets 276 - match: '(?={{path_lookahead}}\s*<)' 277 push: global-modifier 278 # Take care of comments just before a function definition. 279 - match: /\* 280 scope: punctuation.definition.comment.c 281 push: 282 - - match: \s*(?=\w) 283 set: global-modifier 284 - match: "" 285 pop: true 286 - - meta_scope: comment.block.c 287 - match: \*/ 288 scope: punctuation.definition.comment.c 289 pop: true 290 - match: ^\s*(\*)(?!/) 291 captures: 292 1: punctuation.definition.comment.c 293 - include: early-expressions 294 - match: ^\s*\b(extern)(?=\s+"C(\+\+)?") 295 scope: storage.modifier.c++ 296 push: 297 - include: comments 298 - include: strings 299 - match: '\{' 300 scope: punctuation.section.block.begin.c++ 301 set: 302 - meta_scope: meta.extern-c.c++ 303 - match: '^\s*(#\s*ifdef)\s*__cplusplus\s*' 304 scope: meta.preprocessor.c++ 305 captures: 306 1: keyword.control.import.c++ 307 set: 308 - match: '\}' 309 scope: punctuation.section.block.end.c++ 310 pop: true 311 - include: preprocessor-global 312 - include: global 313 - match: '\}' 314 scope: punctuation.section.block.end.c++ 315 pop: true 316 - include: preprocessor-global 317 - include: global 318 - match: (?=\S) 319 set: global-modifier 320 - match: ^\s*(?=\w) 321 push: global-modifier 322 - include: late-expressions 323 324 statements: 325 - include: preprocessor-statements 326 - include: scope:source.c#label 327 - include: expressions 328 329 expressions: 330 - include: early-expressions 331 - include: late-expressions 332 333 early-expressions: 334 - include: early-expressions-before-generic-type 335 - include: generic-type 336 - include: early-expressions-after-generic-type 337 338 early-expressions-before-generic-type: 339 - include: preprocessor-expressions 340 - include: comments 341 - include: case-default 342 - include: using-namespace 343 - include: typedef 344 - include: using-alias 345 - include: keywords-angle-brackets 346 - include: keywords-parens 347 - include: keywords 348 - include: numbers 349 # Prevent a '<' from getting scoped as the start of another template 350 # parameter list, if in reality a less-than-or-equals sign is meant. 351 - match: <= 352 scope: keyword.operator.comparison.c 353 354 early-expressions-after-generic-type: 355 - include: members-arrow 356 - include: operators 357 - include: members-dot 358 - include: strings 359 - include: parens 360 - include: brackets 361 - include: block 362 - include: variables 363 - include: constants 364 - match: ',' 365 scope: punctuation.separator.c++ 366 - match: '\)|\}' 367 scope: invalid.illegal.stray-bracket-end.c++ 368 369 expressions-minus-generic-type: 370 - include: early-expressions-before-generic-type 371 - include: angle-brackets 372 - include: early-expressions-after-generic-type 373 - include: late-expressions 374 375 expressions-minus-generic-type-function-call: 376 - include: early-expressions-before-generic-type 377 - include: angle-brackets 378 - include: early-expressions-after-generic-type 379 - include: late-expressions-before-function-call 380 - include: identifiers 381 - match: ';' 382 scope: punctuation.terminator.c++ 383 384 late-expressions: 385 - include: late-expressions-before-function-call 386 - include: function-call 387 - include: identifiers 388 - match: ';' 389 scope: punctuation.terminator.c++ 390 391 late-expressions-before-function-call: 392 - include: unique-late-expressions 393 - include: modifiers-parens 394 - include: modifiers 395 - include: types 396 397 expressions-minus-function-call: 398 - include: early-expressions 399 - include: late-expressions-before-function-call 400 - include: identifiers 401 - match: ';' 402 scope: punctuation.terminator.c++ 403 404 comments: 405 - include: scope:source.c#comments 406 407 operators: 408 - include: scope:source.c#operators 409 410 modifiers: 411 - include: unique-modifiers 412 - include: scope:source.c#modifiers 413 414 variables: 415 - include: unique-variables 416 - include: scope:source.c#variables 417 418 constants: 419 - include: unique-constants 420 - include: scope:source.c#constants 421 422 keywords: 423 - include: unique-keywords 424 - include: scope:source.c#keywords 425 426 types: 427 - include: unique-types 428 - include: types-parens 429 - include: scope:source.c#types 430 431 strings: 432 - include: unique-strings 433 - include: scope:source.c#strings 434 435 ## C++-specific contexts 436 437 case-default: 438 - match: '\b(default|case)\b' 439 scope: keyword.control.c++ 440 push: 441 - match: (?=[);,]) 442 pop: true 443 - match: ':' 444 scope: punctuation.separator.c++ 445 pop: true 446 - include: expressions 447 448 modifiers-parens: 449 - match: '\b(alignas)\b\s*(\()' 450 captures: 451 1: storage.modifier.c++ 452 2: meta.group.c++ punctuation.section.group.begin.c++ 453 push: 454 - meta_content_scope: meta.group.c++ 455 - match: '\)' 456 scope: meta.group.c++ punctuation.section.group.end.c++ 457 pop: true 458 - include: expressions 459 - match: \b(__attribute__)\s*(\(\() 460 captures: 461 1: storage.modifier.c++ 462 2: meta.group.c++ punctuation.section.group.begin.c++ 463 push : 464 - meta_scope: meta.attribute.c++ 465 - meta_content_scope: meta.group.c++ 466 - include: parens 467 - include: strings 468 - match: \)\) 469 scope: meta.group.c++ punctuation.section.group.end.c++ 470 pop: true 471 - match: \b(__declspec)(\() 472 captures: 473 1: storage.modifier.c++ 474 2: meta.group.c++ punctuation.section.group.begin.c++ 475 push: 476 - meta_content_scope: meta.group.c++ 477 - match: '\)' 478 scope: meta.group.c++ punctuation.section.group.end.c++ 479 pop: true 480 - match: '\b(align|allocate|code_seg|deprecated|property|uuid)\b\s*(\()' 481 captures: 482 1: storage.modifier.c++ 483 2: meta.group.c++ punctuation.section.group.begin.c++ 484 push: 485 - meta_content_scope: meta.group.c++ 486 - match: '\)' 487 scope: meta.group.c++ punctuation.section.group.end.c++ 488 pop: true 489 - include: numbers 490 - include: strings 491 - match: \b(get|put)\b 492 scope: variable.parameter.c++ 493 - match: ',' 494 scope: punctuation.separator.c++ 495 - match: '=' 496 scope: keyword.operator.assignment.c++ 497 - match: '\b(appdomain|deprecated|dllimport|dllexport|jintrinsic|naked|noalias|noinline|noreturn|nothrow|novtable|process|restrict|safebuffers|selectany|thread)\b' 498 scope: constant.other.c++ 499 500 types-parens: 501 - match: '\b(decltype)\b\s*(\()' 502 captures: 503 1: storage.type.c++ 504 2: meta.group.c++ punctuation.section.group.begin.c++ 505 push: 506 - meta_content_scope: meta.group.c++ 507 - match: '\)' 508 scope: meta.group.c++ punctuation.section.group.end.c++ 509 pop: true 510 - include: expressions 511 512 keywords-angle-brackets: 513 - match: \b({{casts}})\b\s* 514 scope: keyword.operator.word.cast.c++ 515 push: 516 - match: '>' 517 scope: punctuation.section.generic.end.c++ 518 pop: true 519 - match: '<' 520 scope: punctuation.section.generic.begin.c++ 521 push: 522 - match: '(?=>)' 523 pop: true 524 - include: expressions-minus-generic-type-function-call 525 526 keywords-parens: 527 - match: '\b(alignof|typeid|static_assert|sizeof)\b\s*(\()' 528 captures: 529 1: keyword.operator.word.c++ 530 2: meta.group.c++ punctuation.section.group.begin.c++ 531 push: 532 - meta_content_scope: meta.group.c++ 533 - match: '\)' 534 scope: meta.group.c++ punctuation.section.group.end.c++ 535 pop: true 536 - include: expressions 537 538 using-namespace: 539 - match: '\b(using)\s+(namespace)\b' 540 captures: 541 1: keyword.control.c++ 542 2: keyword.control.c++ 543 push: 544 - include: identifiers 545 - match: '' 546 pop: true 547 548 namespace: 549 - match: '\b(namespace)\s+(?=({{path_lookahead}})?(?!\s*[;,]))' 550 scope: meta.namespace.c++ 551 captures: 552 1: keyword.control.c++ 553 push: 554 - meta_content_scope: meta.namespace.c++ entity.name.namespace.c++ 555 - include: identifiers 556 - match: '' 557 set: 558 - meta_scope: meta.namespace.c++ 559 - include: comments 560 - match: '=' 561 scope: keyword.operator.alias.c++ 562 - match: '(?=;)' 563 pop: true 564 - match: '\}' 565 scope: meta.block.c++ punctuation.section.block.end.c++ 566 pop: true 567 - match: '\{' 568 scope: punctuation.section.block.begin.c++ 569 push: 570 - meta_scope: meta.block.c++ 571 - match: '(?=\})' 572 pop: true 573 - include: preprocessor-global 574 - include: global 575 - include: expressions 576 577 template-common: 578 # Exit the template scope if we hit some basic invalid characters. This 579 # helps when a user is in the middle of typing their template types and 580 # prevents re-highlighting the whole file until the next > is found. 581 - match: (?=[{};]) 582 pop: true 583 - include: expressions 584 585 template: 586 - match: \btemplate\b 587 scope: storage.type.template.c++ 588 push: 589 - meta_scope: meta.template.c++ 590 # Explicitly include comments here at the top, in order to NOT match the 591 # \S lookahead in the case of comments. 592 - include: comments 593 - match: < 594 scope: punctuation.section.generic.begin.c++ 595 set: 596 - meta_content_scope: meta.template.c++ 597 - match: '>' 598 scope: meta.template.c++ punctuation.section.generic.end.c++ 599 pop: true 600 - match: \.{3} 601 scope: keyword.operator.variadic.c++ 602 - match: \b(typename|{{before_tag}})\b 603 scope: storage.type.c++ 604 - include: template # include template here for nested templates 605 - include: template-common 606 - match: (?=\S) 607 set: 608 - meta_content_scope: meta.template.c++ 609 - match: \b({{before_tag}})\b 610 scope: storage.type.c++ 611 - include: template-common 612 613 generic-type: 614 - match: '(?=(?!template){{path_lookahead}}\s*{{generic_lookahead}}\s*(\(|\{))' 615 push: 616 - meta_scope: meta.function-call.c++ 617 - match: \btemplate\b 618 scope: storage.type.template.c++ 619 - match: (?:(::)\s*)?({{identifier}})\s*(<) 620 captures: 621 1: punctuation.accessor.double-colon.c++ 622 2: variable.function.c++ 623 3: punctuation.section.generic.begin.c++ 624 push: 625 - match: '>' 626 scope: punctuation.section.generic.end.c++ 627 pop: true 628 - include: expressions-minus-generic-type-function-call 629 - match: (?:(::)\s*)?({{identifier}})\s*(\() 630 captures: 631 1: punctuation.accessor.double-colon.c++ 632 2: variable.function.c++ 633 3: punctuation.section.group.begin.c++ 634 set: 635 - meta_scope: meta.function-call.c++ 636 - meta_content_scope: meta.group.c++ 637 - match: '\)' 638 scope: meta.group.c++ punctuation.section.group.end.c++ 639 pop: true 640 - include: expressions 641 - match: (?:(::)\s*)?({{identifier}})\s*(\{) 642 captures: 643 1: punctuation.accessor.double-colon.c++ 644 2: variable.function.c++ 645 3: punctuation.section.group.begin.c++ 646 set: 647 - meta_scope: meta.function-call.c++ 648 - meta_content_scope: meta.group.c++ 649 - match: '\}' 650 scope: meta.group.c++ punctuation.section.group.end.c++ 651 pop: true 652 - include: expressions 653 - include: identifiers 654 - include: angle-brackets 655 - match: '\(' 656 scope: meta.group.c++ punctuation.section.group.begin.c++ 657 set: 658 - meta_scope: meta.function-call.c++ 659 - meta_content_scope: meta.group.c++ 660 - match: '\)' 661 scope: meta.group.c++ punctuation.section.group.end.c++ 662 pop: true 663 - include: expressions 664 - match: '\{' 665 scope: meta.group.c++ punctuation.section.group.begin.c++ 666 set: 667 - meta_scope: meta.function-call.c++ 668 - meta_content_scope: meta.group.c++ 669 - match: '\}' 670 scope: meta.group.c++ punctuation.section.group.end.c++ 671 pop: true 672 - include: expressions 673 - match: '(?=(?!template){{path_lookahead}}\s*{{generic_lookahead}})' 674 push: 675 - include: identifiers 676 - match: '<' 677 scope: punctuation.section.generic.begin.c++ 678 set: 679 - match: '>' 680 scope: punctuation.section.generic.end.c++ 681 pop: true 682 - include: expressions-minus-generic-type-function-call 683 684 angle-brackets: 685 - match: '<(?!<)' 686 scope: punctuation.section.generic.begin.c++ 687 push: 688 - match: '>' 689 scope: punctuation.section.generic.end.c++ 690 pop: true 691 - include: expressions-minus-generic-type-function-call 692 693 block: 694 - match: '\{' 695 scope: punctuation.section.block.begin.c++ 696 push: 697 - meta_scope: meta.block.c++ 698 - match: (?=^\s*#\s*(elif|else|endif)\b) 699 pop: true 700 - match: '\}' 701 scope: punctuation.section.block.end.c++ 702 pop: true 703 - include: statements 704 705 function-call: 706 - match: (?={{path_lookahead}}\s*(\(|\{)) 707 push: 708 - meta_scope: meta.function-call.c++ 709 - include: scope:source.c#c99 710 - match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' 711 captures: 712 1: punctuation.accessor.double-colon.c++ 713 2: punctuation.accessor.double-colon.c++ 714 - match: '(?:(::)\s*)?({{identifier}})' 715 captures: 716 1: punctuation.accessor.c++ 717 2: variable.function.c++ 718 - match: '\(' 719 scope: meta.group.c++ punctuation.section.group.begin.c++ 720 set: 721 - meta_content_scope: meta.function-call.c++ meta.group.c++ 722 - match: '\)' 723 scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ 724 pop: true 725 - include: expressions 726 - match: '\{' 727 scope: meta.group.c++ punctuation.section.group.begin.c++ 728 set: 729 - meta_content_scope: meta.function-call.c++ meta.group.c++ 730 - match: '\}' 731 scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ 732 pop: true 733 - include: expressions 734 735 members-inside-function-call: 736 - meta_content_scope: meta.method-call.c++ meta.group.c++ 737 - match: \) 738 scope: meta.method-call.c++ meta.group.c++ punctuation.section.group.end.c++ 739 pop: true 740 - include: expressions 741 742 members-after-accessor-junction: 743 # After we've seen an accessor (dot or arrow), this context decides what 744 # kind of entity we're accessing. 745 - include: comments 746 - match: \btemplate\b 747 scope: meta.method-call.c++ storage.type.template.c++ 748 # Guaranteed to be a template member function call after we match this 749 set: 750 - meta_content_scope: meta.method-call.c++ 751 - include: comments 752 - match: '{{identifier}}' 753 scope: variable.function.member.c++ 754 set: 755 - meta_content_scope: meta.method-call.c++ 756 - match: \( 757 scope: meta.group.c++ punctuation.section.group.begin.c++ 758 set: members-inside-function-call 759 - include: comments 760 - include: angle-brackets 761 - match: (?=\S) # safety pop 762 pop: true 763 - match: (?=\S) # safety pop 764 pop: true 765 # Operator overloading 766 - match: '({{operator_method_name}})\s*(\()' 767 captures: 768 0: meta.method-call.c++ 769 1: variable.function.member.c++ 770 2: meta.group.c++ punctuation.section.group.begin.c++ 771 set: members-inside-function-call 772 # Non-templated member function call 773 - match: (~?{{identifier}})\s*(\() 774 captures: 775 0: meta.method-call.c++ 776 1: variable.function.member.c++ 777 2: meta.group.c++ punctuation.section.group.begin.c++ 778 set: members-inside-function-call 779 # Templated member function call 780 - match: (~?{{identifier}})\s*(?={{generic_lookahead}}) 781 captures: 782 1: variable.function.member.c++ 783 set: 784 - meta_scope: meta.method-call.c++ 785 - match: < 786 scope: punctuation.section.generic.begin.c++ 787 set: 788 - meta_content_scope: meta.method-call.c++ 789 - match: '>' 790 scope: punctuation.section.generic.end.c++ 791 set: 792 - meta_content_scope: meta.method-call.c++ 793 - include: comments 794 - match: \( 795 scope: punctuation.section.group.begin.c++ 796 set: members-inside-function-call 797 - match: (?=\S) # safety pop 798 pop: true 799 - include: expressions 800 # Explicit base-class access 801 - match: ({{identifier}})\s*(::) 802 captures: 803 1: variable.other.base-class.c++ 804 2: punctuation.accessor.double-colon.c++ 805 set: members-after-accessor-junction # reset 806 # Just a regular member variable 807 - match: '{{identifier}}' 808 scope: variable.other.readwrite.member.c++ 809 pop: true 810 811 members-dot: 812 - include: scope:source.c#access-illegal 813 # No lookahead required because members-dot goes after operators in the 814 # early-expressions-after-generic-type context. This means triple dots 815 # (i.e. "..." or "variadic") is attempted first. 816 - match: \. 817 scope: punctuation.accessor.dot.c++ 818 push: members-after-accessor-junction 819 820 members-arrow: 821 # This needs to be before operators in the 822 # early-expressions-after-generic-type context because otherwise the "->" 823 # from the C language will match. 824 - match: -> 825 scope: punctuation.accessor.arrow.c++ 826 push: members-after-accessor-junction 827 828 using-alias: 829 # consume keyword if followed by typename 830 - match: '\b(using)\b(?=\s+typename\b)' 831 captures: 832 1: keyword.control.c++ 833 - match: '\b(using)\b\s+({{identifier}})(?!\s*(<|::))' 834 captures: 835 1: keyword.control.c++ 836 2: entity.name.type.using.c++ 837 838 typedef: 839 - match: \btypedef\b 840 scope: storage.type.c++ 841 push: 842 - match: ({{identifier}})?\s*(?=;) 843 captures: 844 1: entity.name.type.typedef.c++ 845 pop: true 846 - match: \b(struct)\s+({{identifier}})\b 847 captures: 848 1: storage.type.c++ 849 - include: expressions-minus-generic-type 850 851 parens: 852 - match: \( 853 scope: punctuation.section.group.begin.c++ 854 push: 855 - meta_scope: meta.group.c++ 856 - match: \) 857 scope: punctuation.section.group.end.c++ 858 pop: true 859 - include: expressions 860 861 brackets: 862 - match: \[ 863 scope: punctuation.section.brackets.begin.c++ 864 push: 865 - meta_scope: meta.brackets.c++ 866 - match: \] 867 scope: punctuation.section.brackets.end.c++ 868 pop: true 869 - include: expressions 870 871 function-trailing-return-type: 872 - match: '{{non_angle_brackets}}' 873 pop: true 874 - include: angle-brackets 875 - include: types 876 - include: modifiers-parens 877 - include: modifiers 878 - include: identifiers 879 - match: \*|& 880 scope: keyword.operator.c++ 881 - include: function-trailing-return-type-parens 882 - match: '(?=\S)' 883 pop: true 884 885 function-trailing-return-type-parens: 886 - match: \( 887 scope: punctuation.section.group.begin.c++ 888 push: 889 - meta_scope: meta.group.c++ 890 - match: \) 891 scope: punctuation.section.group.end.c++ 892 pop: true 893 - include: function-trailing-return-type 894 895 ## Detection of function and data structure definitions at the global level 896 897 global-modifier: 898 - include: comments 899 - include: modifiers-parens 900 - include: modifiers 901 # Constructors and destructors don't have a type 902 - match: '(?={{path_lookahead}}\s*(?:{{generic_lookahead}})?\s*::\s*{{identifier}}\s*\()' 903 set: 904 - meta_content_scope: meta.function.c++ meta.toc-list.full-identifier.c++ 905 - include: identifier-path-generic 906 - match: '(?:(::)\s*)?({{identifier}})' 907 captures: 908 1: punctuation.accessor.double-colon.c++ 909 2: entity.name.function.constructor.c++ 910 - match: '(?=[^\w\s])' 911 set: function-definition-params 912 - match: '(?={{path_lookahead}}\s*(?:{{generic_lookahead}})?\s*::\s*~{{identifier}}\s*(\(|$))' 913 set: 914 - meta_content_scope: meta.function.c++ meta.toc-list.full-identifier.c++ 915 - include: identifier-path-generic 916 - match: '(?:(::)\s*)?(~{{identifier}})' 917 captures: 918 1: punctuation.accessor.double-colon.c++ 919 2: entity.name.function.destructor.c++ 920 - match: '(?=[^\w\s])' 921 set: function-definition-params 922 # If we see a path ending in :: before a newline, we don't know if it is 923 # a constructor or destructor, or a long return type, so we are just going 924 # to treat it like a regular function. Most likely it is a constructor, 925 # since it doesn't seem most developers would create such a long typename. 926 - match: '(?={{path_lookahead}}\s*(?:{{generic_lookahead}})?::\s*$)' 927 set: 928 - meta_content_scope: meta.function.c++ meta.toc-list.full-identifier.c++ 929 - include: identifier-path-generic 930 - match: '(::)\s*$' 931 captures: 932 1: punctuation.accessor.double-colon.c++ 933 - match: '(?:(::)\s*)?(~?{{identifier}})(?=\s*\()' 934 captures: 935 1: punctuation.accessor.double-colon.c++ 936 2: entity.name.function.c++ 937 - match: '(?=[^\w\s])' 938 set: function-definition-params 939 - include: unique-strings 940 - match: '(?=\S)' 941 set: global-type 942 943 global-type: 944 - include: comments 945 - match: \*|& 946 scope: keyword.operator.c++ 947 - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}}|operator)\b)' 948 pop: true 949 - match: '(?=\s)' 950 set: global-maybe-function 951 # If a class/struct/enum followed by a name that is not a macro or declspec 952 # then this is likely a return type of a function. This is uncommon. 953 - match: |- 954 (?x: 955 ({{before_tag}}) 956 \s+ 957 (?= 958 (?![[:upper:][:digit:]_]+\b|__declspec|{{before_tag}}) 959 {{path_lookahead}} 960 (\s+{{identifier}}\s*\(|\s*[*&]) 961 ) 962 ) 963 captures: 964 1: storage.type.c++ 965 set: 966 - include: identifiers 967 - match: '' 968 set: global-maybe-function 969 # The previous match handles return types of struct/enum/etc from a func, 970 # there this one exits the context to allow matching an actual struct/class 971 - match: '(?=\b({{before_tag}})\b)' 972 set: data-structures 973 - match: '(?=\b({{casts}})\b\s*<)' 974 pop: true 975 - match: '{{non_angle_brackets}}' 976 pop: true 977 - include: angle-brackets 978 - include: types 979 # Allow a macro call 980 - match: '({{identifier}})\s*(\()(?=[^\)]+\))' 981 captures: 982 1: variable.function.c++ 983 2: meta.group.c++ punctuation.section.group.begin.c++ 984 push: 985 - meta_scope: meta.function-call.c++ 986 - meta_content_scope: meta.group.c++ 987 - match: '\)' 988 scope: meta.group.c++ punctuation.section.group.end.c++ 989 pop: true 990 - include: expressions 991 - match: '(?={{path_lookahead}}\s*\()' 992 set: 993 - include: function-call 994 - match: '' 995 pop: true 996 - include: variables 997 - include: constants 998 - include: identifiers 999 - match: (?=\W) 1000 pop: true 1001 1002 global-maybe-function: 1003 - include: comments 1004 # Consume pointer info, macros and any type info that was offset by macros 1005 - match: \*|& 1006 scope: keyword.operator.c++ 1007 - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}})\b)' 1008 pop: true 1009 - match: '\b({{type_qualifier}})\b' 1010 scope: storage.modifier.c++ 1011 - match: '{{non_angle_brackets}}' 1012 pop: true 1013 - include: angle-brackets 1014 - include: types 1015 - include: modifiers-parens 1016 - include: modifiers 1017 # All uppercase identifier just before a newline is most likely a macro 1018 - match: '[[:upper:][:digit:]_]+\s*$' 1019 # Operator overloading 1020 - match: '(?=({{path_lookahead}}\s*(?:{{generic_lookahead}})?::\s*)?{{operator_method_name}}\s*(\(|$))' 1021 set: 1022 - meta_content_scope: meta.function.c++ meta.toc-list.full-identifier.c++ 1023 - include: identifier-path-generic 1024 - match: '(?:(::)\s*)?({{operator_method_name}})(?=\s*\()' 1025 captures: 1026 1: punctuation.accessor.double-colon.c++ 1027 2: entity.name.function.c++ 1028 - match: '(?=\s*(\(|$))' 1029 set: function-definition-params 1030 # Identifier that is not the function name - likely a macro or type 1031 - match: '(?={{path_lookahead}}([ \t]+|[*&])(?!\s*(<|::|\(|$)))' 1032 push: 1033 - include: identifiers 1034 - match: '' 1035 pop: true 1036 # Real function definition 1037 - match: '(?={{path_lookahead}}({{generic_lookahead}}({{path_lookahead}})?)\s*(\(|$))' 1038 set: [function-definition-params, global-function-identifier-generic] 1039 - match: '(?={{path_lookahead}}\s*(\(|$))' 1040 set: [function-definition-params, global-function-identifier] 1041 - match: '(?={{path_lookahead}}\s*::\s*$)' 1042 set: [function-definition-params, global-function-identifier] 1043 - match: '(?=\S)' 1044 pop: true 1045 1046 global-function-identifier-generic: 1047 - meta_content_scope: meta.toc-list.full-identifier.c++ 1048 - include: identifier-path-generic 1049 - match: '(?:(::)\s*)?({{identifier}})(?=\s*(<.*>)?\s*\()' 1050 captures: 1051 1: punctuation.accessor.double-colon.c++ 1052 2: entity.name.function.c++ 1053 - match: '(?=\()' 1054 pop: true 1055 1056 global-function-identifier: 1057 - meta_content_scope: meta.toc-list.full-identifier.c++ 1058 - match: '(?:(::)\s*)?({{identifier}})(?!\s*(::))' 1059 captures: 1060 1: punctuation.accessor.double-colon.c++ 1061 2: entity.name.function.c++ 1062 - include: identifiers 1063 - match: '(?=\S)' 1064 pop: true 1065 1066 function-definition-params: 1067 - meta_content_scope: meta.function.c++ 1068 - include: comments 1069 - match: '(?=\()' 1070 set: 1071 - match: \( 1072 scope: meta.function.parameters.c++ meta.group.c++ punctuation.section.group.begin.c++ 1073 set: 1074 - meta_content_scope: meta.function.parameters.c++ meta.group.c++ 1075 - match : \) 1076 scope: punctuation.section.group.end.c++ 1077 set: function-definition-continue 1078 - match: '\bvoid\b' 1079 scope: storage.type.c++ 1080 - match: '{{identifier}}(?=\s*(\[|,|\)|=))' 1081 scope: variable.parameter.c++ 1082 - match: '=' 1083 scope: keyword.operator.assignment.c++ 1084 push: 1085 - match: '(?=,|\))' 1086 pop: true 1087 - include: expressions-minus-generic-type 1088 - include: scope:source.c#preprocessor-line-continuation 1089 - include: expressions-minus-generic-type 1090 - include: scope:source.c#preprocessor-line-continuation 1091 - match: (?=\S) 1092 pop: true 1093 1094 function-definition-continue: 1095 - meta_content_scope: meta.function.c++ 1096 - include: comments 1097 - match: '(?=;)' 1098 pop: true 1099 - match: '->' 1100 scope: punctuation.separator.c++ 1101 set: function-definition-trailing-return 1102 - include: function-specifiers 1103 - match: '=' 1104 scope: keyword.operator.assignment.c++ 1105 - match: '&' 1106 scope: keyword.operator.c++ 1107 - match: \b0\b 1108 scope: constant.numeric.integer.decimal.c++ 1109 - match: \b(default|delete)\b 1110 scope: storage.modifier.c++ 1111 - match: '(?=\{)' 1112 set: function-definition-body 1113 - match: '(?=\S)' 1114 pop: true 1115 1116 function-definition-trailing-return: 1117 - include: comments 1118 - match: '(?=;)' 1119 pop: true 1120 - match: '(?=\{)' 1121 set: function-definition-body 1122 - include: function-specifiers 1123 - include: function-trailing-return-type 1124 1125 function-definition-body: 1126 - meta_content_scope: meta.function.c++ meta.block.c++ 1127 - match: '\{' 1128 scope: punctuation.section.block.begin.c++ 1129 set: 1130 - meta_content_scope: meta.function.c++ meta.block.c++ 1131 - match: '\}' 1132 scope: meta.function.c++ meta.block.c++ punctuation.section.block.end.c++ 1133 pop: true 1134 - match: (?=^\s*#\s*(elif|else|endif)\b) 1135 pop: true 1136 - match: '(?=({{before_tag}})([^(;]+$|.*\{))' 1137 push: data-structures 1138 - include: statements 1139 1140 ## Data structures including classes, structs, unions and enums 1141 1142 data-structures: 1143 - match: '\bclass\b' 1144 scope: storage.type.c++ 1145 set: data-structures-class-definition 1146 # Detect variable type definitions using struct/enum/union followed by a tag 1147 - match: '\b({{before_tag}})(?=\s+{{path_lookahead}}\s+{{path_lookahead}}\s*[=;\[])' 1148 scope: storage.type.c++ 1149 - match: '\bstruct\b' 1150 scope: storage.type.c++ 1151 set: data-structures-struct-definition 1152 - match: '\benum(\s+(class|struct))?\b' 1153 scope: storage.type.c++ 1154 set: data-structures-enum-definition 1155 - match: '\bunion\b' 1156 scope: storage.type.c++ 1157 set: data-structures-union-definition 1158 - match: '(?=\S)' 1159 pop: true 1160 1161 preprocessor-workaround-eat-macro-before-identifier: 1162 # Handle macros so they aren't matched as the class name 1163 - match: ({{macro_identifier}})(?=\s+~?{{identifier}}) 1164 captures: 1165 1: meta.assumed-macro.c 1166 1167 data-structures-class-definition: 1168 - meta_scope: meta.class.c++ 1169 - include: data-structures-definition-common-begin 1170 - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' 1171 scope: entity.name.class.forward-decl.c++ 1172 set: data-structures-class-definition-after-identifier 1173 - match: '(?={{path_lookahead}})' 1174 set: 1175 - meta_scope: meta.class.c++ 1176 - match: '{{identifier}}(?!\s*::)' 1177 scope: entity.name.class.c++ 1178 set: data-structures-class-definition-after-identifier 1179 - include: identifiers 1180 - match: '(?=[^\w\s])' 1181 set: data-structures-class-definition-after-identifier 1182 - match: '(?=[:{])' 1183 set: data-structures-class-definition-after-identifier 1184 - match: '(?=;)' 1185 pop: true 1186 1187 data-structures-class-definition-after-identifier: 1188 - meta_content_scope: meta.class.c++ 1189 - include: data-structures-definition-common-begin 1190 # No matching of identifiers since they should all be macros at this point 1191 - include: data-structures-definition-common-end 1192 - match: '\{' 1193 scope: meta.block.c++ punctuation.section.block.begin.c++ 1194 set: 1195 - meta_content_scope: meta.class.c++ meta.block.c++ 1196 - match: '\}' 1197 scope: meta.class.c++ meta.block.c++ punctuation.section.block.end.c++ 1198 pop: true 1199 - include: data-structures-body 1200 1201 data-structures-struct-definition: 1202 - meta_scope: meta.struct.c++ 1203 - include: data-structures-definition-common-begin 1204 - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' 1205 scope: entity.name.struct.forward-decl.c++ 1206 set: data-structures-struct-definition-after-identifier 1207 - match: '(?={{path_lookahead}})' 1208 set: 1209 - meta_scope: meta.struct.c++ 1210 - match: '{{identifier}}(?!\s*::)' 1211 scope: entity.name.struct.c++ 1212 set: data-structures-struct-definition-after-identifier 1213 - include: identifiers 1214 - match: '(?=[^\w\s])' 1215 set: data-structures-struct-definition-after-identifier 1216 - match: '(?=[:{])' 1217 set: data-structures-struct-definition-after-identifier 1218 - match: '(?=;)' 1219 pop: true 1220 1221 data-structures-struct-definition-after-identifier: 1222 - meta_content_scope: meta.struct.c++ 1223 - include: data-structures-definition-common-begin 1224 # No matching of identifiers since they should all be macros at this point 1225 - include: data-structures-definition-common-end 1226 - match: '\{' 1227 scope: meta.block.c++ punctuation.section.block.begin.c++ 1228 set: 1229 - meta_content_scope: meta.struct.c++ meta.block.c++ 1230 - match: '\}' 1231 scope: meta.struct.c++ meta.block.c++ punctuation.section.block.end.c++ 1232 pop: true 1233 - include: data-structures-body 1234 1235 data-structures-enum-definition: 1236 - meta_scope: meta.enum.c++ 1237 - include: data-structures-definition-common-begin 1238 - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' 1239 scope: entity.name.enum.forward-decl.c++ 1240 set: data-structures-enum-definition-after-identifier 1241 - match: '(?={{path_lookahead}})' 1242 set: 1243 - meta_scope: meta.enum.c++ 1244 - match: '{{identifier}}(?!\s*::)' 1245 scope: entity.name.enum.c++ 1246 set: data-structures-enum-definition-after-identifier 1247 - include: identifiers 1248 - match: '(?=[^\w\s])' 1249 set: data-structures-enum-definition-after-identifier 1250 - match: '(?=[:{])' 1251 set: data-structures-enum-definition-after-identifier 1252 - match: '(?=;)' 1253 pop: true 1254 1255 data-structures-enum-definition-after-identifier: 1256 - meta_content_scope: meta.enum.c++ 1257 - include: data-structures-definition-common-begin 1258 # No matching of identifiers since they should all be macros at this point 1259 - include: data-structures-definition-common-end 1260 - match: '\{' 1261 scope: meta.block.c++ punctuation.section.block.begin.c++ 1262 set: 1263 - meta_content_scope: meta.enum.c++ meta.block.c++ 1264 # Enums don't support methods so we have a simplified body 1265 - match: '\}' 1266 scope: meta.enum.c++ meta.block.c++ punctuation.section.block.end.c++ 1267 pop: true 1268 - include: statements 1269 1270 data-structures-union-definition: 1271 - meta_scope: meta.union.c++ 1272 - include: data-structures-definition-common-begin 1273 - match: '{{identifier}}(?={{data_structures_forward_decl_lookahead}})' 1274 scope: entity.name.union.forward-decl.c++ 1275 set: data-structures-union-definition-after-identifier 1276 - match: '(?={{path_lookahead}})' 1277 set: 1278 - meta_scope: meta.union.c++ 1279 - match: '{{identifier}}(?!\s*::)' 1280 scope: entity.name.union.c++ 1281 set: data-structures-union-definition-after-identifier 1282 - include: identifiers 1283 - match: '(?=[^\w\s])' 1284 set: data-structures-union-definition-after-identifier 1285 - match: '(?=[{])' 1286 set: data-structures-union-definition-after-identifier 1287 - match: '(?=;)' 1288 pop: true 1289 1290 data-structures-union-definition-after-identifier: 1291 - meta_content_scope: meta.union.c++ 1292 - include: data-structures-definition-common-begin 1293 # No matching of identifiers since they should all be macros at this point 1294 # Unions don't support base classes 1295 - include: angle-brackets 1296 - match: '\{' 1297 scope: meta.block.c++ punctuation.section.block.begin.c++ 1298 set: 1299 - meta_content_scope: meta.union.c++ meta.block.c++ 1300 - match: '\}' 1301 scope: meta.union.c++ meta.block.c++ punctuation.section.block.end.c++ 1302 pop: true 1303 - include: data-structures-body 1304 - match: '(?=;)' 1305 pop: true 1306 1307 data-structures-definition-common-begin: 1308 - include: comments 1309 - match: '(?=\b(?:{{before_tag}}|{{control_keywords}})\b)' 1310 pop: true 1311 - include: preprocessor-other 1312 - include: modifiers-parens 1313 - include: modifiers 1314 - include: preprocessor-workaround-eat-macro-before-identifier 1315 1316 data-structures-definition-common-end: 1317 - include: angle-brackets 1318 - match: \bfinal\b 1319 scope: storage.modifier.c++ 1320 - match: ':' 1321 scope: punctuation.separator.c++ 1322 push: 1323 - include: comments 1324 - include: preprocessor-other 1325 - include: modifiers-parens 1326 - include: modifiers 1327 - match: '\b(virtual|{{visibility_modifiers}})\b' 1328 scope: storage.modifier.c++ 1329 - match: (?={{path_lookahead}}) 1330 push: 1331 - meta_scope: entity.other.inherited-class.c++ 1332 - include: identifiers 1333 - match: '' 1334 pop: true 1335 - include: angle-brackets 1336 - match: ',' 1337 scope: punctuation.separator.c++ 1338 - match: (?=\{|;) 1339 pop: true 1340 - match: '(?=;)' 1341 pop: true 1342 1343 data-structures-body: 1344 - include: preprocessor-data-structures 1345 - match: '(?=\btemplate\b)' 1346 push: 1347 - include: template 1348 - match: (?=\S) 1349 set: data-structures-modifier 1350 - include: using-namespace 1351 - include: typedef 1352 - include: using-alias 1353 - match: \b({{visibility_modifiers}})\s*(:)(?!:) 1354 captures: 1355 1: storage.modifier.c++ 1356 2: punctuation.section.class.c++ 1357 - match: '^\s*(?=(?:~?\w+|::))' 1358 push: data-structures-modifier 1359 - include: expressions-minus-generic-type 1360 1361 data-structures-modifier-friend: 1362 - match: (?=;) 1363 pop: true 1364 - match: '\{' 1365 scope: punctuation.section.block.begin.c++ 1366 set: 1367 - meta_scope: meta.block.c++ 1368 - match: '\}' 1369 scope: punctuation.section.block.end.c++ 1370 pop: true 1371 - include: statements 1372 - include: expressions-minus-function-call 1373 1374 data-structures-modifier: 1375 - match: '\bfriend\b' 1376 scope: storage.modifier.c++ 1377 push: 1378 - include: comments 1379 - match: '\b({{before_tag}})\b' 1380 scope: storage.type.c++ 1381 set: data-structures-modifier-friend 1382 - match: '(?=\S)(?=[^;]+;)' 1383 set: data-structures-modifier-friend 1384 - match: '(?=\S)' 1385 pop: true 1386 - include: comments 1387 - include: modifiers-parens 1388 - include: modifiers 1389 - match: '\bstatic_assert(?=\s*\()' 1390 scope: meta.static-assert.c++ keyword.operator.word.c++ 1391 push: 1392 - match: '\(' 1393 scope: meta.group.c++ punctuation.section.group.begin.c++ 1394 set: 1395 - meta_content_scope: meta.function-call.c++ meta.group.c++ 1396 - match: '\)' 1397 scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ 1398 pop: true 1399 - include: expressions 1400 # Destructor 1401 - match: '(?:{{identifier}}\s*(::)\s*)?~{{identifier}}(?=\s*(\(|$))' 1402 scope: meta.method.destructor.c++ entity.name.function.destructor.c++ 1403 captures: 1404 1: punctuation.accessor.c++ 1405 set: method-definition-params 1406 # It's a macro, not a constructor if there is no type in the first param 1407 - match: '({{identifier}})\s*(\()(?=\s*(?!void){{identifier}}\s*[),])' 1408 captures: 1409 1: variable.function.c++ 1410 2: meta.group.c++ punctuation.section.group.begin.c++ 1411 push: 1412 - meta_scope: meta.function-call.c++ 1413 - meta_content_scope: meta.group.c++ 1414 - match: '\)' 1415 scope: meta.group.c++ punctuation.section.group.end.c++ 1416 pop: true 1417 - include: expressions 1418 # Constructor 1419 - include: preprocessor-workaround-eat-macro-before-identifier 1420 - match: '((?!{{before_tag}}|template){{identifier}})(?=\s*\()' 1421 scope: meta.method.constructor.c++ entity.name.function.constructor.c++ 1422 set: method-definition-params 1423 # Long form constructor 1424 - match: '({{identifier}}\s*(::)\s*{{identifier}})(?=\s*\()' 1425 captures: 1426 1: meta.method.constructor.c++ entity.name.function.constructor.c++ 1427 2: punctuation.accessor.c++ 1428 push: method-definition-params 1429 - match: '(?=\S)' 1430 set: data-structures-type 1431 1432 data-structures-type: 1433 - include: comments 1434 - match: \*|& 1435 scope: keyword.operator.c++ 1436 # Cast methods 1437 - match: '(operator)\s+({{identifier}})(?=\s*(\(|$))' 1438 captures: 1439 1: keyword.control.c++ 1440 2: meta.method.c++ entity.name.function.c++ 1441 set: method-definition-params 1442 - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}}|operator)\b)' 1443 pop: true 1444 - match: '(?=\s)' 1445 set: data-structures-maybe-method 1446 # If a class/struct/enum followed by a name that is not a macro or declspec 1447 # then this is likely a return type of a function. This is uncommon. 1448 - match: |- 1449 (?x: 1450 ({{before_tag}}) 1451 \s+ 1452 (?= 1453 (?![[:upper:][:digit:]_]+\b|__declspec|{{before_tag}}) 1454 {{path_lookahead}} 1455 (\s+{{identifier}}\s*\(|\s*[*&]) 1456 ) 1457 ) 1458 captures: 1459 1: storage.type.c++ 1460 set: 1461 - include: identifiers 1462 - match: '' 1463 set: data-structures-maybe-method 1464 # The previous match handles return types of struct/enum/etc from a func, 1465 # there this one exits the context to allow matching an actual struct/class 1466 - match: '(?=\b({{before_tag}})\b)' 1467 set: data-structures 1468 - match: '(?=\b({{casts}})\b\s*<)' 1469 pop: true 1470 - match: '{{non_angle_brackets}}' 1471 pop: true 1472 - include: angle-brackets 1473 - include: types 1474 - include: variables 1475 - include: constants 1476 - include: identifiers 1477 - match: (?=[&*]) 1478 set: data-structures-maybe-method 1479 - match: (?=\W) 1480 pop: true 1481 1482 data-structures-maybe-method: 1483 - include: comments 1484 # Consume pointer info, macros and any type info that was offset by macros 1485 - match: \*|& 1486 scope: keyword.operator.c++ 1487 - match: '(?=\b({{control_keywords}}|{{operator_keywords}}|{{casts}}|{{memory_operators}}|{{other_keywords}})\b)' 1488 pop: true 1489 - match: '\b({{type_qualifier}})\b' 1490 scope: storage.modifier.c++ 1491 - match: '{{non_angle_brackets}}' 1492 pop: true 1493 - include: angle-brackets 1494 - include: types 1495 - include: modifiers-parens 1496 - include: modifiers 1497 # Operator overloading 1498 - match: '{{operator_method_name}}(?=\s*(\(|$))' 1499 scope: meta.method.c++ entity.name.function.c++ 1500 set: method-definition-params 1501 # Identifier that is not the function name - likely a macro or type 1502 - match: '(?={{path_lookahead}}([ \t]+|[*&])(?!\s*(<|::|\()))' 1503 push: 1504 - include: identifiers 1505 - match: '' 1506 pop: true 1507 # Real function definition 1508 - match: '(?={{path_lookahead}}({{generic_lookahead}})\s*(\())' 1509 set: [method-definition-params, data-structures-function-identifier-generic] 1510 - match: '(?={{path_lookahead}}\s*(\())' 1511 set: [method-definition-params, data-structures-function-identifier] 1512 - match: '(?={{path_lookahead}}\s*::\s*$)' 1513 set: [method-definition-params, data-structures-function-identifier] 1514 - match: '(?=\S)' 1515 pop: true 1516 1517 data-structures-function-identifier-generic: 1518 - include: angle-brackets 1519 - match: '(?={{identifier}})' 1520 push: 1521 - meta_content_scope: entity.name.function.c++ 1522 - include: identifiers 1523 - match: '(?=<)' 1524 pop: true 1525 - match: '(?=\()' 1526 pop: true 1527 1528 data-structures-function-identifier: 1529 - meta_content_scope: entity.name.function.c++ 1530 - include: identifiers 1531 - match: '(?=\S)' 1532 pop: true 1533 1534 method-definition-params: 1535 - meta_content_scope: meta.method.c++ 1536 - include: comments 1537 - match: '(?=\()' 1538 set: 1539 - match: \( 1540 scope: meta.method.parameters.c++ meta.group.c++ punctuation.section.group.begin.c++ 1541 set: 1542 - meta_content_scope: meta.method.parameters.c++ meta.group.c++ 1543 - match : \) 1544 scope: punctuation.section.group.end.c++ 1545 set: method-definition-continue 1546 - match: '\bvoid\b' 1547 scope: storage.type.c++ 1548 - match: '{{identifier}}(?=\s*(\[|,|\)|=))' 1549 scope: variable.parameter.c++ 1550 - match: '=' 1551 scope: keyword.operator.assignment.c++ 1552 push: 1553 - match: '(?=,|\))' 1554 pop: true 1555 - include: expressions-minus-generic-type 1556 - include: expressions-minus-generic-type 1557 - match: '(?=\S)' 1558 pop: true 1559 1560 method-definition-continue: 1561 - meta_content_scope: meta.method.c++ 1562 - include: comments 1563 - match: '(?=;)' 1564 pop: true 1565 - match: '->' 1566 scope: punctuation.separator.c++ 1567 set: method-definition-trailing-return 1568 - include: function-specifiers 1569 - match: '=' 1570 scope: keyword.operator.assignment.c++ 1571 - match: '&' 1572 scope: keyword.operator.c++ 1573 - match: \b0\b 1574 scope: constant.numeric.integer.decimal.c++ 1575 - match: \b(default|delete)\b 1576 scope: storage.modifier.c++ 1577 - match: '(?=:)' 1578 set: 1579 - match: ':' 1580 scope: punctuation.separator.initializer-list.c++ 1581 set: 1582 - meta_scope: meta.method.constructor.initializer-list.c++ 1583 - match: '{{identifier}}' 1584 scope: variable.other.readwrite.member.c++ 1585 push: 1586 - match: \( 1587 scope: meta.group.c++ punctuation.section.group.begin.c++ 1588 set: 1589 - meta_content_scope: meta.group.c++ 1590 - match: \) 1591 scope: meta.group.c++ punctuation.section.group.end.c++ 1592 pop: true 1593 - include: expressions 1594 - match: \{ 1595 scope: meta.group.c++ punctuation.section.group.begin.c++ 1596 set: 1597 - meta_content_scope: meta.group.c++ 1598 - match: \} 1599 scope: meta.group.c++ punctuation.section.group.end.c++ 1600 pop: true 1601 - include: expressions 1602 - include: comments 1603 - match: (?=\{|;) 1604 set: method-definition-continue 1605 - include: expressions 1606 - match: '(?=\{)' 1607 set: method-definition-body 1608 - match: '(?=\S)' 1609 pop: true 1610 1611 method-definition-trailing-return: 1612 - include: comments 1613 - match: '(?=;)' 1614 pop: true 1615 - match: '(?=\{)' 1616 set: method-definition-body 1617 - include: function-specifiers 1618 - include: function-trailing-return-type 1619 1620 method-definition-body: 1621 - meta_content_scope: meta.method.c++ meta.block.c++ 1622 - match: '\{' 1623 scope: punctuation.section.block.begin.c++ 1624 set: 1625 - meta_content_scope: meta.method.c++ meta.block.c++ 1626 - match: '\}' 1627 scope: meta.method.c++ meta.block.c++ punctuation.section.block.end.c++ 1628 pop: true 1629 - match: (?=^\s*#\s*(elif|else|endif)\b) 1630 pop: true 1631 - match: '(?=({{before_tag}})([^(;]+$|.*\{))' 1632 push: data-structures 1633 - include: statements 1634 1635 ## Preprocessor for data-structures 1636 1637 preprocessor-data-structures: 1638 - include: preprocessor-rule-enabled-data-structures 1639 - include: preprocessor-rule-disabled-data-structures 1640 - include: preprocessor-practical-workarounds 1641 1642 preprocessor-rule-disabled-data-structures: 1643 - match: ^\s*((#if)\s+(0))\b 1644 captures: 1645 1: meta.preprocessor.c++ 1646 2: keyword.control.import.c++ 1647 3: constant.numeric.integer.decimal.c++ 1648 push: 1649 - match: ^\s*(#\s*endif)\b 1650 captures: 1651 1: meta.preprocessor.c++ keyword.control.import.c++ 1652 pop: true 1653 - match: ^\s*(#\s*else)\b 1654 captures: 1655 1: meta.preprocessor.c++ keyword.control.import.else.c++ 1656 push: 1657 - match: (?=^\s*#\s*endif\b) 1658 pop: true 1659 - include: negated-block 1660 - include: data-structures-body 1661 - match: "" 1662 push: 1663 - meta_scope: comment.block.preprocessor.if-branch.c++ 1664 - match: (?=^\s*#\s*(else|endif)\b) 1665 pop: true 1666 - include: scope:source.c#preprocessor-disabled 1667 1668 preprocessor-rule-enabled-data-structures: 1669 - match: ^\s*((#if)\s+(0*1))\b 1670 captures: 1671 1: meta.preprocessor.c++ 1672 2: keyword.control.import.c++ 1673 3: constant.numeric.integer.decimal.c++ 1674 push: 1675 - match: ^\s*(#\s*endif)\b 1676 captures: 1677 1: meta.preprocessor.c++ keyword.control.import.c++ 1678 pop: true 1679 - match: ^\s*(#\s*else)\b 1680 captures: 1681 1: meta.preprocessor.c++ keyword.control.import.else.c++ 1682 push: 1683 - meta_content_scope: comment.block.preprocessor.else-branch.c++ 1684 - match: (?=^\s*#\s*endif\b) 1685 pop: true 1686 - include: scope:source.c#preprocessor-disabled 1687 - match: "" 1688 push: 1689 - match: (?=^\s*#\s*(else|endif)\b) 1690 pop: true 1691 - include: negated-block 1692 - include: data-structures-body 1693 1694 ## Preprocessor for global 1695 1696 preprocessor-global: 1697 - include: preprocessor-rule-enabled-global 1698 - include: preprocessor-rule-disabled-global 1699 - include: preprocessor-rule-other-global 1700 1701 preprocessor-statements: 1702 - include: preprocessor-rule-enabled-statements 1703 - include: preprocessor-rule-disabled-statements 1704 - include: preprocessor-rule-other-statements 1705 1706 preprocessor-expressions: 1707 - include: scope:source.c#incomplete-inc 1708 - include: preprocessor-macro-define 1709 - include: scope:source.c#pragma-mark 1710 - include: preprocessor-other 1711 1712 preprocessor-rule-disabled-global: 1713 - match: ^\s*((#if)\s+(0))\b 1714 captures: 1715 1: meta.preprocessor.c++ 1716 2: keyword.control.import.c++ 1717 3: constant.numeric.integer.decimal.c++ 1718 push: 1719 - match: ^\s*(#\s*endif)\b 1720 captures: 1721 1: meta.preprocessor.c++ keyword.control.import.c++ 1722 pop: true 1723 - match: ^\s*(#\s*else)\b 1724 captures: 1725 1: meta.preprocessor.c++ keyword.control.import.else.c++ 1726 push: 1727 - match: (?=^\s*#\s*endif\b) 1728 pop: true 1729 - include: preprocessor-global 1730 - include: negated-block 1731 - include: global 1732 - match: "" 1733 push: 1734 - meta_scope: comment.block.preprocessor.if-branch.c++ 1735 - match: (?=^\s*#\s*(else|endif)\b) 1736 pop: true 1737 - include: scope:source.c#preprocessor-disabled 1738 1739 preprocessor-rule-enabled-global: 1740 - match: ^\s*((#if)\s+(0*1))\b 1741 captures: 1742 1: meta.preprocessor.c++ 1743 2: keyword.control.import.c++ 1744 3: constant.numeric.integer.decimal.c++ 1745 push: 1746 - match: ^\s*(#\s*endif)\b 1747 captures: 1748 1: meta.preprocessor.c++ keyword.control.import.c++ 1749 pop: true 1750 - match: ^\s*(#\s*else)\b 1751 captures: 1752 1: meta.preprocessor.c++ keyword.control.import.else.c++ 1753 push: 1754 - meta_content_scope: comment.block.preprocessor.else-branch.c++ 1755 - match: (?=^\s*#\s*endif\b) 1756 pop: true 1757 - include: scope:source.c#preprocessor-disabled 1758 - match: "" 1759 push: 1760 - match: (?=^\s*#\s*(else|endif)\b) 1761 pop: true 1762 - include: preprocessor-global 1763 - include: negated-block 1764 - include: global 1765 1766 preprocessor-rule-other-global: 1767 - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b 1768 captures: 1769 1: keyword.control.import.c++ 1770 push: 1771 - meta_scope: meta.preprocessor.c++ 1772 - include: scope:source.c#preprocessor-line-continuation 1773 - include: scope:source.c#preprocessor-comments 1774 - match: \bdefined\b 1775 scope: keyword.control.c++ 1776 # Enter a new scope where all elif/else branches have their 1777 # contexts popped by a subsequent elif/else/endif. This ensures that 1778 # preprocessor branches don't push multiple meta.block scopes on 1779 # the stack, thus messing up the "global" context's detection of 1780 # functions. 1781 - match: $\n 1782 set: preprocessor-if-branch-global 1783 1784 # These gymnastics here ensure that we are properly handling scope even 1785 # when the preprocessor is used to create different scope beginnings, such 1786 # as a different if/while condition 1787 preprocessor-if-branch-global: 1788 - match: ^\s*(#\s*endif)\b 1789 captures: 1790 1: meta.preprocessor.c++ keyword.control.import.c++ 1791 pop: true 1792 - match: (?=^\s*#\s*(elif|else)\b) 1793 push: preprocessor-elif-else-branch-global 1794 - match: \{ 1795 scope: punctuation.section.block.begin.c++ 1796 set: preprocessor-block-if-branch-global 1797 - include: preprocessor-global 1798 - include: negated-block 1799 - include: global 1800 1801 preprocessor-block-if-branch-global: 1802 - meta_scope: meta.block.c++ 1803 - match: ^\s*(#\s*endif)\b 1804 captures: 1805 1: meta.preprocessor.c++ keyword.control.import.c++ 1806 set: preprocessor-block-finish-global 1807 - match: (?=^\s*#\s*(elif|else)\b) 1808 push: preprocessor-elif-else-branch-global 1809 - match: \} 1810 scope: punctuation.section.block.end.c++ 1811 set: preprocessor-if-branch-global 1812 - include: statements 1813 1814 preprocessor-block-finish-global: 1815 - meta_scope: meta.block.c++ 1816 - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b 1817 captures: 1818 1: meta.preprocessor.c++ keyword.control.import.c++ 1819 set: preprocessor-block-finish-if-branch-global 1820 - match: \} 1821 scope: punctuation.section.block.end.c++ 1822 pop: true 1823 - include: statements 1824 1825 preprocessor-block-finish-if-branch-global: 1826 - match: ^\s*(#\s*endif)\b 1827 captures: 1828 1: keyword.control.import.c++ 1829 pop: true 1830 - match: \} 1831 scope: punctuation.section.block.end.c++ 1832 set: preprocessor-if-branch-global 1833 - include: statements 1834 1835 preprocessor-elif-else-branch-global: 1836 - match: (?=^\s*#\s*(endif)\b) 1837 pop: true 1838 - include: preprocessor-global 1839 - include: negated-block 1840 - include: global 1841 1842 ## Preprocessor for statements 1843 1844 preprocessor-rule-disabled-statements: 1845 - match: ^\s*((#if)\s+(0))\b 1846 captures: 1847 1: meta.preprocessor.c++ 1848 2: keyword.control.import.c++ 1849 3: constant.numeric.integer.decimal.c++ 1850 push: 1851 - match: ^\s*(#\s*endif)\b 1852 captures: 1853 1: meta.preprocessor.c++ keyword.control.import.c++ 1854 pop: true 1855 - match: ^\s*(#\s*else)\b 1856 captures: 1857 1: meta.preprocessor.c++ keyword.control.import.else.c++ 1858 push: 1859 - match: (?=^\s*#\s*endif\b) 1860 pop: true 1861 - include: negated-block 1862 - include: statements 1863 - match: "" 1864 push: 1865 - meta_scope: comment.block.preprocessor.if-branch.c++ 1866 - match: (?=^\s*#\s*(else|endif)\b) 1867 pop: true 1868 - include: scope:source.c#preprocessor-disabled 1869 1870 preprocessor-rule-enabled-statements: 1871 - match: ^\s*((#if)\s+(0*1))\b 1872 captures: 1873 1: meta.preprocessor.c++ 1874 2: keyword.control.import.c++ 1875 3: constant.numeric.integer.decimal.c++ 1876 push: 1877 - match: ^\s*(#\s*endif)\b 1878 captures: 1879 1: meta.preprocessor.c++ keyword.control.import.c++ 1880 pop: true 1881 - match: ^\s*(#\s*else)\b 1882 captures: 1883 1: meta.preprocessor.c++ keyword.control.import.else.c++ 1884 push: 1885 - meta_content_scope: comment.block.preprocessor.else-branch.c++ 1886 - match: (?=^\s*#\s*endif\b) 1887 pop: true 1888 - include: scope:source.c#preprocessor-disabled 1889 - match: "" 1890 push: 1891 - match: (?=^\s*#\s*(else|endif)\b) 1892 pop: true 1893 - include: negated-block 1894 - include: statements 1895 1896 preprocessor-rule-other-statements: 1897 - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b 1898 captures: 1899 1: keyword.control.import.c++ 1900 push: 1901 - meta_scope: meta.preprocessor.c++ 1902 - include: scope:source.c#preprocessor-line-continuation 1903 - include: scope:source.c#preprocessor-comments 1904 - match: \bdefined\b 1905 scope: keyword.control.c++ 1906 # Enter a new scope where all elif/else branches have their 1907 # contexts popped by a subsequent elif/else/endif. This ensures that 1908 # preprocessor branches don't push multiple meta.block scopes on 1909 # the stack, thus messing up the "global" context's detection of 1910 # functions. 1911 - match: $\n 1912 set: preprocessor-if-branch-statements 1913 1914 # These gymnastics here ensure that we are properly handling scope even 1915 # when the preprocessor is used to create different scope beginnings, such 1916 # as a different if/while condition 1917 preprocessor-if-branch-statements: 1918 - match: ^\s*(#\s*endif)\b 1919 captures: 1920 1: meta.preprocessor.c++ keyword.control.import.c++ 1921 pop: true 1922 - match: (?=^\s*#\s*(elif|else)\b) 1923 push: preprocessor-elif-else-branch-statements 1924 - match: \{ 1925 scope: punctuation.section.block.begin.c++ 1926 set: preprocessor-block-if-branch-statements 1927 - match: (?=(?!{{non_func_keywords}}){{path_lookahead}}\s*\() 1928 set: preprocessor-if-branch-function-call 1929 - include: negated-block 1930 - include: statements 1931 1932 preprocessor-if-branch-function-call: 1933 - meta_content_scope: meta.function-call.c++ 1934 - include: scope:source.c#c99 1935 - match: '(?:(::)\s*)?{{identifier}}\s*(::)\s*' 1936 scope: variable.function.c++ 1937 captures: 1938 1: punctuation.accessor.c++ 1939 2: punctuation.accessor.c++ 1940 - match: '(?:(::)\s*)?{{identifier}}' 1941 scope: variable.function.c++ 1942 captures: 1943 1: punctuation.accessor.c++ 1944 - match: '\(' 1945 scope: meta.group.c++ punctuation.section.group.begin.c++ 1946 set: preprocessor-if-branch-function-call-arguments 1947 1948 preprocessor-if-branch-function-call-arguments: 1949 - meta_content_scope: meta.function-call.c++ meta.group.c++ 1950 - match : \) 1951 scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ 1952 set: preprocessor-if-branch-statements 1953 - match: ^\s*(#\s*(?:elif|else))\b 1954 captures: 1955 1: meta.preprocessor.c++ keyword.control.import.c++ 1956 set: preprocessor-if-branch-statements 1957 - match: ^\s*(#\s*endif)\b 1958 captures: 1959 1: meta.preprocessor.c++ keyword.control.import.c++ 1960 set: preprocessor-if-branch-function-call-arguments-finish 1961 - include: expressions 1962 1963 preprocessor-if-branch-function-call-arguments-finish: 1964 - meta_content_scope: meta.function-call.c++ meta.group.c++ 1965 - match: \) 1966 scope: meta.function-call.c++ meta.group.c++ punctuation.section.group.end.c++ 1967 pop: true 1968 - include: expressions 1969 1970 preprocessor-block-if-branch-statements: 1971 - meta_scope: meta.block.c++ 1972 - match: ^\s*(#\s*endif)\b 1973 captures: 1974 1: meta.preprocessor.c++ keyword.control.import.c++ 1975 set: preprocessor-block-finish-statements 1976 - match: (?=^\s*#\s*(elif|else)\b) 1977 push: preprocessor-elif-else-branch-statements 1978 - match: \} 1979 scope: punctuation.section.block.end.c++ 1980 set: preprocessor-if-branch-statements 1981 - include: statements 1982 1983 preprocessor-block-finish-statements: 1984 - meta_scope: meta.block.c++ 1985 - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b 1986 captures: 1987 1: meta.preprocessor.c++ keyword.control.import.c++ 1988 set: preprocessor-block-finish-if-branch-statements 1989 - match: \} 1990 scope: punctuation.section.block.end.c++ 1991 pop: true 1992 - include: statements 1993 1994 preprocessor-block-finish-if-branch-statements: 1995 - match: ^\s*(#\s*endif)\b 1996 captures: 1997 1: keyword.control.import.c++ 1998 pop: true 1999 - match: \} 2000 scope: meta.block.c++ punctuation.section.block.end.c++ 2001 set: preprocessor-if-branch-statements 2002 - include: statements 2003 2004 preprocessor-elif-else-branch-statements: 2005 - match: (?=^\s*#\s*endif\b) 2006 pop: true 2007 - include: negated-block 2008 - include: statements 2009 2010 ## Preprocessor other 2011 2012 negated-block: 2013 - match: '\}' 2014 scope: punctuation.section.block.end.c++ 2015 push: 2016 - match: '\{' 2017 scope: punctuation.section.block.begin.c++ 2018 pop: true 2019 - match: (?=^\s*#\s*(elif|else|endif)\b) 2020 pop: true 2021 - include: statements 2022 2023 preprocessor-macro-define: 2024 - match: ^\s*(\#\s*define)\b 2025 captures: 2026 1: meta.preprocessor.macro.c++ keyword.control.import.define.c++ 2027 push: 2028 - meta_content_scope: meta.preprocessor.macro.c++ 2029 - include: scope:source.c#preprocessor-line-continuation 2030 - include: scope:source.c#preprocessor-line-ending 2031 - include: scope:source.c#preprocessor-comments 2032 - match: '({{identifier}})(?=\()' 2033 scope: entity.name.function.preprocessor.c++ 2034 set: 2035 - match: '\(' 2036 scope: punctuation.section.group.begin.c++ 2037 set: preprocessor-macro-params 2038 - match: '{{identifier}}' 2039 scope: entity.name.constant.preprocessor.c++ 2040 set: preprocessor-macro-definition 2041 2042 preprocessor-macro-params: 2043 - meta_scope: meta.preprocessor.macro.parameters.c++ meta.group.c++ 2044 - match: '{{identifier}}' 2045 scope: variable.parameter.c++ 2046 - match: \) 2047 scope: punctuation.section.group.end.c++ 2048 set: preprocessor-macro-definition 2049 - match: ',' 2050 scope: punctuation.separator.c++ 2051 push: 2052 - match: '{{identifier}}' 2053 scope: variable.parameter.c++ 2054 pop: true 2055 - include: scope:source.c#preprocessor-line-continuation 2056 - include: scope:source.c#preprocessor-comments 2057 - match: '\.\.\.' 2058 scope: keyword.operator.variadic.c++ 2059 - match: '(?=\))' 2060 pop: true 2061 - match: (/\*).*(\*/) 2062 scope: comment.block.c++ 2063 captures: 2064 1: punctuation.definition.comment.c++ 2065 2: punctuation.definition.comment.c++ 2066 - match: '\S+' 2067 scope: invalid.illegal.unexpected-character.c++ 2068 - include: scope:source.c#preprocessor-line-continuation 2069 - include: scope:source.c#preprocessor-comments 2070 - match: '\.\.\.' 2071 scope: keyword.operator.variadic.c++ 2072 - match: (/\*).*(\*/) 2073 scope: comment.block.c++ 2074 captures: 2075 1: punctuation.definition.comment.c++ 2076 2: punctuation.definition.comment.c++ 2077 - match: $\n 2078 scope: invalid.illegal.unexpected-end-of-line.c++ 2079 2080 preprocessor-macro-definition: 2081 - meta_content_scope: meta.preprocessor.macro.c++ 2082 - include: scope:source.c#preprocessor-line-continuation 2083 - include: scope:source.c#preprocessor-line-ending 2084 - include: scope:source.c#preprocessor-comments 2085 # Don't define blocks in define statements 2086 - match: '\{' 2087 scope: punctuation.section.block.begin.c++ 2088 - match: '\}' 2089 scope: punctuation.section.block.end.c++ 2090 # Captures the namespace macro idiom 2091 - match: '\b(namespace)\s+(?={{path_lookahead}}\s*\{)' 2092 scope: meta.namespace.c++ 2093 captures: 2094 1: keyword.control.c++ 2095 push: 2096 - meta_content_scope: meta.namespace.c++ entity.name.namespace.c++ 2097 - include: identifiers 2098 - match: '(?=\S)' 2099 pop: true 2100 - include: expressions 2101 2102 preprocessor-practical-workarounds: 2103 - include: preprocessor-convention-ignore-uppercase-ident-lines 2104 - include: scope:source.c#preprocessor-convention-ignore-uppercase-calls-without-semicolon 2105 2106 preprocessor-convention-ignore-uppercase-ident-lines: 2107 - match: ^(\s*{{macro_identifier}})+\s*$ 2108 scope: meta.assumed-macro.c++ 2109 push: 2110 # It's possible that we are dealing with a function return type on its own line, and the 2111 # name of the function is on the subsequent line. 2112 - match: '(?={{path_lookahead}}({{generic_lookahead}}({{path_lookahead}})?)\s*\()' 2113 set: [function-definition-params, global-function-identifier-generic] 2114 - match: '(?={{path_lookahead}}\s*\()' 2115 set: [function-definition-params, global-function-identifier] 2116 - match: ^ 2117 pop: true 2118 2119 preprocessor-other: 2120 - match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|else|line|pragma|undef))\b 2121 captures: 2122 1: keyword.control.import.c++ 2123 push: 2124 - meta_scope: meta.preprocessor.c++ 2125 - include: scope:source.c#preprocessor-line-continuation 2126 - include: scope:source.c#preprocessor-line-ending 2127 - include: scope:source.c#preprocessor-comments 2128 - match: \bdefined\b 2129 scope: keyword.control.c++ 2130 - match: ^\s*(#\s*endif)\b 2131 captures: 2132 1: meta.preprocessor.c++ keyword.control.import.c++ 2133 - match: ^\s*(#\s*(?:error|warning))\b 2134 captures: 2135 1: keyword.control.import.error.c++ 2136 push: 2137 - meta_scope: meta.preprocessor.diagnostic.c++ 2138 - include: scope:source.c#preprocessor-line-continuation 2139 - include: scope:source.c#preprocessor-line-ending 2140 - include: scope:source.c#preprocessor-comments 2141 - include: strings 2142 - match: '\S+' 2143 scope: string.unquoted.c++ 2144 - match: ^\s*(#\s*(?:include|include_next|import))\b 2145 captures: 2146 1: keyword.control.import.include.c++ 2147 push: 2148 - meta_scope: meta.preprocessor.include.c++ 2149 - include: scope:source.c#preprocessor-line-continuation 2150 - include: scope:source.c#preprocessor-line-ending 2151 - include: scope:source.c#preprocessor-comments 2152 - match: '"' 2153 scope: punctuation.definition.string.begin.c++ 2154 push: 2155 - meta_scope: string.quoted.double.include.c++ 2156 - match: '"' 2157 scope: punctuation.definition.string.end.c++ 2158 pop: true 2159 - match: < 2160 scope: punctuation.definition.string.begin.c++ 2161 push: 2162 - meta_scope: string.quoted.other.lt-gt.include.c++ 2163 - match: '>' 2164 scope: punctuation.definition.string.end.c++ 2165 pop: true 2166 - include: preprocessor-practical-workarounds