diff --git a/C++/C++.sublime-syntax b/C++/C++.sublime-syntax index 79a7584329..0e2900bace 100644 --- a/C++/C++.sublime-syntax +++ b/C++/C++.sublime-syntax @@ -86,6 +86,12 @@ variables: data_structures_forward_decl_lookahead: '(\s+{{macro_identifier}})*\s*(:\s*({{path_lookahead}}|{{visibility_modifiers}}|,|\s|<[^;]*>)+)?;' non_func_keywords: 'if|for|switch|while|decltype|sizeof|__declspec|__attribute__|typeid|alignof|alignas|static_assert' + attribute_token: '({{identifier}}|{{identifier}}::{{identifier}}|{{identifier}}\(.*\)|{{identifier}}::{{identifier}}\(.*\))' + attribute_list: '({{attribute_token}}|({{attribute_token}},\s*)+({{attribute_token}}|\.\.\.))' + attribute_namespace_list: '(using\s+{{identifier}}:\s*{{attribute_list}})' + attribute_body: '{{attribute_list}}|{{attribute_namespace_list}}' + + contexts: main: - include: preprocessor-global @@ -309,7 +315,7 @@ contexts: - include: global - match: (?=\S) set: global-modifier - - match: ^\s*(?=\w) + - match: ^\s*(?=(\w|\[\[{{attribute_body}}\]\])) push: global-modifier - include: late-expressions @@ -447,7 +453,40 @@ contexts: operators: - include: scope:source.c#operators + attribute_list: + - meta_scope: meta.attribute.c++ + - match: '\b(noreturn|carries_dependency|deprecated|fallthrough|maybe_unused|nodiscard|likely|unlikely|no_unique_address|assume|indeterminate)\b' + scope: storage.modifier.c++ + - include: parens + - match: ',' + scope: punctuation.separator.c++ + - match: '\.\.\.' + scope: keyword.operator.variadic.c++ + - match: \]\] + scope: punctuation.section.attribute.end.c++ + pop: true + + attributes: + - match: '\[\[(?={{attribute_namespace_list}}\]\])' + scope: punctuation.section.attribute.begin.c++ + push: + - meta_scope: meta.attribute.c++ + - match: 'using' + scope: keyword.control.c++ + push: + - match: '{{identifier}}' + push: + - match: ':' + scope: punctuation.separator.c++ + pop: 2 + - match: (?=) + set: attribute_list + - match: '\[\[(?={{attribute_list}}\]\])' + scope: punctuation.section.attribute.begin.c++ + push: attribute_list + modifiers: + - include: attributes - include: unique-modifiers - include: scope:source.c#modifiers @@ -1031,7 +1070,7 @@ contexts: - include: expressions brackets: - - match: \[ + - match: \[(?!\[{{attribute_body}}\]\]) scope: punctuation.section.brackets.begin.c++ push: - meta_scope: meta.brackets.c++ @@ -1553,7 +1592,7 @@ contexts: captures: 1: storage.modifier.c++ 2: punctuation.section.class.c++ - - match: '^\s*(?=(?:~?\w+|::))' + - match: '^\s*(?=(?:~?\w+|::|\[\[{{attribute_body}}\]\]))' push: data-structures-modifier - include: expressions-minus-generic-type diff --git a/C++/C.sublime-syntax b/C++/C.sublime-syntax index 94d543cf68..d83cefdef9 100644 --- a/C++/C.sublime-syntax +++ b/C++/C.sublime-syntax @@ -60,6 +60,9 @@ variables: modifiers: '{{storage_classes}}|{{type_qualifier}}|{{compiler_directive}}' non_func_keywords: 'if|for|switch|while|decltype|typeof|typeof_unqual|_Atomic|_BitInt|sizeof|alignof|_Alignof|alignas|_Alignas|static_assert|_Static_assert|__declspec|__attribute__' + attribute_token: '({{identifier}}|{{identifier}}::{{identifier}}|{{identifier}}\(.*\)|{{identifier}}::{{identifier}}\(.*\))' + attribute_list: '({{attribute_token}}|({{attribute_token}},\s*)+{{attribute_token}})' + contexts: main: - include: preprocessor-global @@ -231,9 +234,24 @@ contexts: - match: \b(sizeof|alignof|_Alignof|static_assert|_Static_assert)\b scope: keyword.operator.word.c + attributes: + - match: '\[\[(?={{attribute_list}}\]\])' + scope: punctuation.section.attribute.begin.c + push: + - meta_scope: meta.attribute.c + - match: '\b(deprecated|__deprecated__|fallthrough|__fallthrough__|nodiscard|__nodiscard__|maybe_unused|__maybe_unused__|noreturn|__noreturn__|unsequenced|__unsequenced__|reproducible|__reproducible__)\b' + scope: storage.modifier.c + - match: ',' + scope: punctuation.separator.c + - include: parens + - match: \]\] + scope: punctuation.section.attribute.end.c + pop: true + modifiers: - match: \b({{modifiers}})\b scope: storage.modifier.c + - include: attributes variables: - match: '\bg[A-Z]\w*\b' @@ -524,7 +542,7 @@ contexts: global: - include: early-expressions - - match: '^\s*(?=\w+)' + - match: '^\s*(?=\w+|\[\[{{attribute_list}}\]\])' push: global-modifier - include: late-expressions @@ -884,7 +902,7 @@ contexts: - include: expressions brackets: - - match: \[ + - match: \[(?!\[{{attribute_list}}\]\]) scope: punctuation.section.brackets.begin.c push: - meta_scope: meta.brackets.c diff --git a/C++/syntax_test_c.c b/C++/syntax_test_c.c index 0a4840f6cb..8da887715c 100644 --- a/C++/syntax_test_c.c +++ b/C++/syntax_test_c.c @@ -1151,6 +1151,40 @@ __notdeclspec(deprecated("bla")) void func2(int) {} /* <- meta.function-call variable.function */ /* ^ entity.name.function */ + + +inline [[nodiscard]] [[gnu::hot]] static void nodiscard_func(); +/* <- storage.modifier.c */ +/* ^^^^^^^^^^^^^ meta.attribute.c */ +/* ^^ punctuation.section.attribute.begin.c */ +/* ^^^^^^^^^ storage.modifier.c */ +/* ^^ punctuation.section.attribute.end.c */ +/* ^^^^^^^^^^^^ meta.attribute.c */ +/* ^^ punctuation.section.attribute.begin.c */ +/* ^^ punctuation.section.attribute.end.c */ +/* ^^^^^^ storage.modifier.c */ +/* ^^^^^^^^^^^^^^ entity.name.function.c */ + + +[[deprecated("no longer used")]] void attribute_with_arg_func(); +/* <- meta.attribute.c punctuation.section.attribute.begin.c */ +/*^^^^^^^^^^ storage.modifier.c */ +/* ^^^^^^^^^^^^^^^^^^ meta.group.c */ +/* ^^^^^^^^^^^^^^^ string.quoted.double.c */ +/* ^ punctuation.section.group.end.c */ +/* ^^ punctuation.section.attribute.end.c */ +/* ^^^^^^^^^^^^^^^^^^^^^^^ entity.name.function.c */ + +inline [[gnu::always_inline, nodiscard]] void gnu_attributes_func(); +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.c */ +/* ^^ meta.attribute.c punctuation.section.attribute.begin.c */ +/* ^ punctuation.separator.c */ +/* ^^^^^^^^^ storage.modifier.c */ +/* ^^ punctuation.section.attribute.end.c */ +/* ^^^^^^^^^^^^^^^^^^^ entity.name.function.c */ + + + ///////////////////////////////////////////// // Test function call in function parameters ///////////////////////////////////////////// diff --git a/C++/syntax_test_cpp.cpp b/C++/syntax_test_cpp.cpp index cbd6154560..47403bd6c9 100644 --- a/C++/syntax_test_cpp.cpp +++ b/C++/syntax_test_cpp.cpp @@ -1827,6 +1827,62 @@ long double operator "" _km (long double x); /* ^^^^^^^^^^^^^^^ meta.function.parameters */ /* ^^^^^^^^^^^^^^^ entity.name.function */ + + +inline [[nodiscard]] [[gnu::hot]] static auto nodiscard_func() -> void; +/* <- storage.modifier.c++ */ +/* ^^^^^^^^^^^^^ meta.attribute.c++ */ +/* ^^ punctuation.section.attribute.begin.c++ */ +/* ^^^^^^^^^ storage.modifier.c++ */ +/* ^^ punctuation.section.attribute.end.c++ */ +/* ^^^^^^^^^^^^ meta.attribute.c++ */ +/* ^^ punctuation.section.attribute.begin.c++ */ +/* ^^ punctuation.section.attribute.end.c++ */ +/* ^^^^^^ storage.modifier.c++ */ +/* ^^^^^^^^^^^^^^ entity.name.function.c++ */ + + +[[deprecated("no longer used")]] static auto attribute_with_arg_func() -> void; +/* <- meta.attribute.c++ punctuation.section.attribute.begin.c++ */ +/*^^^^^^^^^^ storage.modifier.c++ */ +/* ^^^^^^^^^^^^^^^^^^ meta.group.c++ */ +/* ^^^^^^^^^^^^^^^ string.quoted.double.c */ +/* ^ punctuation.section.group.end.c++ */ +/* ^^ punctuation.section.attribute.end.c++ */ +/* ^^^^^^^^^^^^^^^^^^^^^^ entity.name.function.c++ */ + +inline [[gnu::always_inline, nodiscard]] constexpr auto gnu_attributes_func() -> void; +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute.c++ */ +/* ^^ meta.attribute.c++ punctuation.section.attribute.begin.c++ */ +/* ^ meta.attribute.c++ punctuation.separator.c++ */ +/* ^^^^^^^^^ meta.attribute.c++ storage.modifier.c++ */ +/* ^^ meta.attribute.c++ punctuation.section.attribute.end.c++ */ +/* ^^^^^^^^^^^^^^^^^^^ entity.name.function.c++ */ + +[[using gnu: always_inline, hot]] constexpr auto gnu_namespace_attributes_func() -> void; +/* <- meta.attribute.c++ punctuation.section.attribute.begin.c++ */ +/*^^^^^ meta.attribute.c++ keyword.control.c++ */ +/* ^ meta.attribute.c++ punctuation.separator.c++ */ +/* ^ meta.attribute.c++ punctuation.separator.c++ */ +/* ^^ meta.attribute.c++ punctuation.section.attribute.end.c++ */ +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entity.name.function.c++ */ + +struct S{ + + [[noreturn, ...]] static auto pack_attribute_func() -> void; +/* ^^^^^^^^^^^^^^^^^ meta.block.c++ meta.attribute.c++ */ +/* ^^ punctuation.section.attribute.begin.c++ */ +/* ^^^^^^^^ storage.modifier.c++ */ +/* ^ punctuation.separator.c++ */ +/* ^^^ keyword.operator.variadic.c++ */ +/* ^^ punctuation.section.attribute.end.c++ */ +/* ^^^^^^^^^^^^^^^^^^^ entity.name.function.c++ */ + +} + + + + ///////////////////////////////////////////// // Namespace /////////////////////////////////////////////