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.el319
1 files changed, 207 insertions, 112 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 5cb00929007..bacb4670ea0 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -255,6 +255,18 @@ comment at the start of cc-engine.el for more info."
(forward-char)
t))))
+(defun c-forward-over-cpp-define-id ()
+ ;; Assuming point is at the "#" that introduces a preprocessor
+ ;; directive, it's moved forward to the end of the identifier which is
+ ;; "#define"d (or whatever c-opt-cpp-macro-define specifies). Non-nil
+ ;; is returned in this case, in all other cases nil is returned and
+ ;; point isn't moved.
+ ;;
+ ;; This function might do hidden buffer changes.
+ (when (and c-opt-cpp-macro-define-id
+ (looking-at c-opt-cpp-macro-define-id))
+ (goto-char (match-end 0))))
+
(defun c-forward-to-cpp-define-body ()
;; Assuming point is at the "#" that introduces a preprocessor
;; directive, it's moved forward to the start of the definition body
@@ -2442,14 +2454,14 @@ comment at the start of cc-engine.el for more info."
(= (c-backward-token-2 0) 0))
(cond ((and (looking-at c-overloadable-operators-regexp)
- (or (not c-opt-op-identitier-prefix)
+ (or (not c-opt-op-identifier-prefix)
(and (= (c-backward-token-2 1) 0)
- (looking-at c-opt-op-identitier-prefix))))
+ (looking-at c-opt-op-identifier-prefix))))
(point))
((save-excursion
- (and c-opt-op-identitier-prefix
- (looking-at c-opt-op-identitier-prefix)
+ (and c-opt-op-identifier-prefix
+ (looking-at c-opt-op-identifier-prefix)
(= (c-forward-token-2 1) 0)
(looking-at c-overloadable-operators-regexp)))
(point))))
@@ -3843,7 +3855,7 @@ comment at the start of cc-engine.el for more info."
;; good start position for the search, so do it.
(c-find-decl-prefix-search)))
- ;; Now loop. We already got the first match.
+ ;; Now loop. Round what? (ACM, 2006/7/5). We already got the first match.
(while (progn
(while (and
@@ -4534,41 +4546,42 @@ comment at the start of cc-engine.el for more info."
(goto-char start)
nil)
- (while (and
+ (while (progn
(c-syntactic-skip-backward "^<;{}" limit t)
- (if (eq (char-before) ?<)
- t
- ;; Stopped at bob or a char that isn't allowed in an
- ;; arglist, so we've failed.
- (goto-char start)
- nil)
+ (and
+ (if (eq (char-before) ?<)
+ t
+ ;; Stopped at bob or a char that isn't allowed in an
+ ;; arglist, so we've failed.
+ (goto-char start)
+ nil)
- (if (> (point)
- (progn (c-beginning-of-current-token)
- (point)))
- ;; If we moved then the "<" was part of some
- ;; multicharacter token.
- t
+ (if (> (point)
+ (progn (c-beginning-of-current-token)
+ (point)))
+ ;; If we moved then the "<" was part of some
+ ;; multicharacter token.
+ t
- (backward-char)
- (let ((beg-pos (point)))
- (if (c-forward-<>-arglist all-types)
- (cond ((= (point) start)
- ;; Matched the arglist. Break the while.
- (goto-char beg-pos)
- nil)
- ((> (point) start)
- ;; We started from a non-paren ">" inside an
- ;; arglist.
- (goto-char start)
- nil)
- (t
- ;; Matched a shorter arglist. Can be a nested
- ;; one so continue looking.
- (goto-char beg-pos)
- t))
- t)))))
+ (backward-char)
+ (let ((beg-pos (point)))
+ (if (c-forward-<>-arglist all-types)
+ (cond ((= (point) start)
+ ;; Matched the arglist. Break the while.
+ (goto-char beg-pos)
+ nil)
+ ((> (point) start)
+ ;; We started from a non-paren ">" inside an
+ ;; arglist.
+ (goto-char start)
+ nil)
+ (t
+ ;; Matched a shorter arglist. Can be a nested
+ ;; one so continue looking.
+ (goto-char beg-pos)
+ t))
+ t))))))
(/= (point) start))))
@@ -5793,17 +5806,32 @@ y ;; True if there's a suffix match outside the outermost
nil))))
(defun c-forward-label (&optional assume-markup preceding-token-end limit)
- ;; Assuming the point is at the beginning of a token, check if it
- ;; starts a label and if so move over it and return t, otherwise
- ;; don't move and return nil. The end of the label is taken to be
- ;; the end of the first submatch in `c-opt-extra-label-key' if it
- ;; matched, otherwise it's the colon. The point is directly after
- ;; the end on return. The terminating char is marked with
- ;; `c-decl-end' to improve recognition of the following declaration
- ;; or statement.
+ ;; Assuming that point is at the beginning of a token, check if it starts a
+ ;; label and if so move over it and return t, otherwise don't move and
+ ;; return nil. "Label" here means "most things with a colon".
+ ;;
+ ;; More precisely, a "label" is regarded as one of:
+ ;; (i) a goto target like "foo:";
+ ;; (ii) A case label - either the entire construct "case FOO:" or just the
+ ;; bare "case", should the colon be missing;
+ ;; (iii) a keyword which needs a colon, like "default:" or "private:";
+ ;; (iv) One of QT's "extended" C++ variants of
+ ;; "private:"/"protected:"/"public:"/"more:" looking like "public slots:".
+ ;; (v) One of the keywords matched by `c-opt-extra-label-key' (without any
+ ;; colon). Currently (2006-03), this applies only to Objective C's
+ ;; keywords "@private", "@protected", and "@public".
+ ;;
+ ;; One of the things which will NOT be recognised as a label is a bit-field
+ ;; element of a struct, something like "int foo:5".
+ ;;
+ ;; The end of the label is taken to be just after the colon, or the end of
+ ;; the first submatch in `c-opt-extra-label-key'. The point is directly
+ ;; after the end on return. The terminating char gets marked with
+ ;; `c-decl-end' to improve recognition of the following declaration or
+ ;; statement.
;;
;; If ASSUME-MARKUP is non-nil, it's assumed that the preceding
- ;; label, if any, has been marked up like that.
+ ;; label, if any, has already been marked up like that.
;;
;; If PRECEDING-TOKEN-END is given, it should be the first position
;; after the preceding token, i.e. on the other side of the
@@ -5819,8 +5847,11 @@ y ;; True if there's a suffix match outside the outermost
;;
;; This function might do hidden buffer changes.
- (let ((start (point)))
+ (let ((start (point))
+ qt-symbol-idx
+ macro-start) ; if we're in one.
(cond
+ ;; "case" or "default" (Doesn't apply to AWK).
((looking-at c-label-kwds-regexp)
(let ((kwd-end (match-end 1)))
;; Record only the keyword itself for fontification, since in
@@ -5840,7 +5871,7 @@ y ;; True if there's a suffix match outside the outermost
(match-beginning 2))
(progn
- (goto-char (match-beginning 2))
+ (goto-char (match-beginning 2)) ; just after the :
(c-put-c-type-property (1- (point)) 'c-decl-end)
t)
@@ -5851,6 +5882,7 @@ y ;; True if there's a suffix match outside the outermost
(goto-char kwd-end)
t)))
+ ;; @private, @protected, @public, in Objective C, or similar.
((and c-opt-extra-label-key
(looking-at c-opt-extra-label-key))
;; For a `c-opt-extra-label-key' match, we record the whole
@@ -5862,7 +5894,8 @@ y ;; True if there's a suffix match outside the outermost
(c-put-c-type-property (1- (point)) 'c-decl-end)
t)
- ((and c-recognize-colon-labels
+ ;; All other cases of labels.
+ ((and c-recognize-colon-labels ; nil for AWK and IDL, otherwise t.
;; A colon label must have something before the colon.
(not (eq (char-after) ?:))
@@ -5890,7 +5923,8 @@ y ;; True if there's a suffix match outside the outermost
(save-excursion
(goto-char (1- preceding-token-end))
(c-beginning-of-current-token)
- (looking-at c-label-prefix-re))
+ (or (looking-at c-label-prefix-re)
+ (looking-at c-block-stmt-1-key)))
(and (eq (char-before preceding-token-end) ?\))
(c-after-conditional)))
@@ -5899,7 +5933,8 @@ y ;; True if there's a suffix match outside the outermost
(save-excursion
(goto-char (1- preceding-token-end))
(c-beginning-of-current-token)
- (looking-at c-label-prefix-re))
+ (or (looking-at c-label-prefix-re)
+ (looking-at c-block-stmt-1-key)))
(cond
((eq (char-before preceding-token-end) ?\))
@@ -5907,26 +5942,52 @@ y ;; True if there's a suffix match outside the outermost
((eq (char-before preceding-token-end) ?:)
;; Might be after another label, so check it recursively.
- (save-excursion
- (goto-char (1- preceding-token-end))
- ;; Essentially the same as the
- ;; `c-syntactic-re-search-forward' regexp below.
- (c-syntactic-skip-backward "^-]:?;}=*/%&|,<>!@+" nil t)
- (let ((pte (point))
- ;; If the caller turned on recording for us,
- ;; it shouldn't apply when we check the
- ;; preceding label.
- c-record-type-identifiers)
- (c-forward-syntactic-ws)
- (c-forward-label nil pte start))))))))
-
- ;; Check that the next nonsymbol token is ":". Allow '('
- ;; for the sake of macro arguments. FIXME: Should build
- ;; this regexp from the language constants.
- (c-syntactic-re-search-forward
- "[[:?;{=*/%&|,<>!@+-]" limit t t)
- (eq (char-before) ?:)
- (not (eq (char-after) ?:)))
+ (save-restriction
+ (save-excursion
+ (goto-char (1- preceding-token-end))
+ ;; Essentially the same as the
+ ;; `c-syntactic-re-search-forward' regexp below.
+ (setq macro-start
+ (save-excursion (and (c-beginning-of-macro)
+ (point))))
+ (if macro-start (narrow-to-region macro-start (point-max)))
+ (c-syntactic-skip-backward "^-]:?;}=*/%&|,<>!@+" nil t)
+ ;; Note: the following should work instead of the
+ ;; narrow-to-region above. Investigate why not,
+ ;; sometime. ACM, 2006-03-31.
+ ;; (c-syntactic-skip-backward "^-]:?;}=*/%&|,<>!@+"
+ ;; macro-start t)
+ (let ((pte (point))
+ ;; If the caller turned on recording for us,
+ ;; it shouldn't apply when we check the
+ ;; preceding label.
+ c-record-type-identifiers)
+ ;; A label can't start at a cpp directive. Check for
+ ;; this, since c-forward-syntactic-ws would foul up on it.
+ (unless (and c-opt-cpp-prefix (looking-at c-opt-cpp-prefix))
+ (c-forward-syntactic-ws)
+ (c-forward-label nil pte start))))))))))
+
+ ;; Check that the next nonsymbol token is ":", or that we're in one
+ ;; of QT's "slots" declarations. Allow '(' for the sake of macro
+ ;; arguments. FIXME: Should build this regexp from the language
+ ;; constants.
+ (when (c-syntactic-re-search-forward
+ "[ \t[:?;{=*/%&|,<>!@+-]" limit t t) ; not at EOB
+ (backward-char)
+ (setq qt-symbol-idx
+ (and (c-major-mode-is 'c++-mode)
+ (string-match
+ "\\(p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|more\\)\\>"
+ (buffer-substring start (point)))))
+ (c-forward-syntactic-ws limit)
+ (when (or (looking-at ":\\([^:]\\|\\'\\)") ; A single colon.
+ (and qt-symbol-idx
+ (search-forward-regexp "\\=slots\\>" limit t)
+ (progn (c-forward-syntactic-ws limit)
+ (looking-at ":\\([^:]\\|\\'\\)")))) ; A single colon
+ (forward-char) ; to after the colon.
+ t)))
(save-restriction
(narrow-to-region start (point))
@@ -6145,8 +6206,8 @@ comment at the start of cc-engine.el for more info."
;; so that we don't get stuck on that instead of the
;; function arglist.
(c-forward-sexp))
- ((and c-opt-op-identitier-prefix
- (looking-at c-opt-op-identitier-prefix))
+ ((and c-opt-op-identifier-prefix
+ (looking-at c-opt-op-identifier-prefix))
;; Don't trip up on "operator ()".
(c-forward-token-2 2 t)))
(and (< (point) beg)
@@ -6263,10 +6324,10 @@ comment at the start of cc-engine.el for more info."
(and c-overloadable-operators-regexp
(zerop (c-backward-token-2 1 nil lim))
(looking-at c-overloadable-operators-regexp)
- (or (not c-opt-op-identitier-prefix)
+ (or (not c-opt-op-identifier-prefix)
(and
(zerop (c-backward-token-2 1 nil lim))
- (looking-at c-opt-op-identitier-prefix)))
+ (looking-at c-opt-op-identifier-prefix)))
(point))))
(defsubst c-backward-to-block-anchor (&optional lim)
@@ -6314,7 +6375,7 @@ comment at the start of cc-engine.el for more info."
;; operator token preceded by "operator".
(save-excursion
(and (c-safe (c-backward-sexp) t)
- (looking-at c-opt-op-identitier-prefix)))
+ (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))))
@@ -6354,6 +6415,10 @@ comment at the start of cc-engine.el for more info."
;; construct, i.e. if it isn't preceded by ';', '}', ':', bob,
;; or an open paren.
(let ((beg (point)) tentative-move)
+ ;; Go back one "statement" each time round the loop until we're just
+ ;; after a ;, }, or :, or at BOB or the start of a macro or start of
+ ;; an ObjC method. This will move over a multiple declaration whose
+ ;; components are comma separated.
(while (and
;; Must check with c-opt-method-key in ObjC mode.
(not (and c-opt-method-key
@@ -6397,25 +6462,39 @@ comment at the start of cc-engine.el for more info."
knr-argdecl-start))
(goto-char fallback-pos))))
- ;; `c-beginning-of-statement-1' counts each brace block as a
- ;; separate statement, so the result will be 'previous if we've
- ;; moved over any. If they were brace list initializers we might
- ;; not have moved over a declaration boundary though, so change it
- ;; to 'same if we've moved past a '=' before '{', but not ';'.
- ;; (This ought to be integrated into `c-beginning-of-statement-1',
- ;; so we avoid this extra pass which potentially can search over a
- ;; large amount of text.)
+ ;; `c-beginning-of-statement-1' counts each brace block as a separate
+ ;; statement, so the result will be 'previous if we've moved over any.
+ ;; So change our result back to 'same if necessary.
+ ;;
+ ;; If they were brace list initializers we might not have moved over a
+ ;; declaration boundary though, so change it to 'same if we've moved
+ ;; past a '=' before '{', but not ';'. (This ought to be integrated
+ ;; into `c-beginning-of-statement-1', so we avoid this extra pass which
+ ;; 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 (c-syntactic-re-search-forward "[;={]" start t t t)
- (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))))))
+ (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)))))
@@ -6725,8 +6804,8 @@ comment at the start of cc-engine.el for more info."
(setq braceassignp
(cond
;; Check for operator =
- ((and c-opt-op-identitier-prefix
- (looking-at c-opt-op-identitier-prefix))
+ ((and c-opt-op-identifier-prefix
+ (looking-at c-opt-op-identifier-prefix))
nil)
;; Check for `<opchar>= in Pike.
((and (c-major-mode-is 'pike-mode)
@@ -7000,6 +7079,11 @@ comment at the start of cc-engine.el for more info."
stop-at-boi-only
containing-sexp
paren-state)
+ ;; Add the indicated SYNTAX-SYMBOL to `c-syntactic-context', extending it as
+ ;; needed with further syntax elements of the types `substatement',
+ ;; `inexpr-statement', `arglist-cont-nonempty', `statement-block-intro', and
+ ;; `defun-block-intro'.
+ ;;
;; Do the generic processing to anchor the given syntax symbol on
;; the preceding statement: Skip over any labels and containing
;; statements on the same line, and then search backward until we
@@ -8085,7 +8169,9 @@ comment at the start of cc-engine.el for more info."
(and (eq (char-before) ?})
(save-excursion
(let ((start (point)))
- (if c-state-cache
+ (if (and c-state-cache
+ (consp (car c-state-cache))
+ (eq (cdar c-state-cache) (point)))
;; Speed up the backward search a bit.
(goto-char (caar c-state-cache)))
(c-beginning-of-decl-1 containing-sexp)
@@ -8103,26 +8189,30 @@ comment at the start of cc-engine.el for more info."
;; CASE 5J: we are at the topmost level, make
;; sure we skip back past any access specifiers
- ((save-excursion
- (setq placeholder (point))
- (or (memq char-before-ip '(?\; ?{ ?} nil))
- (c-at-vsemi-p before-ws-ip)
- (when (and (eq char-before-ip ?:)
- (eq (c-beginning-of-statement-1 lim)
- 'label))
- (c-backward-syntactic-ws lim)
- (setq placeholder (point)))
- (and (c-major-mode-is 'objc-mode)
- (catch 'not-in-directive
- (c-beginning-of-statement-1 lim)
- (setq placeholder (point))
- (while (and (c-forward-objc-directive)
- (< (point) indent-point))
- (c-forward-syntactic-ws)
- (if (>= (point) indent-point)
- (throw 'not-in-directive t))
- (setq placeholder (point)))
- nil))))
+ ((and
+ ;; A macro continuation line is never at top level.
+ (not (and macro-start
+ (> indent-point macro-start)))
+ (save-excursion
+ (setq placeholder (point))
+ (or (memq char-before-ip '(?\; ?{ ?} nil))
+ (c-at-vsemi-p before-ws-ip)
+ (when (and (eq char-before-ip ?:)
+ (eq (c-beginning-of-statement-1 lim)
+ 'label))
+ (c-backward-syntactic-ws lim)
+ (setq placeholder (point)))
+ (and (c-major-mode-is 'objc-mode)
+ (catch 'not-in-directive
+ (c-beginning-of-statement-1 lim)
+ (setq placeholder (point))
+ (while (and (c-forward-objc-directive)
+ (< (point) indent-point))
+ (c-forward-syntactic-ws)
+ (if (>= (point) indent-point)
+ (throw 'not-in-directive t))
+ (setq placeholder (point)))
+ nil)))))
;; For historic reasons we anchor at bol of the last
;; line of the previous declaration. That's clearly
;; highly bogus and useless, and it makes our lives hard
@@ -8177,6 +8267,11 @@ comment at the start of cc-engine.el for more info."
(c-beginning-of-statement-1 (c-safe-position (point) paren-state))
(c-add-syntax 'template-args-cont (c-point 'boi)))
+ ;; CASE 5Q: we are at a statement within a macro.
+ (macro-start
+ (c-beginning-of-statement-1 containing-sexp)
+ (c-add-stmt-syntax 'statement nil t containing-sexp paren-state))
+
;; CASE 5M: we are at a topmost continuation line
(t
(c-beginning-of-statement-1 (c-safe-position (point) paren-state))