diff options
| author | Alan Mackenzie | 2021-02-02 20:34:42 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2021-02-02 20:34:42 +0000 |
| commit | 9a67da98a25f545ff68540e01a06bc62605ee147 (patch) | |
| tree | 82b4e27a9dbdc89785d64630ab41dcf761fabe46 | |
| parent | 04ab3904eddc01af918fb85b8712cd5d45238468 (diff) | |
| download | emacs-9a67da98a25f545ff68540e01a06bc62605ee147.tar.gz emacs-9a67da98a25f545ff68540e01a06bc62605ee147.zip | |
CC Mode: Prevent "const" inside an identifier being recognized as the keyword
This fixes bug #45560.
* lisp/progmodes/cc-engine.el (c-forward-declarator)
(c-forward-decl-or-cast-1): Amend certain regexp match numbers on account of
the change below. Surround some looking-at calls with save-match-data.
* lisp/progmodes/cc-langs.el (c-type-decl-prefix-keywords-key): New lang
const.
(c-type-decl-prefix-key): Reformulate to match operators and keywords
separately, using the new lang const (above).
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 21 | ||||
| -rw-r--r-- | lisp/progmodes/cc-langs.el | 49 |
2 files changed, 41 insertions, 29 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 3fce7dbafae..484624b8664 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -9021,14 +9021,15 @@ point unchanged and return nil." | |||
| 9021 | (c-forward-noise-clause)) | 9021 | (c-forward-noise-clause)) |
| 9022 | ((and (looking-at c-type-decl-prefix-key) | 9022 | ((and (looking-at c-type-decl-prefix-key) |
| 9023 | (if (and (c-major-mode-is 'c++-mode) | 9023 | (if (and (c-major-mode-is 'c++-mode) |
| 9024 | (match-beginning 3)) | 9024 | (match-beginning 4)) ; Was 3 - 2021-01-01 |
| 9025 | ;; If the third submatch matches in C++ then | 9025 | ;; If the third submatch matches in C++ then |
| 9026 | ;; we're looking at an identifier that's a | 9026 | ;; we're looking at an identifier that's a |
| 9027 | ;; prefix only if it specifies a member pointer. | 9027 | ;; prefix only if it specifies a member pointer. |
| 9028 | (progn | 9028 | (progn |
| 9029 | (setq id-start (point)) | 9029 | (setq id-start (point)) |
| 9030 | (c-forward-name) | 9030 | (c-forward-name) |
| 9031 | (if (looking-at "\\(::\\)") | 9031 | (if (save-match-data |
| 9032 | (looking-at "\\(::\\)")) | ||
| 9032 | ;; We only check for a trailing "::" and | 9033 | ;; We only check for a trailing "::" and |
| 9033 | ;; let the "*" that should follow be | 9034 | ;; let the "*" that should follow be |
| 9034 | ;; matched in the next round. | 9035 | ;; matched in the next round. |
| @@ -9038,13 +9039,15 @@ point unchanged and return nil." | |||
| 9038 | (setq got-identifier t) | 9039 | (setq got-identifier t) |
| 9039 | nil)) | 9040 | nil)) |
| 9040 | t)) | 9041 | t)) |
| 9041 | (if (looking-at c-type-decl-operator-prefix-key) | 9042 | (if (save-match-data |
| 9043 | (looking-at c-type-decl-operator-prefix-key)) | ||
| 9042 | (setq decorated t)) | 9044 | (setq decorated t)) |
| 9043 | (if (eq (char-after) ?\() | 9045 | (if (eq (char-after) ?\() |
| 9044 | (progn | 9046 | (progn |
| 9045 | (setq paren-depth (1+ paren-depth)) | 9047 | (setq paren-depth (1+ paren-depth)) |
| 9046 | (forward-char)) | 9048 | (forward-char)) |
| 9047 | (goto-char (match-end 1))) | 9049 | (goto-char (or (match-end 1) |
| 9050 | (match-end 2)))) | ||
| 9048 | (c-forward-syntactic-ws) | 9051 | (c-forward-syntactic-ws) |
| 9049 | t))) | 9052 | t))) |
| 9050 | 9053 | ||
| @@ -9721,14 +9724,15 @@ This function might do hidden buffer changes." | |||
| 9721 | (setq after-paren-pos (point)))) | 9724 | (setq after-paren-pos (point)))) |
| 9722 | (while (and (looking-at c-type-decl-prefix-key) | 9725 | (while (and (looking-at c-type-decl-prefix-key) |
| 9723 | (if (and (c-major-mode-is 'c++-mode) | 9726 | (if (and (c-major-mode-is 'c++-mode) |
| 9724 | (match-beginning 3)) | 9727 | (match-beginning 4)) |
| 9725 | ;; If the third submatch matches in C++ then | 9728 | ;; If the fourth submatch matches in C++ then |
| 9726 | ;; we're looking at an identifier that's a | 9729 | ;; we're looking at an identifier that's a |
| 9727 | ;; prefix only if it specifies a member pointer. | 9730 | ;; prefix only if it specifies a member pointer. |
| 9728 | (when (progn (setq pos (point)) | 9731 | (when (progn (setq pos (point)) |
| 9729 | (setq got-identifier (c-forward-name))) | 9732 | (setq got-identifier (c-forward-name))) |
| 9730 | (setq name-start pos) | 9733 | (setq name-start pos) |
| 9731 | (if (looking-at "\\(::\\)") | 9734 | (if (save-match-data |
| 9735 | (looking-at "\\(::\\)")) | ||
| 9732 | ;; We only check for a trailing "::" and | 9736 | ;; We only check for a trailing "::" and |
| 9733 | ;; let the "*" that should follow be | 9737 | ;; let the "*" that should follow be |
| 9734 | ;; matched in the next round. | 9738 | ;; matched in the next round. |
| @@ -9749,7 +9753,8 @@ This function might do hidden buffer changes." | |||
| 9749 | (when (save-match-data | 9753 | (when (save-match-data |
| 9750 | (looking-at c-type-decl-operator-prefix-key)) | 9754 | (looking-at c-type-decl-operator-prefix-key)) |
| 9751 | (setq got-function-name-prefix t)) | 9755 | (setq got-function-name-prefix t)) |
| 9752 | (goto-char (match-end 1))) | 9756 | (goto-char (or (match-end 1) |
| 9757 | (match-end 2)))) | ||
| 9753 | (c-forward-syntactic-ws))) | 9758 | (c-forward-syntactic-ws))) |
| 9754 | 9759 | ||
| 9755 | (setq got-parens (> paren-depth 0)) | 9760 | (setq got-parens (> paren-depth 0)) |
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index f4dcbcda962..07479389c62 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el | |||
| @@ -3433,41 +3433,47 @@ possible for good performance." | |||
| 3433 | t (c-make-bare-char-alt (c-lang-const c-block-prefix-disallowed-chars) t)) | 3433 | t (c-make-bare-char-alt (c-lang-const c-block-prefix-disallowed-chars) t)) |
| 3434 | (c-lang-defvar c-block-prefix-charset (c-lang-const c-block-prefix-charset)) | 3434 | (c-lang-defvar c-block-prefix-charset (c-lang-const c-block-prefix-charset)) |
| 3435 | 3435 | ||
| 3436 | (c-lang-defconst c-type-decl-prefix-key | 3436 | (c-lang-defconst c-type-decl-prefix-keywords-key |
| 3437 | "Regexp matching any declarator operator that might precede the | 3437 | ;; Regexp matching any keyword operator that might precede the identifier in |
| 3438 | identifier in a declaration, e.g. the \"*\" in \"char *argv\". This | 3438 | ;; a declaration, e.g. "const" or nil. It doesn't test there is no "_" |
| 3439 | regexp should match \"(\" if parentheses are valid in declarators. | 3439 | ;; following the keyword. |
| 3440 | The end of the first submatch is taken as the end of the operator. | ||
| 3441 | Identifier syntax is in effect when this is matched (see | ||
| 3442 | `c-identifier-syntax-table')." | ||
| 3443 | t (if (or (c-lang-const c-type-modifier-kwds) (c-lang-const c-modifier-kwds)) | 3440 | t (if (or (c-lang-const c-type-modifier-kwds) (c-lang-const c-modifier-kwds)) |
| 3444 | (concat | 3441 | (concat |
| 3445 | (regexp-opt (c--delete-duplicates | 3442 | (regexp-opt (c--delete-duplicates |
| 3446 | (append (c-lang-const c-type-modifier-kwds) | 3443 | (append (c-lang-const c-type-modifier-kwds) |
| 3447 | (c-lang-const c-modifier-kwds)) | 3444 | (c-lang-const c-modifier-kwds)) |
| 3448 | :test 'string-equal) | 3445 | :test 'string-equal) |
| 3449 | t) | 3446 | t) |
| 3450 | "\\>") | 3447 | "\\>"))) |
| 3451 | ;; Default to a regexp that never matches. | 3448 | |
| 3452 | regexp-unmatchable) | 3449 | (c-lang-defconst c-type-decl-prefix-key |
| 3450 | "Regexp matching any declarator operator that might precede the | ||
| 3451 | identifier in a declaration, e.g. the \"*\" in \"char *argv\". This | ||
| 3452 | regexp should match \"(\" if parentheses are valid in declarators. | ||
| 3453 | The operator found is either the first submatch (if it is not a | ||
| 3454 | keyword) or the second submatch (if it is)." | ||
| 3455 | t (if (c-lang-const c-type-decl-prefix-keywords-key) | ||
| 3456 | (concat "\\(\\`a\\`\\)\\|" ; 1 - will never match. | ||
| 3457 | (c-lang-const c-type-decl-prefix-keywords-key) ; 2 | ||
| 3458 | "\\([^_]\\|$\\)") ; 3 | ||
| 3459 | "\\`a\\`") ;; Default to a regexp that never matches. | ||
| 3453 | ;; Check that there's no "=" afterwards to avoid matching tokens | 3460 | ;; Check that there's no "=" afterwards to avoid matching tokens |
| 3454 | ;; like "*=". | 3461 | ;; like "*=". |
| 3455 | (c objc) (concat "\\(" | 3462 | (c objc) (concat "\\(" ; 1 |
| 3456 | "[*(]" | 3463 | "[*(]" |
| 3457 | "\\|" | 3464 | "\\)\\|" |
| 3458 | (c-lang-const c-type-decl-prefix-key) | 3465 | (c-lang-const c-type-decl-prefix-keywords-key) ; 2 |
| 3459 | "\\)" | 3466 | "\\([^=_]\\|$\\)") ; 3 |
| 3460 | "\\([^=]\\|$\\)") | 3467 | c++ (concat "\\(" ; 1 |
| 3461 | c++ (concat "\\(" | ||
| 3462 | "&&" | 3468 | "&&" |
| 3463 | "\\|" | 3469 | "\\|" |
| 3464 | "\\.\\.\\." | 3470 | "\\.\\.\\." |
| 3465 | "\\|" | 3471 | "\\|" |
| 3466 | "[*(&~]" | 3472 | "[*(&~]" |
| 3473 | "\\)\\|\\(" ; 2 | ||
| 3474 | (c-lang-const c-type-decl-prefix-keywords-key) ; 3 | ||
| 3467 | "\\|" | 3475 | "\\|" |
| 3468 | (c-lang-const c-type-decl-prefix-key) | 3476 | (concat "\\(" ; 4 |
| 3469 | "\\|" | ||
| 3470 | (concat "\\(" ; 3 | ||
| 3471 | ;; If this matches there's special treatment in | 3477 | ;; If this matches there's special treatment in |
| 3472 | ;; `c-font-lock-declarators' and | 3478 | ;; `c-font-lock-declarators' and |
| 3473 | ;; `c-font-lock-declarations' that check for a | 3479 | ;; `c-font-lock-declarations' that check for a |
| @@ -3475,8 +3481,9 @@ Identifier syntax is in effect when this is matched (see | |||
| 3475 | (c-lang-const c-identifier-start) | 3481 | (c-lang-const c-identifier-start) |
| 3476 | "\\)") | 3482 | "\\)") |
| 3477 | "\\)" | 3483 | "\\)" |
| 3478 | "\\([^=]\\|$\\)") | 3484 | "\\([^=_]\\|$\\)") ; 5 |
| 3479 | pike "\\(\\*\\)\\([^=]\\|$\\)") | 3485 | pike "\\(\\*\\)\\([^=]\\|$\\)") |
| 3486 | |||
| 3480 | (c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key) | 3487 | (c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key) |
| 3481 | 'dont-doc) | 3488 | 'dont-doc) |
| 3482 | 3489 | ||