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.
+2014-12-19 Alan Mackenzie <acm@muc.de>
+
+ 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 <rudalics@gmx.at>
* textmodes/ispell.el (ispell-command-loop): Don't use
(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
(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)))
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.
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