summaryrefslogtreecommitdiff
path: root/lisp/progmodes/cc-engine.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/cc-engine.el')
-rw-r--r--lisp/progmodes/cc-engine.el757
1 files changed, 429 insertions, 328 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 4bd85d740d9..d71a8299cf6 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -870,7 +870,7 @@ comment at the start of cc-engine.el for more info."
stack
;; Regexp which matches "for", "if", etc.
(cond-key (or c-opt-block-stmt-key
- "\\<\\>")) ; Matches nothing.
+ "a\\`")) ; Doesn't match anything.
;; Return value.
(ret 'same)
;; Positions of the last three sexps or bounds we've stopped at.
@@ -1080,12 +1080,15 @@ comment at the start of cc-engine.el for more info."
(let ((before-sws-pos (point))
;; The end position of the area to search for statement
;; barriers in this round.
- (maybe-after-boundary-pos pos))
+ (maybe-after-boundary-pos pos)
+ comma-delimited)
;; Go back over exactly one logical sexp, taking proper
;; account of macros and escaped EOLs.
(while
(progn
+ (setq comma-delimited (and (not comma-delim)
+ (eq (char-before) ?\,)))
(unless (c-safe (c-backward-sexp) t)
;; Give up if we hit an unbalanced block. Since the
;; stack won't be empty the code below will report a
@@ -1121,10 +1124,23 @@ comment at the start of cc-engine.el for more info."
;; Just gone back over a brace block?
((and
(eq (char-after) ?{)
+ (not comma-delimited)
(not (c-looking-at-inexpr-block lim nil t))
(save-excursion
(c-backward-token-2 1 t nil)
- (not (looking-at "=\\([^=]\\|$\\)"))))
+ (not (looking-at "=\\([^=]\\|$\\)")))
+ (or
+ (not c-opt-block-decls-with-vars-key)
+ (save-excursion
+ (c-backward-token-2 1 t nil)
+ (if (and (looking-at c-symbol-start)
+ (not (looking-at c-keywords-regexp)))
+ (c-backward-token-2 1 t nil))
+ (and
+ (not (looking-at
+ c-opt-block-decls-with-vars-key))
+ (or comma-delim
+ (not (eq (char-after) ?\,)))))))
(save-excursion
(c-forward-sexp) (point)))
;; Just gone back over some paren block?
@@ -1273,7 +1289,7 @@ comment at the start of cc-engine.el for more info."
(c-backward-syntactic-ws)
;; protect AWK post-inc/decrement operators, etc.
(and (not (c-at-vsemi-p (point)))
- (/= (skip-chars-backward "-+!*&~@`#") 0)))
+ (/= (skip-chars-backward "-.+!*&~@`#") 0)))
(setq pos (point)))
(goto-char pos)
ret)))
@@ -1690,35 +1706,35 @@ comment at the start of cc-engine.el for more info."
`(let ((beg ,beg) (end ,end))
(put-text-property beg end 'c-is-sws t)
,@(when (facep 'c-debug-is-sws-face)
- `((c-debug-add-face beg end 'c-debug-is-sws-face)))))
+ '((c-debug-add-face beg end 'c-debug-is-sws-face)))))
(defmacro c-put-in-sws (beg end)
;; This macro does a hidden buffer change.
`(let ((beg ,beg) (end ,end))
(put-text-property beg end 'c-in-sws t)
,@(when (facep 'c-debug-is-sws-face)
- `((c-debug-add-face beg end 'c-debug-in-sws-face)))))
+ '((c-debug-add-face beg end 'c-debug-in-sws-face)))))
(defmacro c-remove-is-sws (beg end)
;; This macro does a hidden buffer change.
`(let ((beg ,beg) (end ,end))
(remove-text-properties beg end '(c-is-sws nil))
,@(when (facep 'c-debug-is-sws-face)
- `((c-debug-remove-face beg end 'c-debug-is-sws-face)))))
+ '((c-debug-remove-face beg end 'c-debug-is-sws-face)))))
(defmacro c-remove-in-sws (beg end)
;; This macro does a hidden buffer change.
`(let ((beg ,beg) (end ,end))
(remove-text-properties beg end '(c-in-sws nil))
,@(when (facep 'c-debug-is-sws-face)
- `((c-debug-remove-face beg end 'c-debug-in-sws-face)))))
+ '((c-debug-remove-face beg end 'c-debug-in-sws-face)))))
(defmacro c-remove-is-and-in-sws (beg end)
;; This macro does a hidden buffer change.
`(let ((beg ,beg) (end ,end))
(remove-text-properties beg end '(c-is-sws nil c-in-sws nil))
,@(when (facep 'c-debug-is-sws-face)
- `((c-debug-remove-face beg end 'c-debug-is-sws-face)
+ '((c-debug-remove-face beg end 'c-debug-is-sws-face)
(c-debug-remove-face beg end 'c-debug-in-sws-face)))))
;; The type of literal position `end' is in a `before-change-functions'
@@ -3870,9 +3886,10 @@ comment at the start of cc-engine.el for more info."
(defmacro c-state-maybe-marker (place marker)
;; If PLACE is non-nil, return a marker marking it, otherwise nil.
;; We (re)use MARKER.
- `(and ,place
- (or ,marker (setq ,marker (make-marker)))
- (set-marker ,marker ,place)))
+ `(let ((-place- ,place))
+ (and -place-
+ (or ,marker (setq ,marker (make-marker)))
+ (set-marker ,marker -place-))))
(defun c-parse-state ()
;; This is a wrapper over `c-parse-state-1'. See that function for a
@@ -4286,6 +4303,41 @@ comment at the start of cc-engine.el for more info."
"\\w\\|\\s_\\|\\s\"\\|\\s|"
"\\w\\|\\s_\\|\\s\""))
+(defun c-forward-over-token (&optional balanced)
+ "Move forward over a token.
+Return t if we moved, nil otherwise (i.e. we were at EOB, or a
+non-token or BALANCED is non-nil and we can't move). If we
+are at syntactic whitespace, move over this in place of a token.
+
+If BALANCED is non-nil move over any balanced parens we are at, and never move
+out of an enclosing paren."
+ (let ((jump-syntax (if balanced
+ c-jump-syntax-balanced
+ c-jump-syntax-unbalanced))
+ (here (point)))
+ (condition-case nil
+ (cond
+ ((/= (point)
+ (progn (c-forward-syntactic-ws) (point)))
+ ;; If we're at whitespace, count this as the token.
+ t)
+ ((eobp) nil)
+ ((looking-at jump-syntax)
+ (goto-char (scan-sexps (point) 1))
+ t)
+ ((looking-at c-nonsymbol-token-regexp)
+ (goto-char (match-end 0))
+ t)
+ ((save-restriction
+ (widen)
+ (looking-at c-nonsymbol-token-regexp))
+ nil)
+ (t
+ (forward-char)
+ t))
+ (error (goto-char here)
+ nil))))
+
(defun c-forward-over-token-and-ws (&optional balanced)
"Move forward over a token and any following whitespace
Return t if we moved, nil otherwise (i.e. we were at EOB, or a
@@ -4297,35 +4349,8 @@ out of an enclosing paren.
This function differs from `c-forward-token-2' in that it will move forward
over the final token in a buffer, up to EOB."
- (let ((jump-syntax (if balanced
- c-jump-syntax-balanced
- c-jump-syntax-unbalanced))
- (here (point)))
- (when
- (condition-case nil
- (cond
- ((/= (point)
- (progn (c-forward-syntactic-ws) (point)))
- ;; If we're at whitespace, count this as the token.
- t)
- ((eobp) nil)
- ((looking-at jump-syntax)
- (goto-char (scan-sexps (point) 1))
- t)
- ((looking-at c-nonsymbol-token-regexp)
- (goto-char (match-end 0))
- t)
- ((save-restriction
- (widen)
- (looking-at c-nonsymbol-token-regexp))
- nil)
- (t
- (forward-char)
- t))
- (error (goto-char here)
- nil))
- (c-forward-syntactic-ws)
- t)))
+ (prog1 (c-forward-over-token balanced)
+ (c-forward-syntactic-ws)))
(defun c-forward-token-2 (&optional count balanced limit)
"Move forward by tokens.
@@ -4727,56 +4752,6 @@ comment at the start of cc-engine.el for more info."
(defvar safe-pos-list) ; bound in c-syntactic-skip-backward
-(defsubst c-ssb-lit-begin ()
- ;; Return the start of the literal point is in, or nil.
- ;; We read and write the variables `safe-pos', `safe-pos-list', `state'
- ;; bound in the caller.
-
- ;; Use `parse-partial-sexp' from a safe position down to the point to check
- ;; if it's outside comments and strings.
- (save-excursion
- (let ((pos (point)) safe-pos state)
- ;; Pick a safe position as close to the point as possible.
- ;;
- ;; FIXME: Consult `syntax-ppss' here if our cache doesn't give a good
- ;; position.
-
- (while (and safe-pos-list
- (> (car safe-pos-list) (point)))
- (setq safe-pos-list (cdr safe-pos-list)))
- (unless (setq safe-pos (car-safe safe-pos-list))
- (setq safe-pos (max (or (c-safe-position
- (point) (c-parse-state))
- 0)
- (point-min))
- safe-pos-list (list safe-pos)))
-
- ;; Cache positions along the way to use if we have to back up more. We
- ;; cache every closing paren on the same level. If the paren cache is
- ;; relevant in this region then we're typically already on the same
- ;; level as the target position. Note that we might cache positions
- ;; after opening parens in case safe-pos is in a nested list. That's
- ;; both uncommon and harmless.
- (while (progn
- (setq state (parse-partial-sexp
- safe-pos pos 0))
- (< (point) pos))
- (setq safe-pos (point)
- safe-pos-list (cons safe-pos safe-pos-list)))
-
- ;; If the state contains the start of the containing sexp we cache that
- ;; position too, so that parse-partial-sexp in the next run has a bigger
- ;; chance of starting at the same level as the target position and thus
- ;; will get more good safe positions into the list.
- (if (elt state 1)
- (setq safe-pos (1+ (elt state 1))
- safe-pos-list (cons safe-pos safe-pos-list)))
-
- (if (or (elt state 3) (elt state 4))
- ;; Inside string or comment. Continue search at the
- ;; beginning of it.
- (elt state 8)))))
-
(defun c-syntactic-skip-backward (skip-chars &optional limit paren-level)
"Like `skip-chars-backward' but only look at syntactically relevant chars,
i.e. don't stop at positions inside syntactic whitespace or string
@@ -4793,108 +4768,110 @@ Non-nil is returned if the point moved, nil otherwise.
Note that this function might do hidden buffer changes. See the
comment at the start of cc-engine.el for more info."
-
- (c-self-bind-state-cache
- (let ((start (point))
- ;; A list of syntactically relevant positions in descending
- ;; order. It's used to avoid scanning repeatedly over
- ;; potentially large regions with `parse-partial-sexp' to verify
- ;; each position. Used in `c-ssb-lit-begin'
- safe-pos-list
+ (let* ((start (point))
;; The result from `c-beginning-of-macro' at the start position or the
- ;; start position itself if it isn't within a macro. Evaluated on
- ;; demand.
- start-macro-beg
+ ;; start position itself if it isn't within a macro.
+ (start-macro-beg
+ (save-excursion
+ (goto-char start)
+ (c-beginning-of-macro limit)
+ (point)))
+ lit-beg
;; The earliest position after the current one with the same paren
;; level. Used only when `paren-level' is set.
- lit-beg
- (paren-level-pos (point)))
+ (paren-level-pos (point))
+ ;; Whether we can optimize with an early `c-backward-syntactic-ws'.
+ (opt-ws (string-match "^\\^[^ \t\n\r]+$" skip-chars)))
- (while
- (progn
- ;; The next loop "tries" to find the end point each time round,
- ;; loops when it hasn't succeeded.
- (while
- (and
- (let ((pos (point)))
- (while (and
- (< (skip-chars-backward skip-chars limit) 0)
- ;; Don't stop inside a literal.
- (when (setq lit-beg (c-ssb-lit-begin))
+ ;; In the next while form, we only loop when `skip-chars' is something
+ ;; like "^/" and we've stopped at the end of a block comment.
+ (while
+ (progn
+ ;; The next loop "tries" to find the end point each time round,
+ ;; loops when it's ended up at the wrong level of nesting.
+ (while
+ (and
+ ;; Optimize for, in particular, large blocks of comments from
+ ;; `comment-region'.
+ (progn (when opt-ws
+ (c-backward-syntactic-ws)
+ (setq paren-level-pos (point)))
+ t)
+ ;; Move back to a candidate end point which isn't in a literal
+ ;; or in a macro we didn't start in.
+ (let ((pos (point))
+ macro-start)
+ (while (and
+ (< (skip-chars-backward skip-chars limit) 0)
+ (or
+ (when (setq lit-beg (c-literal-start))
(goto-char lit-beg)
- t)))
- (< (point) pos))
-
- (let ((pos (point)) state-2 pps-end-pos)
-
- (cond
- ((and paren-level
- (save-excursion
- (setq state-2 (parse-partial-sexp
- pos paren-level-pos -1)
- pps-end-pos (point))
- (/= (car state-2) 0)))
- ;; Not at the right level.
-
- (if (and (< (car state-2) 0)
- ;; We stop above if we go out of a paren.
- ;; Now check whether it precedes or is
- ;; nested in the starting sexp.
- (save-excursion
- (setq state-2
- (parse-partial-sexp
- pps-end-pos paren-level-pos
- nil nil state-2))
- (< (car state-2) 0)))
-
- ;; We've stopped short of the starting position
- ;; so the hit was inside a nested list. Go up
- ;; until we are at the right level.
- (condition-case nil
- (progn
- (goto-char (scan-lists pos -1
- (- (car state-2))))
- (setq paren-level-pos (point))
- (if (and limit (>= limit paren-level-pos))
- (progn
- (goto-char limit)
- nil)
- t))
- (error
- (goto-char (or limit (point-min)))
- nil))
-
- ;; The hit was outside the list at the start
- ;; position. Go to the start of the list and exit.
- (goto-char (1+ (elt state-2 1)))
- nil))
-
- ((c-beginning-of-macro limit)
- ;; Inside a macro.
- (if (< (point)
- (or start-macro-beg
- (setq start-macro-beg
- (save-excursion
- (goto-char start)
- (c-beginning-of-macro limit)
- (point)))))
- t
-
- ;; It's inside the same macro we started in so it's
- ;; a relevant match.
- (goto-char pos)
- nil))))))
-
- (> (point)
- (progn
- ;; Skip syntactic ws afterwards so that we don't stop at the
- ;; end of a comment if `skip-chars' is something like "^/".
- (c-backward-syntactic-ws)
- (point)))))
+ t)
+ ;; Don't stop inside a macro we didn't start in.
+ (when
+ (save-excursion
+ (and (c-beginning-of-macro limit)
+ (< (point) start-macro-beg)
+ (setq macro-start (point))))
+ (goto-char macro-start))))
+ (when opt-ws
+ (c-backward-syntactic-ws)))
+ (< (point) pos))
+
+ ;; Check whether we're at the wrong level of nesting (when
+ ;; `paren-level' is non-nil).
+ (let ((pos (point)) state-2 pps-end-pos)
+ (when
+ (and paren-level
+ (save-excursion
+ (setq state-2 (parse-partial-sexp
+ pos paren-level-pos -1)
+ pps-end-pos (point))
+ (/= (car state-2) 0)))
+ ;; Not at the right level.
+ (if (and (< (car state-2) 0)
+ ;; We stop above if we go out of a paren.
+ ;; Now check whether it precedes or is
+ ;; nested in the starting sexp.
+ (save-excursion
+ (setq state-2
+ (parse-partial-sexp
+ pps-end-pos paren-level-pos
+ nil nil state-2))
+ (< (car state-2) 0)))
+
+ ;; We've stopped short of the starting position
+ ;; so the hit was inside a nested list. Go up
+ ;; until we are at the right level.
+ (condition-case nil
+ (progn
+ (goto-char (scan-lists pos -1
+ (- (car state-2))))
+ (setq paren-level-pos (point))
+ (if (and limit (>= limit paren-level-pos))
+ (progn
+ (goto-char limit)
+ nil)
+ t))
+ (error
+ (goto-char (or limit (point-min)))
+ nil))
+
+ ;; The hit was outside the list at the start
+ ;; position. Go to the start of the list and exit.
+ (goto-char (1+ (elt state-2 1)))
+ nil)))))
+
+ (> (point)
+ (progn
+ ;; Skip syntactic ws afterwards so that we don't stop at the
+ ;; end of a comment if `skip-chars' is something like "^/".
+ (c-backward-syntactic-ws)
+ (point)))))
- ;; We might want to extend this with more useful return values in
- ;; the future.
- (/= (point) start))))
+ ;; We might want to extend this with more useful return values in
+ ;; the future.
+ (/= (point) start)))
;; The following is an alternative implementation of
;; `c-syntactic-skip-backward' that uses backward movement to keep
@@ -5177,6 +5154,9 @@ comment at the start of cc-engine.el for more info."
(defsubst c-determine-limit-get-base (start try-size)
;; Get a "safe place" approximately TRY-SIZE characters before START.
;; This defsubst doesn't preserve point.
+ (goto-char start)
+ (c-backward-syntactic-ws)
+ (setq start (point))
(let* ((pos (max (- start try-size) (point-min)))
(s (c-state-semi-pp-to-literal pos))
(cand (or (car (cddr s)) pos)))
@@ -5186,9 +5166,9 @@ comment at the start of cc-engine.el for more info."
(point))))
(defun c-determine-limit (how-far-back &optional start try-size)
- ;; Return a buffer position HOW-FAR-BACK non-literal characters from
- ;; START (default point). The starting position, either point or
- ;; START may not be in a comment or string.
+ ;; Return a buffer position approximately HOW-FAR-BACK non-literal
+ ;; characters from START (default point). The starting position, either
+ ;; point or START may not be in a comment or string.
;;
;; The position found will not be before POINT-MIN and won't be in a
;; literal.
@@ -5206,6 +5186,12 @@ comment at the start of cc-engine.el for more info."
(s (parse-partial-sexp pos pos)) ; null state.
stack elt size
(count 0))
+ ;; Optimization for large blocks of comments, particularly those being
+ ;; created by `comment-region'.
+ (goto-char pos)
+ (forward-comment try-size)
+ (setq pos (point))
+
(while (< pos start)
;; Move forward one literal each time round this loop.
;; Move forward to the start of a comment or string.
@@ -5248,6 +5234,10 @@ comment at the start of cc-engine.el for more info."
;; Have we found enough yet?
(cond
+ ((null elt) ; No non-literal characters found.
+ (if (> base (point-min))
+ (c-determine-limit how-far-back base (* 2 try-size))
+ (point-min)))
((>= count how-far-back)
(+ (car elt) (- count how-far-back)))
((eq base (point-min))
@@ -5255,7 +5245,7 @@ comment at the start of cc-engine.el for more info."
((> base (- start try-size)) ; Can only happen if we hit point-min.
(car elt))
(t
- (c-determine-limit (- how-far-back count) base try-size))))))
+ (c-determine-limit (- how-far-back count) base (* 2 try-size)))))))
(defun c-determine-+ve-limit (how-far &optional start-pos)
;; Return a buffer position about HOW-FAR non-literal characters forward
@@ -6890,8 +6880,8 @@ comment at the start of cc-engine.el for more info."
`(let (res)
(setq c-last-identifier-range nil)
(while (if (setq res ,(if (eq type 'type)
- `(c-forward-type)
- `(c-forward-name)))
+ '(c-forward-type)
+ '(c-forward-name)))
nil
(cond ((looking-at c-keywords-regexp)
(c-forward-keyword-clause 1))
@@ -6901,8 +6891,8 @@ comment at the start of cc-engine.el for more info."
(when (memq res '(t known found prefix maybe))
(when c-record-type-identifiers
,(if (eq type 'type)
- `(c-record-type-id c-last-identifier-range)
- `(c-record-ref-id c-last-identifier-range)))
+ '(c-record-type-id c-last-identifier-range)
+ '(c-record-ref-id c-last-identifier-range)))
t)))
(defmacro c-forward-id-comma-list (type update-safe-pos)
@@ -6913,7 +6903,7 @@ comment at the start of cc-engine.el for more info."
;; This macro might do hidden buffer changes.
`(while (and (progn
,(when update-safe-pos
- `(setq safe-pos (point)))
+ '(setq safe-pos (point)))
(eq (char-after) ?,))
(progn
(forward-char)
@@ -7138,7 +7128,7 @@ comment at the start of cc-engine.el for more info."
(progn
(c-forward-syntactic-ws)
(when (or (and c-record-type-identifiers all-types)
- (not (equal c-inside-<>-type-key "\\(\\<\\>\\)")))
+ (not (equal c-inside-<>-type-key "\\(a\\`\\)")))
(c-forward-syntactic-ws)
(cond
((eq (char-after) ??)
@@ -7688,7 +7678,7 @@ comment at the start of cc-engine.el for more info."
(c-record-type-id id-range))
(unless res
(setq res 'found)))
- (setq res (if (c-check-type id-start id-end)
+ (setq res (if (c-check-qualified-type id-start)
;; It's an identifier that has been used as
;; a type somewhere else.
'found
@@ -7700,7 +7690,7 @@ comment at the start of cc-engine.el for more info."
(c-forward-syntactic-ws)
(setq res
(if (eq (char-after) ?\()
- (if (c-check-type id-start id-end)
+ (if (c-check-qualified-type id-start)
;; It's an identifier that has been used as
;; a type somewhere else.
'found
@@ -7825,6 +7815,37 @@ comment at the start of cc-engine.el for more info."
(prog1 (car ,ps)
(setq ,ps (cdr ,ps)))))
+(defun c-forward-over-compound-identifier ()
+ ;; Go over a possibly compound identifier, such as C++'s Foo::Bar::Baz,
+ ;; returning that identifier (with any syntactic WS removed). Return nil if
+ ;; we're not at an identifier.
+ (when (c-on-identifier)
+ (let ((consolidated "") (consolidated-:: "")
+ start end)
+ (while
+ (progn
+ (setq start (point))
+ (c-forward-over-token)
+ (setq consolidated
+ (concat consolidated-::
+ (buffer-substring-no-properties start (point))))
+ (c-forward-syntactic-ws)
+ (and c-opt-identifier-concat-key
+ (looking-at c-opt-identifier-concat-key)
+ (progn
+ (setq start (point))
+ (c-forward-over-token)
+ (setq end (point))
+ (c-forward-syntactic-ws)
+ (and
+ (c-on-identifier)
+ (setq consolidated-::
+ (concat consolidated
+ (buffer-substring-no-properties start end))))))))
+ (if (equal consolidated "")
+ nil
+ consolidated))))
+
(defun c-back-over-compound-identifier ()
;; Point is putatively just after a "compound identifier", i.e. something
;; looking (in C++) like this "FQN::of::base::Class". Move to the start of
@@ -7849,6 +7870,21 @@ comment at the start of cc-engine.el for more info."
(goto-char end)
t)))
+(defun c-check-qualified-type (from)
+ ;; Look up successive tails of a (possibly) qualified type in
+ ;; `c-found-types'. If one of them matches, return it, else return nil.
+ (save-excursion
+ (goto-char from)
+ (let ((compound (c-forward-over-compound-identifier)))
+ (when compound
+ (while (and c-opt-identifier-concat-key
+ (> (length compound) 0)
+ (not (gethash compound c-found-types))
+ (string-match c-opt-identifier-concat-key compound))
+ (setq compound (substring compound (match-end 0))))
+ (and (gethash compound c-found-types)
+ compound)))))
+
(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 ":"
@@ -7888,7 +7924,7 @@ comment at the start of cc-engine.el for more info."
;; 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) ?,)
+ '(while (eq (char-before) ?,)
(backward-char)
(c-backward-syntactic-ws)
(when (not (memq (char-before) '(?\) ?})))
@@ -8550,7 +8586,7 @@ comment at the start of cc-engine.el for more info."
;; Skip over type decl prefix operators. (Note similar code in
;; `c-forward-declarator'.)
(if (and c-recognize-typeless-decls
- (equal c-type-decl-prefix-key "\\<\\>"))
+ (equal c-type-decl-prefix-key "a\\`")) ; Regexp which doesn't match
(when (eq (char-after) ?\()
(progn
(setq paren-depth (1+ paren-depth))
@@ -8609,6 +8645,7 @@ comment at the start of cc-engine.el for more info."
;; construct here in C, since we want to recognize this as a
;; typeless function declaration.
(not (and (c-major-mode-is 'c-mode)
+ (not got-prefix)
(or (eq context 'top) make-top)
(eq (char-after) ?\)))))
(if (eq (char-after) ?\))
@@ -8638,31 +8675,39 @@ comment at the start of cc-engine.el for more info."
;; (con|de)structors in C++ and `c-typeless-decl-kwds'
;; style declarations. That isn't applicable in an
;; arglist context, though.
- (when (and (= paren-depth 1)
- (not got-prefix-before-parens)
- (not (eq at-type t))
- (or backup-at-type
- maybe-typeless
- backup-maybe-typeless
- (when c-recognize-typeless-decls
- (and (memq context '(nil top))
- ;; Deal with C++11's "copy-initialization"
- ;; where we have <type>(<constant>), by
- ;; contrasting with a typeless
- ;; <name>(<type><parameter>, ...).
- (save-excursion
- (goto-char after-paren-pos)
- (c-forward-syntactic-ws)
- (or (c-forward-type)
- ;; Recognize a top-level typeless
- ;; function declaration in C.
- (and (c-major-mode-is 'c-mode)
- (or (eq context 'top) make-top)
- (eq (char-after) ?\))))))))
- (setq pos (c-up-list-forward (point)))
- (eq (char-before pos) ?\)))
+ (when (and (> paren-depth 0)
+ (not got-prefix-before-parens)
+ (not (eq at-type t))
+ (or backup-at-type
+ maybe-typeless
+ backup-maybe-typeless
+ (when c-recognize-typeless-decls
+ (and (memq context '(nil top))
+ ;; Deal with C++11's "copy-initialization"
+ ;; where we have <type>(<constant>), by
+ ;; contrasting with a typeless
+ ;; <name>(<type><parameter>, ...).
+ (save-excursion
+ (goto-char after-paren-pos)
+ (c-forward-syntactic-ws)
+ (or (c-forward-type)
+ ;; Recognize a top-level typeless
+ ;; function declaration in C.
+ (and (c-major-mode-is 'c-mode)
+ (or (eq context 'top) make-top)
+ (eq (char-after) ?\))))))))
+ (let ((pd paren-depth))
+ (setq pos (point))
+ (catch 'pd
+ (while (> pd 0)
+ (setq pos (c-up-list-forward pos))
+ (when (or (null pos)
+ (not (eq (char-before pos) ?\))))
+ (throw 'pd nil))
+ (goto-char pos)
+ (setq pd (1- pd)))
+ t)))
(c-fdoc-shift-type-backward)
- (goto-char pos)
t)))
(c-forward-syntactic-ws))
@@ -9531,11 +9576,10 @@ comment at the start of cc-engine.el for more info."
;; back we should search.
;;
;; This function might do hidden buffer changes.
- (c-with-syntax-table c++-template-syntax-table
- (c-backward-token-2 0 t lim)
- (while (and (or (looking-at c-symbol-start)
- (looking-at "[<,]\\|::"))
- (zerop (c-backward-token-2 1 t lim))))))
+ (c-backward-token-2 0 t lim)
+ (while (and (or (looking-at c-symbol-start)
+ (looking-at "[<,]\\|::"))
+ (zerop (c-backward-token-2 1 t lim)))))
(defun c-in-method-def-p ()
;; Return nil if we aren't in a method definition, otherwise the
@@ -9833,9 +9877,15 @@ comment at the start of cc-engine.el for more info."
;; This function might do hidden buffer changes.
(save-excursion
(and (zerop (c-backward-token-2 1 t lim))
+ (if (looking-at c-block-stmt-hangon-key)
+ (zerop (c-backward-token-2 1 t lim))
+ t)
(or (looking-at c-block-stmt-1-key)
(and (eq (char-after) ?\()
(zerop (c-backward-token-2 1 t lim))
+ (if (looking-at c-block-stmt-hangon-key)
+ (zerop (c-backward-token-2 1 t lim))
+ t)
(or (looking-at c-block-stmt-2-key)
(looking-at c-block-stmt-1-2-key))))
(point))))
@@ -9905,11 +9955,10 @@ comment at the start of cc-engine.el for more info."
(and (c-safe (c-backward-sexp) t)
(looking-at c-opt-op-identifier-prefix)))
(and (eq (char-before) ?<)
- (c-with-syntax-table c++-template-syntax-table
- (if (c-safe (goto-char (c-up-list-forward (point))))
- t
- (goto-char (point-max))
- nil)))))
+ (if (c-safe (goto-char (c-up-list-forward (point))))
+ t
+ (goto-char (point-max))
+ nil))))
(setq base (point)))
(while (and
@@ -10002,28 +10051,25 @@ comment at the start of cc-engine.el for more info."
;; potentially can search over a large amount of text.). Take special
;; pains not to get mislead by C++'s "operator=", and the like.
(if (and (eq move 'previous)
- (c-with-syntax-table (if (c-major-mode-is 'c++-mode)
- c++-template-syntax-table
- (syntax-table))
- (save-excursion
- (and
- (progn
- (while ; keep going back to "[;={"s until we either find
- ; no more, or get to one which isn't an "operator ="
- (and (c-syntactic-re-search-forward "[;={]" start t t t)
- (eq (char-before) ?=)
- c-overloadable-operators-regexp
- c-opt-op-identifier-prefix
- (save-excursion
- (eq (c-backward-token-2) 0)
- (looking-at c-overloadable-operators-regexp)
- (eq (c-backward-token-2) 0)
- (looking-at c-opt-op-identifier-prefix))))
- (eq (char-before) ?=))
- (c-syntactic-re-search-forward "[;{]" start t t)
- (eq (char-before) ?{)
- (c-safe (goto-char (c-up-list-forward (point))) t)
- (not (c-syntactic-re-search-forward ";" start t t))))))
+ (save-excursion
+ (and
+ (progn
+ (while ; keep going back to "[;={"s until we either find
+ ; no more, or get to one which isn't an "operator ="
+ (and (c-syntactic-re-search-forward "[;={]" start t t t)
+ (eq (char-before) ?=)
+ c-overloadable-operators-regexp
+ c-opt-op-identifier-prefix
+ (save-excursion
+ (eq (c-backward-token-2) 0)
+ (looking-at c-overloadable-operators-regexp)
+ (eq (c-backward-token-2) 0)
+ (looking-at c-opt-op-identifier-prefix))))
+ (eq (char-before) ?=))
+ (c-syntactic-re-search-forward "[;{]" start t t)
+ (eq (char-before) ?{)
+ (c-safe (goto-char (c-up-list-forward (point))) t)
+ (not (c-syntactic-re-search-forward ";" start t t)))))
(cons 'same nil)
(cons move nil)))))
@@ -10038,10 +10084,7 @@ comment at the start of cc-engine.el for more info."
;; `c-end-of-macro' instead in those cases.
;;
;; This function might do hidden buffer changes.
- (let ((start (point))
- (decl-syntax-table (if (c-major-mode-is 'c++-mode)
- c++-template-syntax-table
- (syntax-table))))
+ (let ((start (point)))
(catch 'return
(c-search-decl-header-end)
@@ -10062,34 +10105,32 @@ comment at the start of cc-engine.el for more info."
(throw 'return nil)))
(if (or (not c-opt-block-decls-with-vars-key)
(save-excursion
- (c-with-syntax-table decl-syntax-table
- (let ((lim (point)))
- (goto-char start)
- (not (and
- ;; Check for `c-opt-block-decls-with-vars-key'
- ;; before the first paren.
- (c-syntactic-re-search-forward
- (concat "[;=([{]\\|\\("
- c-opt-block-decls-with-vars-key
- "\\)")
- lim t t t)
- (match-beginning 1)
- (not (eq (char-before) ?_))
- ;; Check that the first following paren is
- ;; the block.
- (c-syntactic-re-search-forward "[;=([{]"
- lim t t t)
- (eq (char-before) ?{)))))))
+ (let ((lim (point)))
+ (goto-char start)
+ (not (and
+ ;; Check for `c-opt-block-decls-with-vars-key'
+ ;; before the first paren.
+ (c-syntactic-re-search-forward
+ (concat "[;=\(\[{]\\|\\("
+ c-opt-block-decls-with-vars-key
+ "\\)")
+ lim t t t)
+ (match-beginning 1)
+ (not (eq (char-before) ?_))
+ ;; Check that the first following paren is
+ ;; the block.
+ (c-syntactic-re-search-forward "[;=\(\[{]"
+ lim t t t)
+ (eq (char-before) ?{))))))
;; The declaration doesn't have any of the
;; `c-opt-block-decls-with-vars' keywords in the
;; beginning, so it ends here at the end of the block.
(throw 'return t)))
- (c-with-syntax-table decl-syntax-table
- (while (progn
- (if (eq (char-before) ?\;)
- (throw 'return t))
- (c-syntactic-re-search-forward ";" nil 'move t))))
+ (while (progn
+ (if (eq (char-before) ?\;)
+ (throw 'return t))
+ (c-syntactic-re-search-forward ";" nil 'move t)))
nil)))
(defun c-looking-at-decl-block (_containing-sexp goto-start &optional limit)
@@ -10169,7 +10210,7 @@ comment at the start of cc-engine.el for more info."
;; legal because it's part of a "compound keyword" like
;; "enum class". Of course, if c-after-brace-list-key
;; is nil, we can skip the test.
- (or (equal c-after-brace-list-key "\\<\\>")
+ (or (equal c-after-brace-list-key "a\\`") ; Regexp which doesn't match
(save-match-data
(save-excursion
(not
@@ -10520,6 +10561,10 @@ comment at the start of cc-engine.el for more info."
((and class-key
(looking-at class-key))
(setq braceassignp nil))
+ ((and c-has-compound-literals
+ (looking-at c-return-key))
+ (setq braceassignp t)
+ nil)
((eq (char-after) ?=)
;; We've seen a =, but must check earlier tokens so
;; that it isn't something that should be ignored.
@@ -10558,9 +10603,14 @@ comment at the start of cc-engine.el for more info."
))))
nil)
(t t))))))
- (if (and (eq braceassignp 'dontknow)
- (/= (c-backward-token-2 1 t lim) 0))
- (setq braceassignp nil)))
+ (when (and (eq braceassignp 'dontknow)
+ (/= (c-backward-token-2 1 t lim) 0))
+ (if (save-excursion
+ (and c-has-compound-literals
+ (eq (c-backward-token-2 1 nil lim) 0)
+ (eq (char-after) ?\()))
+ (setq braceassignp t)
+ (setq braceassignp nil))))
(cond
(braceassignp
@@ -10635,7 +10685,8 @@ comment at the start of cc-engine.el for more info."
;; This will pick up brace list declarations.
(save-excursion
(goto-char containing-sexp)
- (c-backward-over-enum-header))
+ (and (c-backward-over-enum-header)
+ (point)))
;; this will pick up array/aggregate init lists, even if they are nested.
(save-excursion
(let ((bufpos t)
@@ -10925,7 +10976,7 @@ comment at the start of cc-engine.el for more info."
(c-on-identifier)))
(and c-special-brace-lists
(c-looking-at-special-brace-list))
- (and (c-major-mode-is 'c++-mode)
+ (and c-has-compound-literals
(save-excursion
(goto-char block-follows)
(not (c-looking-at-statement-block)))))
@@ -11260,9 +11311,7 @@ comment at the start of cc-engine.el for more info."
(cdr (assoc (match-string 1)
c-other-decl-block-key-in-symbols-alist))
(max (c-point 'boi paren-pos) (point))))
- ((save-excursion
- (goto-char paren-pos)
- (c-looking-at-or-maybe-in-bracelist containing-sexp))
+ ((c-inside-bracelist-p paren-pos paren-state nil)
(if (save-excursion
(goto-char paren-pos)
(c-looking-at-statement-block))
@@ -11354,10 +11403,9 @@ comment at the start of cc-engine.el for more info."
;; CASE B.2: brace-list-open
((or (consp special-brace-list)
- (consp
- (c-looking-at-or-maybe-in-bracelist
- containing-sexp beg-of-same-or-containing-stmt))
- )
+ (c-inside-bracelist-p (point)
+ (cons containing-sexp paren-state)
+ nil))
;; The most semantically accurate symbol here is
;; brace-list-open, but we normally report it simply as a
;; statement-cont. The reason is that one normally adjusts
@@ -11468,17 +11516,15 @@ comment at the start of cc-engine.el for more info."
((and (c-major-mode-is 'c++-mode)
(save-excursion
(goto-char indent-point)
- (c-with-syntax-table c++-template-syntax-table
- (setq placeholder (c-up-list-backward)))
+ (setq placeholder (c-up-list-backward))
(and placeholder
(eq (char-after placeholder) ?<)
(/= (char-before placeholder) ?<)
(progn
(goto-char (1+ placeholder))
(not (looking-at c-<-op-cont-regexp))))))
- (c-with-syntax-table c++-template-syntax-table
- (goto-char placeholder)
- (c-beginning-of-statement-1 containing-sexp t))
+ (goto-char placeholder)
+ (c-beginning-of-statement-1 containing-sexp t)
(if (save-excursion
(c-backward-syntactic-ws containing-sexp)
(eq (char-before) ?<))
@@ -12138,21 +12184,38 @@ comment at the start of cc-engine.el for more info."
;; NB: No c-after-special-operator-id stuff in this
;; clause - we assume only C++ needs it.
(c-syntactic-skip-backward "^;,=" lim t))
+ (setq placeholder (point))
(memq (char-before) '(?, ?= ?<)))
(cond
+ ;; CASE 5D.6: Something like C++11's "using foo = <type-exp>"
+ ((save-excursion
+ (and (eq (char-before placeholder) ?=)
+ (goto-char placeholder)
+ (eq (c-backward-token-2 1 nil lim) 0)
+ (eq (point) (1- placeholder))
+ (eq (c-beginning-of-statement-1 lim) 'same)
+ (looking-at c-equals-type-clause-key)
+ (let ((preserve-point (point)))
+ (when
+ (and
+ (eq (c-forward-token-2 1 nil nil) 0)
+ (c-on-identifier))
+ (setq placeholder preserve-point)))))
+ (c-add-syntax
+ 'statement-cont placeholder)
+ )
+
;; CASE 5D.3: perhaps a template list continuation?
((and (c-major-mode-is 'c++-mode)
(save-excursion
(save-restriction
- (c-with-syntax-table c++-template-syntax-table
- (goto-char indent-point)
- (setq placeholder (c-up-list-backward))
- (and placeholder
- (eq (char-after placeholder) ?<))))))
- (c-with-syntax-table c++-template-syntax-table
- (goto-char placeholder)
- (c-beginning-of-statement-1 lim t))
+ (goto-char indent-point)
+ (setq placeholder (c-up-list-backward))
+ (and placeholder
+ (eq (char-after placeholder) ?<)))))
+ (goto-char placeholder)
+ (c-beginning-of-statement-1 lim t)
(if (save-excursion
(c-backward-syntactic-ws lim)
(eq (char-before) ?<))
@@ -12176,8 +12239,7 @@ comment at the start of cc-engine.el for more info."
(and (looking-at c-class-key)
(zerop (c-forward-token-2 2 nil indent-point))
(if (eq (char-after) ?<)
- (c-with-syntax-table c++-template-syntax-table
- (zerop (c-forward-token-2 1 t indent-point)))
+ (zerop (c-forward-token-2 1 t indent-point))
t)
(eq (char-after) ?:))))
(goto-char placeholder)
@@ -12284,7 +12346,18 @@ comment at the start of cc-engine.el for more info."
;; The '}' is unbalanced.
nil
(c-end-of-decl-1)
- (>= (point) indent-point))))))
+ (>= (point) indent-point))))
+ ;; Check that we only have one brace block here, i.e. that we
+ ;; don't have something like a function with a struct
+ ;; declaration as its type.
+ (save-excursion
+ (or (not (and state-cache (consp (car state-cache))))
+ ;; The above probably can't happen.
+ (progn
+ (goto-char placeholder)
+ (and (c-syntactic-re-search-forward
+ "{" indent-point t)
+ (eq (1- (point)) (caar state-cache))))))))
(goto-char placeholder)
(c-add-stmt-syntax 'topmost-intro-cont nil nil
containing-sexp paren-state))
@@ -12432,6 +12505,11 @@ comment at the start of cc-engine.el for more info."
;; in-expression block or brace list. C.f. cases 4, 16A
;; and 17E.
((and (eq char-after-ip ?{)
+ (or (not (eq (char-after containing-sexp) ?\())
+ (save-excursion
+ (and c-opt-inexpr-brace-list-key
+ (eq (c-beginning-of-statement-1 lim t nil t) 'same)
+ (looking-at c-opt-inexpr-brace-list-key))))
(progn
(setq placeholder (c-inside-bracelist-p (point)
paren-state
@@ -12606,23 +12684,30 @@ comment at the start of cc-engine.el for more info."
(= (point) containing-sexp)))
(if (eq (point) (c-point 'boi))
(c-add-syntax 'brace-list-close (point))
- (setq lim (c-most-enclosing-brace state-cache (point)))
+ (setq lim (or (save-excursion
+ (and
+ (c-back-over-member-initializers)
+ (point)))
+ (c-most-enclosing-brace state-cache (point))))
(c-beginning-of-statement-1 lim nil nil t)
(c-add-stmt-syntax 'brace-list-close nil t lim paren-state)))
(t
- ;; Prepare for the rest of the cases below by going to the
- ;; token following the opening brace
- (if (consp special-brace-list)
- (progn
- (goto-char (car (car special-brace-list)))
- (c-forward-token-2 1 nil indent-point))
- (goto-char containing-sexp))
- (forward-char)
- (let ((start (point)))
- (c-forward-syntactic-ws indent-point)
- (goto-char (max start (c-point 'bol))))
- (c-skip-ws-forward indent-point)
+ ;; Prepare for the rest of the cases below by going back to the
+ ;; previous entry, or BOI before that, providing that this is
+ ;; inside the enclosing brace.
+ (goto-char indent-point)
+ (c-beginning-of-statement-1 containing-sexp nil nil t)
+ (when (/= (point) indent-point)
+ (if (> (c-point 'boi) containing-sexp)
+ (goto-char (c-point 'boi))
+ (if (consp special-brace-list)
+ (progn
+ (goto-char (caar special-brace-list))
+ (c-forward-token-2 1 nil indent-point))
+ (goto-char containing-sexp))
+ (forward-char)
+ (c-skip-ws-forward indent-point)))
(cond
;; CASE 9C: we're looking at the first line in a brace-list
@@ -12632,8 +12717,12 @@ comment at the start of cc-engine.el for more info."
(goto-char containing-sexp))
(if (eq (point) (c-point 'boi))
(c-add-syntax 'brace-list-intro (point))
- (setq lim (c-most-enclosing-brace state-cache (point)))
- (c-beginning-of-statement-1 lim)
+ (setq lim (or (save-excursion
+ (and
+ (c-back-over-member-initializers)
+ (point)))
+ (c-most-enclosing-brace state-cache (point))))
+ (c-beginning-of-statement-1 lim nil nil t)
(c-add-stmt-syntax 'brace-list-intro nil t lim paren-state)))
;; CASE 9D: this is just a later brace-list-entry or
@@ -13177,6 +13266,18 @@ Cannot combine absolute offsets %S and %S in `add' method"
indent)))
+(def-edebug-spec c-bos-pop-state t)
+(def-edebug-spec c-bos-save-error-info t)
+(def-edebug-spec c-state-cache-top-lparen t)
+(def-edebug-spec c-state-cache-top-paren t)
+(def-edebug-spec c-state-cache-after-top-paren t)
+(def-edebug-spec c-state-maybe-marker (form symbolp))
+(def-edebug-spec c-record-type-id t)
+(def-edebug-spec c-record-ref-id t)
+(def-edebug-spec c-forward-keyword-prefixed-id t)
+(def-edebug-spec c-forward-id-comma-list t)
+(def-edebug-spec c-pull-open-brace (symbolp))
+
(cc-provide 'cc-engine)
;; Local Variables: