diff options
Diffstat (limited to 'lisp/progmodes/cc-engine.el')
-rw-r--r-- | lisp/progmodes/cc-engine.el | 757 |
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: |