summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2015-11-15 21:59:40 +0000
committerAlan Mackenzie <acm@muc.de>2015-11-15 21:59:40 +0000
commit4765d24e18a947678bfa63b0351f68931484273c (patch)
treef5d4e92fda24b2c8450b47a051662ba9b452cf5a
parentd99ccd6dd171a12cf528c03a4a956ad1751173c5 (diff)
downloademacs-4765d24e18a947678bfa63b0351f68931484273c.tar.gz
emacs-4765d24e18a947678bfa63b0351f68931484273c.tar.bz2
emacs-4765d24e18a947678bfa63b0351f68931484273c.zip
De-pessimize detection of C++ member initialization lists.
list/progmodes/cc-engine.el (c-back-over-list-of-member-inits): New macro. (c-back-over-member-initializers): Reformulate such that c-at-toplevel-p is only called when a construct "looks right" rather than continually. (c-guess-basic-syntax, CASE 5R): Add a check for the mode being C++ Mode.
-rw-r--r--lisp/progmodes/cc-engine.el89
1 files changed, 54 insertions, 35 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 6572cee2cc7..9e9bee8752f 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6666,49 +6666,65 @@ comment at the start of cc-engine.el for more info."
(or res (goto-char here))
res))
+(defmacro c-back-over-list-of-member-inits ()
+ ;; Go back over a list of elements, each looking like:
+ ;; <symbol> (<expression>) ,
+ ;; or <symbol> {<expression>} ,
+ ;; when we are putatively immediately after a comma. Stop when we don't see
+ ;; a comma. If either of <symbol> or bracketed <expression> is missing,
+ ;; throw nil to 'level. If the terminating } or ) is unmatched, throw nil
+ ;; to 'done. This is not a general purpose macro!
+ `(while (eq (char-before) ?,)
+ (backward-char)
+ (c-backward-syntactic-ws)
+ (when (not (memq (char-before) '(?\) ?})))
+ (throw 'level nil))
+ (when (not (c-go-list-backward))
+ (throw 'done nil))
+ (c-backward-syntactic-ws)
+ (when (not (c-simple-skip-symbol-backward))
+ (throw 'level nil))
+ (c-backward-syntactic-ws)))
+
(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
;; the function's arglist. Otherwise return nil, leaving point unchanged.
(let ((here (point))
(paren-state (c-parse-state))
- res)
-
+ pos level-plausible at-top-level res)
+ ;; Assume tentatively that we're at the top level. Try to go back to the
+ ;; colon we seek.
(setq res
(catch 'done
- (if (not (c-at-toplevel-p))
- (progn
- (while (not (c-at-toplevel-p))
- (goto-char (c-pull-open-brace paren-state)))
- (c-backward-syntactic-ws)
- (when (not (c-simple-skip-symbol-backward))
- (throw 'done nil))
- (c-backward-syntactic-ws))
- (c-backward-syntactic-ws)
- (when (memq (char-before) '(?\) ?}))
- (when (not (c-go-list-backward))
- (throw 'done nil))
- (c-backward-syntactic-ws))
- (when (c-simple-skip-symbol-backward)
- (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))
-
- (and
- (eq (char-before) ?:)
- (c-just-after-func-arglist-p))))
+ (setq level-plausible
+ (catch 'level
+ (c-backward-syntactic-ws)
+ (when (memq (char-before) '(?\) ?}))
+ (when (not (c-go-list-backward))
+ (throw 'done nil))
+ (c-backward-syntactic-ws))
+ (when (c-simple-skip-symbol-backward)
+ (c-backward-syntactic-ws))
+ (c-back-over-list-of-member-inits)
+ (and (eq (char-before) ?:)
+ (c-just-after-func-arglist-p))))
+
+ (while (and (not (and level-plausible
+ (setq at-top-level (c-at-toplevel-p))))
+ (setq pos (c-pull-open-brace paren-state))) ; might be a paren.
+ (setq level-plausible
+ (catch 'level
+ (goto-char pos)
+ (c-backward-syntactic-ws)
+ (when (not (c-simple-skip-symbol-backward))
+ (throw 'level nil))
+ (c-backward-syntactic-ws)
+ (c-back-over-list-of-member-inits)
+ (and (eq (char-before) ?:)
+ (c-just-after-func-arglist-p)))))
+ (and at-top-level level-plausible)))
(or res (goto-char here))
res))
@@ -8048,6 +8064,8 @@ brace.
Note that this function might do hidden buffer changes. See the
comment at the start of cc-engine.el for more info."
+ ;; Note to maintainers: this function consumes a great mass of CPU cycles.
+ ;; It's use should thus be minimised as far as possible.
(let ((paren-state (c-parse-state)))
(or (not (c-most-enclosing-brace paren-state))
(c-search-uplist-for-classkey paren-state))))
@@ -10052,7 +10070,8 @@ comment at the start of cc-engine.el for more info."
;; Note there is no limit on the backward search here, since member
;; init lists can, in practice, be very large.
((save-excursion
- (when (setq placeholder (c-back-over-member-initializers))
+ (when (and (c-major-mode-is 'c++-mode)
+ (setq placeholder (c-back-over-member-initializers)))
(setq tmp-pos (point))))
(if (= (c-point 'bosws) (1+ tmp-pos))
(progn