From 948fa912de164a1374c87e9206cddca741b7fa33 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Fri, 19 Dec 2014 18:35:14 +0000 Subject: [PATCH] Make C++11 uniform init syntax work. New keywords "final" and "override" cc-engine.el (c-back-over-member-initializer-braces): New function. (c-guess-basic-syntax): Set `containing-sex' and `lim' using the new function. cc-fonts.el (c-font-lock-declarations): Check more carefully for "are we at a declarator?" using c-back-over-member-initializers. cc-langs.el (c-type-modifier-kwds): include "final" and "override" in the C++ value. --- lisp/ChangeLog | 16 ++++++++++ lisp/progmodes/cc-engine.el | 58 +++++++++++++++++++++++++++------- lisp/progmodes/cc-fonts.el | 62 +++++++++++++++++++------------------ lisp/progmodes/cc-langs.el | 2 +- 4 files changed, 95 insertions(+), 43 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index feeab01a106..12530a997ba 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,19 @@ +2014-12-19 Alan Mackenzie + + Make C++11 uniform init syntax work. New keywords "final" and "override" + + * progmodes/cc-engine.el (c-back-over-member-initializer-braces): + New function. + (c-guess-basic-syntax): Set `containing-sex' and `lim' using the + new function. + + * progmodes/cc-fonts.el (c-font-lock-declarations): Check more + carefully for "are we at a declarator?" using + c-back-over-member-initializers. + + * progmodes/cc-langs.el (c-type-modifier-kwds): include "final" + and "override" in the C++ value. + 2014-12-19 Martin Rudalics * textmodes/ispell.el (ispell-command-loop): Don't use diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index a24cb3d7488..9a6e975dd93 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -6588,6 +6588,36 @@ comment at the start of cc-engine.el for more info." (prog1 (car ,ps) (setq ,ps (cdr ,ps))))) +(defun c-back-over-member-initializer-braces () + ;; Point is just after a closing brace/parenthesis. Try to parse this as a + ;; C++ member initializer list, going back to just after the introducing ":" + ;; and returning t. Otherwise return nil, leaving point unchanged. + (let ((here (point)) res) + (setq res + (catch 'done + (when (not (c-go-list-backward)) + (throw 'done nil)) + (c-backward-syntactic-ws) + (when (not (c-simple-skip-symbol-backward)) + (throw 'done nil)) + (c-backward-syntactic-ws) + + (while (eq (char-before) ?,) + (backward-char) + (c-backward-syntactic-ws) + (when (not (memq (char-before) '(?\) ?}))) + (throw 'done nil)) + (when (not (c-go-list-backward)) + (throw 'done nil)) + (c-backward-syntactic-ws) + (when (not (c-simple-skip-symbol-backward)) + (throw 'done nil)) + (c-backward-syntactic-ws)) + + (eq (char-before) ?:))) + (or res (goto-char here)) + res)) + (defun c-back-over-member-initializers () ;; Test whether we are in a C++ member initializer list, and if so, go back ;; to the introducing ":", returning the position of the opening paren of @@ -9588,22 +9618,26 @@ comment at the start of cc-engine.el for more info." (c-keyword-sym (match-string 1))))) ;; Init some position variables. - (if c-state-cache + (if paren-state (progn (setq containing-sexp (car paren-state) paren-state (cdr paren-state)) (if (consp containing-sexp) - (progn - (setq lim (cdr containing-sexp)) - (if (cdr c-state-cache) - ;; Ignore balanced paren. The next entry - ;; can't be another one. - (setq containing-sexp (car (cdr c-state-cache)) - paren-state (cdr paren-state)) - ;; If there is no surrounding open paren then - ;; put the last balanced pair back on paren-state. - (setq paren-state (cons containing-sexp paren-state) - containing-sexp nil))) + (save-excursion + (goto-char (cdr containing-sexp)) + (if (and (c-major-mode-is 'c++-mode) + (c-back-over-member-initializer-braces)) + (c-syntactic-skip-backward "^}" nil t)) + (setq lim (point)) + (if paren-state + ;; Ignore balanced paren. The next entry + ;; can't be another one. + (setq containing-sexp (car paren-state) + paren-state (cdr paren-state)) + ;; If there is no surrounding open paren then + ;; put the last balanced pair back on paren-state. + (setq paren-state (cons containing-sexp paren-state) + containing-sexp nil))) (setq lim (1+ containing-sexp)))) (setq lim (point-min))) diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 448e76427f2..d39376a2f03 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -1464,36 +1464,38 @@ casts and declarations are fontified. Used on level 2 and higher." c-recognize-knr-p) ; Strictly speaking, bogus, but it ; speeds up lisp.h tremendously. (save-excursion - (unless (or (eobp) - (looking-at "\\s(\\|\\s)")) - (forward-char)) - (setq bod-res (car (c-beginning-of-decl-1 decl-search-lim))) - (if (and (eq bod-res 'same) - (save-excursion - (c-backward-syntactic-ws) - (eq (char-before) ?\}))) - (c-beginning-of-decl-1 decl-search-lim)) - - ;; We're now putatively at the declaration. - (setq paren-state (c-parse-state)) - ;; At top level or inside a "{"? - (if (or (not (setq encl-pos - (c-most-enclosing-brace paren-state))) - (eq (char-after encl-pos) ?\{)) - (progn - (when (looking-at c-typedef-key) ; "typedef" - (setq is-typedef t) - (goto-char (match-end 0)) - (c-forward-syntactic-ws)) - ;; At a real declaration? - (if (memq (c-forward-type t) '(t known found decltype)) - (progn - (c-font-lock-declarators (point-max) t is-typedef) - nil) - ;; False alarm. Return t to go on to the next check. - (goto-char start-pos) - t)) - t)))))) + (if (c-back-over-member-initializers) + t ; Can't be at a declarator + (unless (or (eobp) + (looking-at "\\s(\\|\\s)")) + (forward-char)) + (setq bod-res (car (c-beginning-of-decl-1 decl-search-lim))) + (if (and (eq bod-res 'same) + (save-excursion + (c-backward-syntactic-ws) + (eq (char-before) ?\}))) + (c-beginning-of-decl-1 decl-search-lim)) + + ;; We're now putatively at the declaration. + (setq paren-state (c-parse-state)) + ;; At top level or inside a "{"? + (if (or (not (setq encl-pos + (c-most-enclosing-brace paren-state))) + (eq (char-after encl-pos) ?\{)) + (progn + (when (looking-at c-typedef-key) ; "typedef" + (setq is-typedef t) + (goto-char (match-end 0)) + (c-forward-syntactic-ws)) + ;; At a real declaration? + (if (memq (c-forward-type t) '(t known found decltype)) + (progn + (c-font-lock-declarators (point-max) t is-typedef) + nil) + ;; False alarm. Return t to go on to the next check. + (goto-char start-pos) + t)) + t))))))) ;; It was a false alarm. Check if we're in a label (or other ;; construct with `:' except bitfield) instead. diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index b93cc780732..31298d74e48 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -1741,7 +1741,7 @@ but they don't build a type of themselves. Unlike the keywords on not the type face." t nil c '("const" "restrict" "volatile") - c++ '("const" "constexpr" "noexcept" "volatile" "throw") + c++ '("const" "constexpr" "noexcept" "volatile" "throw" "final" "override") objc '("const" "volatile")) (c-lang-defconst c-opt-type-modifier-key -- 2.39.2