From e0e37d7b163c3a250ca80484f430e0fb053cd119 Mon Sep 17 00:00:00 2001 From: Raul E Rangel Date: Wed, 9 Jan 2019 11:02:15 -0700 Subject: [PATCH] [C] Refactor struct handling So correctly fixing this involved a lot more changes then I expected. Fixes #1830 Signed-off-by: Raul E Rangel --- C++/C.sublime-syntax | 306 ++++++++++++++++++++++++------ C++/syntax_test_c.c | 405 ++++++++++++++++++++++++++++++++++++++-- C++/syntax_test_cpp.cpp | 66 ++++++- 3 files changed, 697 insertions(+), 80 deletions(-) diff --git a/C++/C.sublime-syntax b/C++/C.sublime-syntax index 0f5385f48b..db398b2ea5 100644 --- a/C++/C.sublime-syntax +++ b/C++/C.sublime-syntax @@ -13,7 +13,7 @@ variables: macro_identifier: \b[[:upper:]_][[:upper:][:digit:]_]{2,}\b # only uppercase, at least 3 chars control_keywords: 'break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while' basic_types: 'asm|__asm__|auto|bool|_Bool|char|_Complex|double|float|_Imaginary|int|long|short|signed|unsigned|void' - before_tag: 'struct|union|enum' + before_tag: 'union|enum' microsoft_types: '__int8|__int16|__int32|__int64' windows_types: 'APIENTRY|ATOM|BOOL|BOOLEAN|BYTE|CALLBACK|CCHAR|CHAR|COLORREF|CONST|DWORD|DWORDLONG|DWORD_PTR|DWORD32|DWORD64|FLOAT|HACCEL|HALF_PTR|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCONV|HCONVLIST|HCURSOR|HDC|HDDEDATA|HDESK|HDROP|HDWP|HENHMETAFILE|HFILE|HFONT|HGDIOBJ|HGLOBAL|HHOOK|HICON|HINSTANCE|HKEY|HKL|HLOCAL|HMENU|HMETAFILE|HMODULE|HMONITOR|HPALETTE|HPEN|HRESULT|HRGN|HRSRC|HSZ|HWINSTA|HWND|INT|INT_PTR|INT8|INT16|INT32|INT64|LANGID|LCID|LCTYPE|LGRPID|LONG|LONGLONG|LONG_PTR|LONG32|LONG64|LPARAM|LPBOOL|LPBYTE|LPCOLORREF|LPCSTR|LPCTSTR|LPCVOID|LPCWSTR|LPDWORD|LPHANDLE|LPINT|LPLONG|LPSTR|LPTSTR|LPVOID|LPWORD|LPWSTR|LRESULT|PBOOL|PBOOLEAN|PBYTE|PCHAR|PCSTR|PCTSTR|PCWSTR|PDWORD|PDWORDLONG|PDWORD_PTR|PDWORD32|PDWORD64|PFLOAT|PHALF_PTR|PHANDLE|PHKEY|PINT|PINT_PTR|PINT8|PINT16|PINT32|PINT64|PLCID|PLONG|PLONGLONG|PLONG_PTR|PLONG32|PLONG64|POINTER_32|POINTER_64|POINTER_SIGNED|POINTER_UNSIGNED|PSHORT|PSIZE_T|PSSIZE_T|PSTR|PTBYTE|PTCHAR|PTSTR|PUCHAR|PUHALF_PTR|PUINT|PUINT_PTR|PUINT8|PUINT16|PUINT32|PUINT64|PULONG|PULONGLONG|PULONG_PTR|PULONG32|PULONG64|PUSHORT|PVOID|PWCHAR|PWORD|PWSTR|QWORD|SC_HANDLE|SC_LOCK|SERVICE_STATUS_HANDLE|SHORT|SIZE_T|SSIZE_T|TBYTE|TCHAR|UCHAR|UHALF_PTR|UINT|UINT_PTR|UINT8|UINT16|UINT32|UINT64|ULONG|ULONGLONG|ULONG_PTR|ULONG32|ULONG64|UNICODE_STRING|USHORT|USN|VOID|WCHAR|WINAPI|WORD|WPARAM' stdint: 'int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t' @@ -25,6 +25,14 @@ variables: non_func_keywords: 'if|for|switch|while|decltype|sizeof|__declspec|__attribute__' contexts: + or_pop: + - match: '(?=\S)' + comment: Pop if nothing matched (whitespace are ignored). + pop: true + + prototype: + - include: comments + main: - include: preprocessor-global - include: global @@ -47,6 +55,7 @@ contexts: scope: punctuation.definition.comment.c push: - meta_scope: comment.block.c + meta_include_prototype: false - match: \*/ scope: punctuation.definition.comment.c pop: true @@ -60,6 +69,7 @@ contexts: scope: punctuation.definition.comment.c push: - meta_scope: comment.line.double-slash.c + meta_include_prototype: false - match: '(\\)$\n' captures: 1: punctuation.separator.continuation.c @@ -72,7 +82,8 @@ contexts: 1: storage.type.string.c 2: punctuation.definition.string.begin.c push: - - meta_scope: string.quoted.double.c + - meta_include_prototype: false + meta_scope: string.quoted.double.c - match: '"' scope: punctuation.definition.string.end.c pop: true @@ -84,6 +95,7 @@ contexts: 2: punctuation.definition.string.begin.c push: - meta_scope: string.quoted.single.c + meta_include_prototype: false - match: "'" scope: punctuation.definition.string.end.c pop: true @@ -122,7 +134,7 @@ contexts: - match: \b({{control_keywords}})\b scope: keyword.control.c - match: \bsizeof\b - scope: keyword.operator.word.c + scope: keyword.operator.word.c debug.keywords modifiers: - match: \b({{modifiers}})\b @@ -150,6 +162,7 @@ contexts: scope: support.function.C99.c types: + - include: struct-keyword - match: \b({{basic_types}}|{{before_tag}})\b scope: storage.type.c - match: \b(u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t|ptrdiff_t)\b @@ -243,18 +256,20 @@ contexts: # comment without a line continuation ends at the newline. preprocessor-comments: - match: /\* - scope: punctuation.definition.comment.c + scope: punctuation.definition.comment.c debug.preprocessor-comments push: - meta_scope: comment.block.c + - meta_include_prototype: false - match: '\\$\n' scope: punctuation.separator.continuation.c - match: \*/ scope: punctuation.definition.comment.c pop: true - match: // - scope: punctuation.definition.comment.c + scope: punctuation.definition.comment.c debug.preprocessor-comments push: - meta_scope: comment.line.double-slash.c + - meta_include_prototype: false - match: '(\\)$\n' captures: 1: punctuation.separator.continuation.c @@ -320,6 +335,7 @@ contexts: - include: modifiers-parens - include: modifiers - include: types + - include: struct-keyword - include: function-call - match: ';' scope: punctuation.terminator.c @@ -327,6 +343,7 @@ contexts: ## C-specific contexts global-modifier: + - meta_scope: debug.global-modifier - include: comments - include: modifiers-parens - include: modifiers @@ -334,6 +351,7 @@ contexts: set: global-type global-type: + - meta_scope: debug.global-type - include: comments - match: \* scope: keyword.operator.c @@ -350,12 +368,13 @@ contexts: ) ) captures: - 1: storage.type.c + 1: storage.type.c debug.global-type set: global-maybe-function # The previous match handles return types of struct/enum/etc from a func, # there this one exits the context to allow matching an actual struct/union - match: '(?=\b({{before_tag}})\b)' set: data-structures + - include: struct-keyword - match: '(?=\b({{control_keywords}})\b)' pop: true - match: '(?=\s)' @@ -396,8 +415,23 @@ contexts: - match: '{{identifier}}(?!\s*(\(|$))' # Real function definition - match: '{{identifier}}(?=\s*(\(|$))' - scope: meta.function.c entity.name.function.c + scope: meta.function.c entity.name.function.c debug.global set: function-definition-params + - match: '\((?=\s*\*)' + scope: punctuation.section.group.begin debug.global-maybe-function.function-pointer + comment: Function pointers are not really functions, but variables + push: + - meta_scope: meta.parens + - match: \) + scope: punctuation.section.parens.end + set: + - include: function-definition-params-group + - include: or_pop + - match: \* + scope: storage.modifier.c + - match: '{{identifier}}' + scope: variable.other.c debug.global-maybe-function.function-pointer + - include: or_pop - match: '(?=\S)' pop: true @@ -406,21 +440,32 @@ contexts: - include: comments - match: '(?=\()' set: - - match: \( - scope: meta.function.parameters.c meta.group.c punctuation.section.group.begin.c - set: - - meta_content_scope: meta.function.parameters.c meta.group.c - - match : \) - scope: punctuation.section.group.end.c - set: function-definition-continue - - match: '\bvoid\b' - scope: storage.type.c - - match: '{{identifier}}(?=\s*(\[|,|\)))' - scope: variable.parameter.c - - include: expressions - - include: preprocessor-line-continuation + - include: function-definition-params-group + - include: function-definition-continue - match: (?=\S) pop: true + function-definition-params-group: + - match: \( + scope: punctuation.section.group.begin.c + push: + - meta_scope: meta.function.parameters.c meta.group.c + - match : \) + scope: punctuation.section.group.end.c + pop: true + - match: '\bvoid\b' + scope: storage.type.c + - match: \* + scope: storage.modifier.c + - match: \.\.\. + scope: keyword.operator.variadic.c + - match: '{{identifier}}(?=\s*(\[|,|\)))' + scope: variable.parameter.c + - include: struct-keyword-parameter + - include: expressions + - match: '{{identifier}}' + scope: support.type.c + comment: We match the variable name above + - include: preprocessor-line-continuation function-definition-continue: - meta_content_scope: meta.function.c @@ -429,33 +474,29 @@ contexts: pop: true - match: \b(const|final|noexcept|override)\b scope: storage.modifier.c - - match: '(?=\{)' - set: function-definition-body + - include: function-definition-body - match: '(?=\S)' pop: true function-definition-body: - - meta_content_scope: meta.function.c - match: '\{' - scope: meta.block.c punctuation.section.block.begin.c + scope: punctuation.section.block.begin.c set: - - meta_content_scope: meta.function.c meta.block.c + - meta_scope: meta.function.c meta.block.c debug.function-definition-body - match: '\}' - scope: meta.function.c meta.block.c punctuation.section.block.end.c + scope: punctuation.section.block.end.c pop: true - match: (?=^\s*#\s*(elif|else|endif)\b) pop: true - match: '(?=({{before_tag}})([^(;]+$|.*\{))' push: data-structures + - include: struct-keyword - include: statements data-structures: # Detect variable type definitions using struct/enum/union followed by a tag - - match: '\b({{before_tag}})(?=\s+{{identifier}}\s+{{identifier}}\s*[=;\[])' + - match: '\b({{before_tag}})(?=\s+{{identifier}}(?:\s+{{identifier}})*(?:\s*\*\s*|\s)+{{identifier}}\s*[,=;\[])' scope: storage.type.c - - match: '\bstruct\b' - scope: storage.type.c - set: data-structures-struct-definition - match: '\benum\b' scope: storage.type.c set: data-structures-enum-definition @@ -465,23 +506,141 @@ contexts: - match: '(?=\S)' pop: true - data-structures-struct-definition: - - meta_scope: meta.struct.c - - include: data-structures-definition-common-begin - - match: '{{identifier}}(?=\s*;)' - scope: entity.name.struct.forward-decl.c + macro-identifiers: + - match: '{{macro_identifier}}' + comment: Not sure I think this is a good idea + scope: variable.annotation + + parameter-variable-identifier: + - match: \* + scope: storage.modifier.c + - match: \( + scope: punctuation.section.group.begin debug.parameter-variable-identifier.function-pointer + comment: Function pointer declaration as variable + push: + - meta_scope: meta.parens + - match: \) + scope: punctuation.section.parens.end + set: + - include: function-definition-params-group + - include: or_pop + - match: \* + scope: storage.modifier.c + - match: '{{identifier}}' + scope: variable.parameter.c debug.parameter-variable-identifier.function-pointer - match: '{{identifier}}' - scope: entity.name.struct.c - - match: '(?=;)' - pop: true - - match: '\{' - scope: meta.block.c punctuation.section.block.begin.c + scope: variable.parameter.c debug.parameter-variable-identifier + + variable-identifier-list: + - include: modifiers-parens + - match: \* + scope: storage.modifier.c + - match: '{{identifier}}(?=\s*\()' + scope: meta.function.c entity.name.function.c debug.variable-identifier-list.function-first set: - - meta_content_scope: meta.struct.c meta.block.c + - meta_scope: debug.variable-identifier-list.function + - include: function-definition-params-group + - include: function-definition-body + - match: '(?=\S)' + set: variable-identifier-list + - match: \( + scope: punctuation.section.group.begin debug.variable-identifier-list.function-pointer + comment: Function pointer declaration + push: + - meta_scope: meta.parens + - match: \) + scope: punctuation.section.parens.end + set: + - include: function-definition-params-group + - include: or_pop + - match: \* + scope: storage.modifier.c + - match: '{{identifier}}' + scope: variable.other.c debug.variable-identifier-list.function-pointer + - match: '{{identifier}}' + scope: variable.other.c debug.variable-identifier-list + push: + - meta_scope: debug.variable-identifier-list.array-or-assignment + - match: \[ + scope: punctuation.section.brackets.begin.c storage.modifier.c + push: + - meta_scope: meta.brackets.c + - match: \] + scope: punctuation.section.brackets.end.c storage.modifier.c + pop: true + - include: expressions + # Expressions doesn't handle macro identifiers or enum constants + - match: '{{macro_identifier}}' + scope: support.constant.c + - match: \= + scope: keyword.operator.assignment.c + set: + - meta_scope: debug.variable-identifier-list.assignment + - match: '(?=,|;)' + pop: true + - include: expressions + - include: or_pop + - include: or_pop + - match: ',' + scope: punctuation.separator debug.variable-identifier-list + - include: or_pop + + struct-keyword-parameter: + - match: '\bstruct\b' + scope: storage.type.c + push: + - meta_scope: meta.struct.c debug.struct-keyword-parameter + - match: '{{identifier}}' + scope: support.type.c + comment: Type for variable declaration + set: + - include: parameter-variable-identifier + - include: or_pop + - include: or_pop + + struct-keyword: + - match: '\bstruct\b' + scope: storage.type.c + push: + - meta_scope: meta.struct.c debug.struct-keyword + # - include: data-structures-definition-common-begin + # This handles __attribute__ and __declspec + - include: modifiers-parens + - include: macro-identifiers + - match: '{{identifier}}(?=\s*{|\s*\n)' + scope: entity.name.struct.c + comment: Struct definition + set: struct-body + - match: '(?={)' + comment: Anonymous struct definition + set: struct-body + - match: '{{identifier}}' + scope: support.type.c debug.data-structures-struct-definition + comment: Type for variable declaration + set: variable-identifier-list + - include: or_pop + struct-body: + - match: '\{' + scope: punctuation.section.block.begin.c + push: + - meta_scope: meta.struct.c meta.block.c debug.struct-body - match: '\}' - scope: meta.struct.c meta.block.c punctuation.section.block.end.c - pop: true + scope: punctuation.section.block.end.c + set: + - meta_scope: debug.struct-body.struct-end + - match: '\n' + comment: > + Struct body declarations should normally have an identifier + afterwards or ; to terminate them. If the ; is missing we don't + want to grab an identifier from another line. Typically variable + names are on the same line as the }, so if we find a new line + treat it as a terminator. + pop: true + - include: variable-identifier-list + - include: or_pop + - include: struct-keyword - include: data-structures-body + - include: or_pop data-structures-enum-definition: - meta_scope: meta.enum.c @@ -493,14 +652,34 @@ contexts: - match: '(?=;)' pop: true - match: '\{' - scope: meta.block.c punctuation.section.block.begin.c + scope: punctuation.section.block.begin.c set: - - meta_content_scope: meta.enum.c meta.block.c + - meta_scope: meta.enum.c meta.block.c debug.data-structures-enum-definition # Enums don't support methods so we have a simplified body - match: '\}' scope: meta.enum.c meta.block.c punctuation.section.block.end.c pop: true - - include: data-structures-body + - match: '{{identifier}}' + scope: constant.other.enum.c + push: + - meta_scope: debug.data-structures-enum-definition.pre-assignment + - match: '=' + scope: keyword.operator.assignment + set: + - meta_scope: debug.data-structures-enum-definition.post + # expressions gobbles up the , and } (which it shouldn't) + # so we need to match before so we break out of the scope + # correctly. We need to fix expressions. + - match: '(?=,|})' + pop: true + - include: expressions + - include: or_pop + # No equals + - include: or_pop + - match: ',' + scope: punctuation.separator.c + + #- include: data-structures-body data-structures-union-definition: - meta_scope: meta.union.c @@ -528,6 +707,7 @@ contexts: - include: modifiers # Handle macros so they aren't matched as the class name - match: '\b[[:upper:][:digit:]_]+\b' + scope: macro data-structures-definition-common-end: - match: '(?=;)' @@ -535,13 +715,31 @@ contexts: data-structures-body: - include: preprocessor-data-structures + - include: preprocessor-expressions + - include: preprocessor-convention-ignore-uppercase-calls-without-semicolon - match: '(?={{before_tag}})' push: data-structures - - include: expressions + # - include: modifiers-parens + - include: struct-keyword + - match: '\b{{type_qualifier}}\b' + scope: storage.modifier.c + - match: '{{basic_types}}' + scope: storage.type.c + comment: Improve this to better match built-in types + push: + - meta_scope: debug.data-structures-body.variable-identifier + - include: variable-identifier-list + - match: '{{identifier}}' + scope: support.type.c + comment: Improve this to better match built-in types + push: + - meta_scope: debug.data-structures-body.variable-identifier + - include: variable-identifier-list + #- include: expressions block: - match: '\{' - scope: punctuation.section.block.begin.c + scope: punctuation.section.block.begin.c debug.block push: - meta_scope: meta.block.c - match: (?=^\s*#\s*(elif|else|endif)\b) @@ -625,7 +823,7 @@ contexts: keywords-parens: - match: '\b(sizeof)\b\s*(\()' captures: - 1: keyword.operator.word.c + 1: keyword.operator.word.c debug.keywords-parens 2: meta.group.c punctuation.section.group.begin.c push: - meta_content_scope: meta.group.c @@ -798,7 +996,8 @@ contexts: captures: 1: keyword.control.import.c push: - - meta_scope: meta.preprocessor.c + - meta_scope: meta.preprocessor.c debug.preprocessor-rule-other-global + - meta_include_prototype: false - include: preprocessor-line-continuation - include: preprocessor-comments - match: \bdefined\b @@ -822,7 +1021,7 @@ contexts: - match: (?=^\s*#\s*(elif|else)\b) push: preprocessor-elif-else-branch-global - match: \{ - scope: punctuation.section.block.begin.c + scope: punctuation.section.block.begin.c debug.preprocessor-if-branch-global set: preprocessor-block-if-branch-global - include: preprocessor-global - include: negated-block @@ -928,7 +1127,7 @@ contexts: captures: 1: keyword.control.import.c push: - - meta_scope: meta.preprocessor.c + - meta_scope: meta.preprocessor.c debug.preprocessor-rule-other-statements - include: preprocessor-line-continuation - include: preprocessor-comments - match: \bdefined\b @@ -1147,7 +1346,8 @@ contexts: captures: 1: keyword.control.import.c push: - - meta_scope: meta.preprocessor.c + - meta_scope: meta.preprocessor.c debug.preprocessor-other + - meta_include_prototype: false - include: preprocessor-line-continuation - include: preprocessor-line-ending - include: preprocessor-comments diff --git a/C++/syntax_test_c.c b/C++/syntax_test_c.c index 838d21b7cb..4100526991 100644 --- a/C++/syntax_test_c.c +++ b/C++/syntax_test_c.c @@ -13,6 +13,8 @@ int main(){ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.macro */ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.group */ /* ^^^^^^^^^^^^^^^^^^^^^^^^ meta.group meta.group */ +/* ^^^^^^ storage.type */ +/* ^ support.type */ /* <- keyword.control.import.define */ /* ^ entity.name.constant.preprocessor */ /* ^ comment.block */ @@ -56,7 +58,7 @@ int i; // The following example ensures that comments at the end of preprocessor // directives don't mess with context transitions int func() { -/* ^^^^^^^^ meta.function */ +/* ^^^^^^ meta.function */ /* ^^ meta.function.parameters */ /* ^ meta.block punctuation.section.block.begin */ /* ^ entity.name.function */ @@ -69,6 +71,12 @@ int func() { /* ^ comment.line */ #endif /* ^ keyword.control.import */ + + print("// String"); +/*^^^^^ meta.function-call.c variable.function.c */ +/* ^^^^^^^^^^^ string.quoted.double.c +/* ^ punctuation.definition.string.begin.c */ +/* ^ punctuation.definition.string.end.c */ } /* <- meta.function meta.block punctuation.section.block.end */ /* <- - meta.function meta.block */ @@ -263,16 +271,20 @@ struct point /* ^ storage.type */ /* ^ entity.name.struct */ { +/* <- meta.struct.c meta.block.c punctuation.section.block.begin.c */ int x; int y; } +/* <- meta.struct.c meta.block.c punctuation.section.block.end.c */ struct point2 { /* ^ storage.type */ /* ^ entity.name.struct */ +/* ^ meta.struct.c meta.block.c punctuation.section.block.begin.c */ int x; int y; } +/* <- meta.struct.c meta.block.c punctuation.section.block.end.c */ int main(void) { /* ^^^^ entity.name.function */ @@ -280,39 +292,114 @@ int main(void) { } struct point get_point() {} -/* ^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^ meta.function */ +/* ^^ meta.function.parameters */ +/* ^^ meta.function */ /* ^^ meta.function.parameters */ /* ^^ meta.block */ /* ^ punctuation.section.block.begin /* ^ punctuation.section.block.end -/* ^ storage.type */ -/* ^ - entity.name.struct */ +/* <- storage.type */ +/* ^ support.type - entity.name.struct */ /* ^ entity.name.function */ -struct point **alloc_points(); -/* ^ storage.type */ -/* ^ - entity.name.struct */ -/* ^^ keyword.operator */ -/* ^ entity.name.function */ +inline struct point **alloc_points(); +/* ^ storage.type */ +/* ^ support.type - entity.name.struct */ +/* ^^ storage.modifier.c */ +/* ^ entity.name.function */ struct point* alloc_point(); +/* <- storage.type.c */ +/* ^^^^^ meta.struct.c support.type.c */ +/* ^ storage.modifier.c */ /* ^ entity.name.function - variable.function */ -struct point FOO_API *alloc_point3(); +struct point FOO_API *alloc_point3(), alloc_point2(), struct_var2; +/* <- storage.type.c */ +/* ^^^^^ meta.struct.c support.type.c */ +/* ^ storage.modifier.c */ /* ^ entity.name.function - variable.function */ +/* ^ punctuation.separator */ +/* ^ entity.name.function - variable.function */ +/* ^^^^^^^^^^^ variable.other.c */ + +struct { +/* <- storage.type.c */ +/* ^ meta.struct.c meta.block.c punctuation.section.block.begin.c */ + int a; +/*^^^ storage.type.c */ +/* ^ variable.other.c */ +} anon_s, *anon_b, anon_s_f(), anon_c = { +/* <- meta.struct.c meta.block.c punctuation.section.block.end.c */ +/*^^^^^^ variable.other.c */ +/* ^^^^^^ variable.other.c */ +/* ^^^^^^^^ entity.name.function.c */ +/* ^^^^^^ variable.other.c */ +/* ^ keyword.operator.assignment.c */ + .a = 4 +}, anon_d = {.a = 6}, anon_arr[] = {{.a = 1}, {.a = 2}}, anon_g; + /* <- punctuation.separator */ +/* ^^^^^^ variable.other.c */ +/* ^ keyword.operator.assignment.c */ +/* ^ punctuation.separator */ +/* ^^^^^^^^ variable.other.c */ +/* ^^ meta.brackets.c storage.modifier.c */ +/* ^ keyword.operator.assignment.c */ +/* ^ punctuation.separator */ +/* ^^^^^^ variable.other.c */ +/* ^ punctuation.terminator.c */ + +static inline u64 xhci_read_64(const struct xhci_hcd *xhci, + __le64 __iomem *regs); + +typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); +// TODO int main(void) { struct UI_BoundingBox decorativeBox = {10, titleHeight-3, width-20, height-10}; -/* ^ - entity.name */ -/* ^ - entity.name */ +/* ^^^^^^ storage.type */ +/* ^ support.type - entity.name */ +/* ^ variable.other - entity.name */ } -struct foo MACRO { -/* ^ entity.name.struct */ -/* ^ - entity.name */ +struct MACRO foo { +/* ^ variable.annotation - entity.name - support.type*/ +/* ^ entity.name.struct */ } +struct UI_BoundingBox position; +/* ^ support.type.c - entity.name */ +/* ^ variable.other - entity.name */ + +struct UI_BoundingBox *position_p; +/* ^ support.type.c - entity.name */ +/* ^ variable.other - entity.name */ + +struct UI_BoundingBox * position_p1; +/* ^ support.type.c - entity.name */ +/* ^ variable.other - entity.name */ + +struct UI_BoundingBox **position_p2; +/* ^ support.type.c - entity.name */ +/* ^ variable.other - entity.name */ + +struct UI_BoundingBox ** position_p3; +/* ^ support.type.c - entity.name */ +/* ^ variable.other - entity.name */ + + +struct UI_BoundingBox ** position_p4, position_p5, * position_p6; +/* ^ support.type.c - entity.name */ +/* ^ variable.other - entity.name */ +/* ^^ storage.modifier.c */ +/* ^ punctuation.separator */ +/* ^ variable.other - entity.name */ +/* ^ punctuation.separator */ +/* ^ storage.modifier.c */ +/* ^ variable.other - entity.name */ + // Partially-typed struct foo /* ^ entity.name */ @@ -321,17 +408,297 @@ struct UI_MenuBoxData /* <- storage.type */ /* ^ entity.name.struct */ { +/* <- meta.struct.c meta.block.c punctuation.section.block.begin.c */ struct UI_BoundingBox position; -/* ^ - entity.name */ -/* ^ - entity.name */ +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ variable.other.c - entity.name */ + struct UI_BoundingBox *position_p; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + struct UI_BoundingBox * position_p1; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + struct UI_BoundingBox **position_p2; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + struct UI_BoundingBox ** position_p3; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + struct UI_BoundingBox* position_p4; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + struct UI_BoundingBox** position_p5; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + struct UI_BoundingBox * * position_p5; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ storage.modifier.c */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + struct UI_BoundingBox *pos_1, *pos_1; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + + const volatile struct UI_BoundingBox *cv_p; +/* ^^^^^ storage.modifier.c */ +/* ^^^^^^^^ storage.modifier.c */ +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + + long resume_done[USB_MAXCHILDREN]; +/* ^^^^ storage.type.c */ +/* ^^^^^^^^^^^ variable.other.c */ +/* ^^^^^^^^^^^^^^^^^ meta.brackets.c */ +/* ^ punctuation.section.brackets.begin.c */ +/* ^^^^^^^^^^^^^^^ support.constant.c */ +/* ^ punctuation.section.brackets.end.c */ + + struct xhci_run_regs __iomem *run_regs; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ - entity.name */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + struct xhci_run_regs __attribute__((noderef)) *run_regs; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ - entity.name */ +/* ^ storage.modifier.c */ +/* ^ variable.other.c - entity.name */ + + struct __attribute__((noderef)) xhci_run_regs *run_regs; +/* ^^^^^^ storage.type */ +/* ^ support.type.c - entity.name */ +/* ^ storage.modifier.c */ +/* ^ - entity.name */ + struct nested_t { +/* ^^^^^^ storage.type */ +/* ^^^^^^^^ entity.name.struct.c */ +/* ^ meta.struct.c meta.block.c meta.struct.c meta.block.c punctuation.section.block.begin.c */ + int bar; +/* ^^^ storage.type.c */ +/* ^^^ variable.other.c */ + } nested; +/* ^^^^^^ variable.other.c */ + +#define CMD_RING_STATE_RUNNING (1 << 0) +/* <- meta.preprocessor.macro.c keyword.control.import.define.c */ +/* ^ meta.preprocessor.macro.c entity.name.constant.preprocessor.c */ + enum UI_BoxCharType borderType; /* ^ - entity.name */ /* ^ - entity.name */ unsigned int paddingX; unsigned int paddingY; struct UI_ScrollBoxText boxContents[]; +/* ^^^^^^ storage.type */ /* ^ - entity.name */ /* ^ - entity.name */ + + struct delayed_work monitor_work ____cacheline_aligned_in_smp; +/* ^^^^^^ storage.type */ + const struct efx_channel_type * +/* ^^^^^storage.modifier.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^^^^^^^^^^^^ support.type - entity.name */ +/* ^ storage.modifier.c */ + extra_channel_type[EFX_MAX_EXTRA_CHANNELS]; +/* ^^^^^^^^^^^^^^^^^^ variable.other.c */ +/* ^^^^^^^^^^^^^^^^^^^^^^^^ meta.brackets.c */ +/* ^^^^^^^^^^^^^^^^^^^^^^ support.constant.c */ +/* ^ punctuation.section.brackets.begin.c storage.modifier.c */ +/* ^ punctuation.section.brackets.end.c storage.modifier.c */ + +#if 0 + struct UI_BoundingBox bb1; +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.block.preprocessor.if-branch.c */ +#else + struct UI_BoundingBox bb1; +#endif +}; +/* <- meta.struct.c meta.block.c punctuation.section.block.end.c */ + +#define CMD_RING_STATE_RUNNING (1 << 0) +/* <- meta.preprocessor.macro.c keyword.control.import.define.c */ +/* ^ meta.preprocessor.macro.c entity.name.constant.preprocessor.c */ + +struct __attribute__((packed)) child_t { +/* <- storage.type */ +/* ^ meta.attribute.c storage.modifier.c */ +/* ^^^^^^^ entity.name.struct */ + int foo; +/* ^^^ storage.type.c */ +/* ^^^ variable.other.c */ +}; + +struct child_t child1; + +struct __attribute__((packed)) child_t_line +/* <- storage.type */ +/* ^ meta.attribute.c storage.modifier.c */ +/* ^^^^^^^ entity.name.struct */ +{ + int foo; +/* ^^^ storage.type.c */ +/* ^^^ variable.other.c */ +}; + +struct __attribute__((packed)) +/* <- storage.type */ +/* ^ meta.attribute.c storage.modifier.c */ +{ +/* <- meta.struct.c meta.block.c punctuation.section.block.begin.c */ + int foo; +/* ^^^ storage.type.c */ +/* ^^^ variable.other.c */ +}; +/* <- meta.struct.c meta.block.c punctuation.section.block.end.c */ + +struct rproc_ops { +/* <- storage.type */ +/* ^ entity.name.struct */ +/* ^ meta.struct.c meta.block.c punctuation.section.block.begin.c */ + int (*start)(struct rproc *rproc); +/* ^^^ storage.type.c */ +/* ^^^^^ variable.other.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^ support.type.c */ +/* ^^^^^ variable.parameter.c */ + int (*start)(struct rproc *); +/* ^^^ storage.type.c */ +/* ^^^^^ variable.other.c */ +/* ^ meta.function.parameters.c meta.group.c punctuation.section.group.begin.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^ support.type.c */ +/* ^ storage.modifier.c */ +/* ^ meta.function.parameters.c meta.group.c punctuation.section.group.end.c */ + int (*start)(struct rproc *, struct rproc *); +/* ^^^ storage.type.c */ +/* ^^^^^ variable.other.c */ +/* ^ meta.function.parameters.c meta.group.c punctuation.section.group.begin.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^ support.type.c */ +/* ^ storage.modifier.c */ +/* ^ punctuation.separator.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^ support.type.c */ +/* ^ storage.modifier.c */ +/* ^ meta.function.parameters.c meta.group.c punctuation.section.group.end.c */ + void * (*da_to_va)(struct rproc *rproc, u64 da, int len); +/* ^^^ storage.type.c */ +/* ^^^^^^^^ variable.other.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^ support.type.c */ +/* ^^^^^ variable.parameter.c */ +/* ^^^ support.type */ +/* ^^ variable.parameter */ +/* ^^^ storage.type */ +/* ^^^ variable.parameter */ + struct resource_table *(*find_loaded_rsc_table)( +/* ^^^^^^ storage.type.c */ +/* ^^^^^^^^^^^^^^ support.type.c */ +/* ^^^^^^^^^^^^^^^^^^^^^ variable.other.c */ + struct rproc *rproc, const struct firmware *fw); +/* ^^^^^^ storage.type.c */ +/* ^^^^^ support.type.c */ +/* ^ storage.modifier.c */ +/* ^^^^^ variable.parameter.c */ +/* ^ punctuation.separator */ +/* ^^^^^ storage.modifier.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^^^^ support.type.c */ +/* ^^ variable.parameter.c */ +}; +/* <- meta.struct.c meta.block.c punctuation.section.block.end.c */ + +void * (*da_to_va)(struct rproc *rproc, u64 da, int len); +/* <- storage.type.c */ +/* ^^^^^^^^ variable.other.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^ support.type.c */ +/* ^ storage.modifier.c */ +/* ^^^^^ variable.parameter.c */ +/* ^^^ support.type.c */ +/* ^^ variable.parameter */ +/* ^^^ storage.type */ +/* ^^^ variable.parameter */ + +struct resource_table *(*find_loaded_rsc_table)( +/* <- storage.type.c */ +/* ^^^^^^^^^^^^^^ support.type.c */ +/* ^^^^^^^^^^^^^^^^^^^^^ variable.other.c */ + struct rproc *rproc, const struct firmware *fw); +/* ^^^^^^ storage.type.c */ +/* ^^^^^ support.type.c */ +/* ^ storage.modifier.c */ +/* ^^^^^ variable.parameter.c */ +/* ^ punctuation.separator */ +/* ^^^^^ storage.modifier.c */ +/* ^^^^^^ storage.type.c */ +/* ^^^^^^^^ support.type.c */ +/* ^ storage.modifier.c */ +/* ^^ variable.parameter.c */ + +static const struct pci_driver my_driver __pci_driver = { + .ops = &pci_my_device_ops, + .vendor = PCI_VENDOR_ID, + .devices = pci_device_ids, +}; + +static const struct spd_info { +/* ^^^^^^ meta.struct.c storage.type.c */ +/* ^^^^^^^^ entity.name.struct.c */ + size_t spd_len; +/* ^^^^^^ support.type */ +/* ^^^^^^^ variable.other.c */ + size_t spd_part_len; +/* ^^^^^^ support.type */ +/* ^^^^^^^ variable.other.c */ +} spd_mem_info[] = { +/*^^^^^^^^^^^^ variable.other.c */ +/* ^^ meta.brackets.c storage.modifier.c */ + [SPD_INFO_DDR4] = { + .spd_len = SPD_DDR4_LENGTH, + .spd_part_len = SPD_DDR4_PART_LEN, + }, + [SPD_INFO_DEFAULT] = { + .spd_len = SPD_DEFAULT_LENGTH, + .spd_part_len = SPD_DEFAULT_PART_LEN, + }, +}; + +enum { +/* <- storage.type */ + ENUM_A, +/* ^ constant.other.enum.c */ +/* ^ punctuation.separator.c */ + ENUM_B = 6, +/* ^ constant.other.enum.c */ +/* ^ keyword.operator.assignment */ +/* ^ constant.numeric.c */ +/* ^ punctuation.separator.c */ + ENUM_C +/* ^ constant.other.enum.c */ }; ///////////////////////////////////////////// @@ -434,7 +801,7 @@ int /* comment */ * myfunc (int * a) /*^^^^^^^ meta.function.parameters meta.group */ /* <- punctuation.section.group.begin */ -/* ^ keyword.operator */ +/* ^ storage.modifier */ /* ^ variable.parameter */ /* ^ punctuation.section.group.end */ { @@ -449,7 +816,7 @@ func_name() { } MACRO1 void * MACRO2 myfuncname () { -/* ^^^^^^^^^^^^^^^ meta.function */ +/* ^^^^^^^^^^ meta.function */ /* ^^ meta.function.parameters */ /* ^ meta.block punctuation.section.block.begin /* ^ storage.type */ diff --git a/C++/syntax_test_cpp.cpp b/C++/syntax_test_cpp.cpp index 6a319a1ac3..a86082e8ca 100644 --- a/C++/syntax_test_cpp.cpp +++ b/C++/syntax_test_cpp.cpp @@ -237,6 +237,56 @@ bool foo (bool run=true) {} /* ^ entity.name.function */ }; +struct UI_BoundingBox position; +/* ^ - entity.name */ +/* ^ - entity.name */ + +struct UI_BoundingBox *position_p; +/* ^ - entity.name */ +/* ^ - entity.name */ + +struct UI_BoundingBox * position_p2; +/* ^ - entity.name */ +/* ^ - entity.name */ + +struct UI_BoundingBox **position_p2; +/* ^ - entity.name */ +/* ^ - entity.name */ + +struct UI_BoundingBox ** position_p2; +/* ^ - entity.name */ +/* ^ - entity.name */ + +struct UI_MenuBoxData +/* <- storage.type */ +/* ^ entity.name.struct */ +{ + struct UI_BoundingBox position; +/* ^ - entity.name */ +/* ^ - entity.name */ + struct UI_BoundingBox *position_p; +/* ^ - entity.name */ +/* ^ - entity.name */ + struct UI_BoundingBox * position_p1; +/* ^ - entity.name */ +/* ^ - entity.name */ + struct UI_BoundingBox **position_p2; +/* ^ - entity.name */ +/* ^ - entity.name */ + struct UI_BoundingBox ** position_p3; +/* ^ - entity.name */ +/* ^ - entity.name */ + enum UI_BoxCharType borderType; +/* ^ - entity.name */ +/* ^ - entity.name */ + unsigned int paddingX; + unsigned int paddingY; + struct UI_ScrollBoxText boxContents[]; +/* ^ - entity.name */ +/* ^ - entity.name */ +}; + + ///////////////////////////////////////////// // Strings ///////////////////////////////////////////// @@ -478,7 +528,7 @@ template /* ^ meta.template constant.numeric */ /* ^ meta.template keyword.operator */ /* ^ meta.template constant.language */ -struct Foo +struct Foo { /* <- meta.struct - meta.template */ @@ -515,7 +565,7 @@ template class B { /* ... */ }; /* ^ - meta.template */ template class C { /* ... */ }; -// templates inside templates... it's templates all the way down +// templates inside templates... it's templates all the way down template class P> class X { /* ... */ }; /* ^ meta.template punctuation */ /* ^ meta.template meta.template punctuation */ @@ -615,7 +665,7 @@ int main() { // Example from section 14.2/4 of // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf -struct X +struct X { template X* alloc(); @@ -623,12 +673,12 @@ struct X template static X* adjust(); }; -template -void f(T* p) +template +void f(T* p) { // Be optimistic: scope it as a template member function call anyway. T* p1 = p->alloc<200>(); // ill-formed: < means less than - + T* p2 = p->template alloc<200>(); // OK: < starts template argument list /* ^ punctuation.accessor */ /* ^ storage.type - variable.other */ @@ -636,7 +686,7 @@ void f(T* p) // Be optimistic: scope it as a template member function call anyway. T::adjust<100>(); // ill-formed: < means less than - + T::template adjust<100>(); // OK: < starts template argument list /* <- - variable.function */ /*^ punctuation.accessor */ @@ -1783,7 +1833,7 @@ class Foo { /* ^ meta.method.constructor.initializer-list */ /* ^ - meta.function-call - variable.function */ private: - int var1, var2, var3, var4; + int var1, var2, var3, var4; }; class X {