;; The starting position from where we determined `c-macro-cache'.
(defvar c-macro-cache-syntactic nil)
(make-variable-buffer-local 'c-macro-cache-syntactic)
-;; non-nil iff `c-macro-cache' has both elements set AND the cdr is at a
-;; syntactic end of macro, not merely an apparent one.
+;; Either nil, or the syntactic end of the macro currently represented by
+;; `c-macro-cache'.
+(defvar c-macro-cache-no-comment nil)
+(make-variable-buffer-local 'c-macro-cache-no-comment)
+;; Either nil, or the last character of the macro currently represented by
+;; `c-macro-cache' which isn't in a comment. */
(defun c-invalidate-macro-cache (beg end)
;; Called from a before-change function. If the change region is before or
((< beg (car c-macro-cache))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))
((and (cdr c-macro-cache)
(< beg (cdr c-macro-cache)))
(setcdr c-macro-cache nil)
(setq c-macro-cache-start-pos beg
- c-macro-cache-syntactic nil))))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))))
(defun c-macro-is-genuine-p ()
;; Check that the ostensible CPP construct at point is a real one. In
t))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil)
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil)
(save-restriction
(if lim (narrow-to-region lim (point-max)))
(>= (point) (car c-macro-cache)))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))
(while (progn
(end-of-line)
(when (and (eq (char-before) ?\\)
(let* ((here (point))
(there (progn (c-end-of-macro) (point)))
s)
- (unless c-macro-cache-syntactic
+ (if c-macro-cache-syntactic
+ (goto-char c-macro-cache-syntactic)
(setq s (parse-partial-sexp here there))
(while (and (or (nth 3 s) ; in a string
(nth 4 s)) ; in a comment (maybe at end of line comment)
(> there here)) ; No infinite loops, please.
(setq there (1- (nth 8 s)))
(setq s (parse-partial-sexp here there)))
- (setq c-macro-cache-syntactic (car c-macro-cache)))
+ (setq c-macro-cache-syntactic (point)))
+ (point)))
+
+(defun c-no-comment-end-of-macro ()
+ ;; Go to the end of a CPP directive, or a pos just before which isn't in a
+ ;; comment. For this purpose, open strings are ignored.
+ ;;
+ ;; This function must only be called from the beginning of a CPP construct.
+ ;;
+ ;; Note that this function might do hidden buffer changes. See the comment
+ ;; at the start of cc-engine.el for more info.
+ (let* ((here (point))
+ (there (progn (c-end-of-macro) (point)))
+ s)
+ (if c-macro-cache-no-comment
+ (goto-char c-macro-cache-no-comment)
+ (setq s (parse-partial-sexp here there))
+ (while (and (nth 3 s) ; in a string
+ (> there here)) ; No infinite loops, please.
+ (setq here (1+ (nth 8 s)))
+ (setq s (parse-partial-sexp here there)))
+ (when (nth 4 s)
+ (goto-char (1- (nth 8 s))))
+ (setq c-macro-cache-no-comment (point)))
(point)))
(defun c-forward-over-cpp-define-id ()
\f
;;; Basic utility functions.
+(defun c-delq-from-dotted-list (elt dlist)
+ ;; If ELT is a member of the (possibly dotted) list DLIST, remove all
+ ;; occurrences of it (except for any in the last cdr of DLIST).
+ ;;
+ ;; Call this as (setq DLIST (c-delq-from-dotted-list ELT DLIST)), as
+ ;; sometimes the original structure is changed, sometimes it's not.
+ ;;
+ ;; This function is needed in Emacs < 24.5, and possibly XEmacs, because
+ ;; `delq' throws an error in these versions when given a dotted list.
+ (let ((tail dlist) prev)
+ (while (consp tail)
+ (if (eq (car tail) elt)
+ (if prev
+ (setcdr prev (cdr tail))
+ (setq dlist (cdr dlist)))
+ (setq prev tail))
+ (setq tail (cdr tail)))
+ dlist))
+
(defun c-syntactic-content (from to paren-level)
;; Return the given region as a string where all syntactic
;; whitespace is removed or, where necessary, replaced with a single
(< c-state-old-cpp-beg here))
(c-with-all-but-one-cpps-commented-out
c-state-old-cpp-beg
- (min c-state-old-cpp-end here)
+ c-state-old-cpp-end
(c-invalidate-state-cache-1 here))
(c-with-cpps-commented-out
(c-invalidate-state-cache-1 here))))
(make-variable-buffer-local 'c-parse-state-state)
(defun c-record-parse-state-state ()
(setq c-parse-state-point (point))
+ (when (markerp (cdr (assq 'c-state-old-cpp-beg c-parse-state-state)))
+ (move-marker (cdr (assq 'c-state-old-cpp-beg c-parse-state-state)) nil)
+ (move-marker (cdr (assq 'c-state-old-cpp-end c-parse-state-state)) nil))
(setq c-parse-state-state
(mapcar
(lambda (arg)
c-state-old-cpp-end
c-parse-state-point))))
(defun c-replay-parse-state-state ()
- (message
+ (message "%s"
(concat "(setq "
(mapconcat
(lambda (arg)
(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) (or c-state-cache
- (c-parse-state)))
+ (point) (c-parse-state))
0)
(point-min))
safe-pos-list (list safe-pos)))
Note that this function might do hidden buffer changes. See the
comment at the start of cc-engine.el for more info."
- (let ((start (point))
- state-2
- ;; 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
- ;; 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
- ;; 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)))
-
- (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))
- (goto-char lit-beg)
- t)))
- (< (point) pos))
+ (c-self-bind-state-cache
+ (let ((start (point))
+ state-2
+ ;; 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
+ ;; 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
+ ;; 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)))
+
+ (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))
+ (goto-char lit-beg)
+ t)))
+ (< (point) pos))
+
+ (let ((pos (point)) state-2 pps-end-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))))))
- (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)))))
+ (> (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
;;
;; This macro might do hidden buffer changes.
`(let (res)
+ (setq c-last-identifier-range nil)
(while (if (setq res ,(if (eq type 'type)
`(c-forward-type)
`(c-forward-name)))
nil
(cond ((looking-at c-keywords-regexp)
(c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause)))))
- (when (memq res '(t known found prefix))
- ,(when (eq type 'ref)
- `(when c-record-type-identifiers
- (c-record-ref-id c-last-identifier-range)))
+ (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)))
t)))
(defmacro c-forward-id-comma-list (type update-safe-pos)
;; `nconc' doesn't mind that the tail of
;; `c-record-found-types' is t.
(nconc c-record-found-types c-record-type-identifiers)))
- (if (c-major-mode-is 'java-mode) (c-fontify-recorded-types-and-refs))
t)
(goto-char start)
(progn
(c-forward-syntactic-ws)
(when (or (and c-record-type-identifiers all-types)
- (c-major-mode-is 'java-mode))
- ;; All encountered identifiers are types, so set the
- ;; promote flag and parse the type.
- (progn
- (c-forward-syntactic-ws)
- (if (looking-at "\\?")
- (forward-char)
- (when (looking-at c-identifier-start)
+ (not (equal c-inside-<>-type-key "\\(\\<\\>\\)")))
+ (c-forward-syntactic-ws)
+ (cond
+ ((eq (char-after) ??)
+ (forward-char))
+ ((and (looking-at c-identifier-start)
+ (not (looking-at c-keywords-regexp)))
+ (if (or (and all-types c-record-type-identifiers)
+ (c-major-mode-is 'java-mode))
+ ;; All encountered identifiers are types, so set the
+ ;; promote flag and parse the type.
(let ((c-promote-possible-types t)
(c-record-found-types t))
- (c-forward-type))))
+ (c-forward-type))
+ (c-forward-token-2))))
- (c-forward-syntactic-ws)
+ (c-forward-syntactic-ws)
- (when (or (looking-at "extends")
- (looking-at "super"))
- (forward-word)
- (c-forward-syntactic-ws)
- (let ((c-promote-possible-types t)
- (c-record-found-types t))
- (c-forward-type)
- (c-forward-syntactic-ws)))))
+ (when (looking-at c-inside-<>-type-key)
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (let ((c-promote-possible-types t)
+ (c-record-found-types t))
+ (c-forward-type))
+ (c-forward-syntactic-ws)))
(setq pos (point)) ; e.g. first token inside the '<'
((and c-recognize-<>-arglists
(eq (char-after) ?<))
;; Maybe an angle bracket arglist.
- (when (let ((c-record-type-identifiers t)
- (c-record-found-types t))
+ (when (let (c-last-identifier-range)
(c-forward-<>-arglist nil))
- (c-add-type start (1+ pos))
(c-forward-syntactic-ws)
- (setq pos (point)
- c-last-identifier-range nil)
+ (unless (eq (char-after) ?\()
+ (setq c-last-identifier-range nil)
+ (c-add-type start (1+ pos)))
+ (setq pos (point))
(if (and c-opt-identifier-concat-key
(looking-at c-opt-identifier-concat-key))
(c-forward-syntactic-ws)
t)
- (when (and c-record-type-identifiers id-start)
+ (when (and c-record-type-identifiers id-start
+ (not (eq (char-after) ?\()))
(c-record-type-id (cons id-start id-end)))
(setq res 'template)
nil)))
(while (cond
((looking-at c-decl-hangon-key)
(c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause))))
(setq pos (point))
;; It's an identifier that might be a type.
'maybe))))
((eq name-res 'template)
- ;; A template is a type.
+ ;; A template is sometimes a type.
(goto-char id-end)
- (setq res t))
+ (c-forward-syntactic-ws)
+ (setq res
+ (if (eq (char-after) ?\()
+ (if (c-check-type id-start id-end)
+ ;; It's an identifier that has been used as
+ ;; a type somewhere else.
+ 'found
+ ;; It's an identifier that might be a type.
+ 'maybe)
+ t)))
(t
;; Otherwise it's an operator identifier, which is not a type.
(goto-char start)
(c-backward-syntactic-ws))
(c-back-over-list-of-member-inits)
(and (eq (char-before) ?:)
+ (save-excursion
+ (c-backward-token-2)
+ (not (looking-at c-:$-multichar-token-regexp)))
(c-just-after-func-arglist-p))))
(while (and (not (and level-plausible
(c-backward-syntactic-ws)
(c-back-over-list-of-member-inits)
(and (eq (char-before) ?:)
+ (save-excursion
+ (c-backward-token-2)
+ (not (looking-at c-:$-multichar-token-regexp)))
(c-just-after-func-arglist-p)))))
(and at-top-level level-plausible)))
(cond
((looking-at c-decl-hangon-key)
(c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause))
((and (looking-at c-type-decl-prefix-key)
(if (and (c-major-mode-is 'c++-mode)
(while (cond
((looking-at c-decl-hangon-key)
(c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause))))
(<= (point) limit))
;; If a declaration is parsed:
;;
;; The point is left at the first token after the first complete
- ;; declarator, if there is one. The return value is a cons where
- ;; the car is the position of the first token in the declarator. (See
- ;; below for the cdr.)
+ ;; declarator, if there is one. The return value is a list of 4 elements,
+ ;; where the first is the position of the first token in the declarator.
+ ;; (See below for the other three.)
;; Some examples:
;;
;; void foo (int a, char *b) stuff ...
;;
;;
;;
- ;; The cdr of the return value is non-nil when a
+ ;; The second element of the return value is non-nil when a
;; `c-typedef-decl-kwds' specifier is found in the declaration.
;; Specifically it is a dotted pair (A . B) where B is t when a
;; `c-typedef-kwds' ("typedef") is present, and A is t when some
;; specifier is present. I.e., (some of) the declared
;; identifier(s) are types.
;;
+ ;; The third element of the return value is non-nil when the declaration
+ ;; parsed might be an expression. The fourth element is the position of
+ ;; the start of the type identifier.
+ ;;
;; If a cast is parsed:
;;
;; The point is left at the first token after the closing paren of
cast-end
;; Have we got a new-style C++11 "auto"?
new-style-auto
+ ;; Set when the symbol before `preceding-token-end' is known to
+ ;; terminate the previous construct, or when we're at point-min.
+ at-decl-start
;; Save `c-record-type-identifiers' and
;; `c-record-ref-identifiers' since ranges are recorded
;; speculatively and should be thrown away if it turns out
;; that it isn't a declaration or cast.
(save-rec-type-ids c-record-type-identifiers)
- (save-rec-ref-ids c-record-ref-identifiers))
+ (save-rec-ref-ids c-record-ref-identifiers)
+ ;; Set when we parse a declaration which might also be an expression,
+ ;; such as "a *b". See CASE 16 and CASE 17.
+ maybe-expression)
+
+ (save-excursion
+ (goto-char preceding-token-end)
+ (setq at-decl-start
+ (or (bobp)
+ (let ((tok-end (point)))
+ (c-backward-token-2)
+ (member (buffer-substring-no-properties (point) tok-end)
+ c-pre-start-tokens)))))
(while (c-forward-annotation)
(c-forward-syntactic-ws))
(save-excursion
(c-forward-keyword-clause 1)
(setq kwd-clause-end (point))))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(setq noise-start (point))
(c-forward-noise-clause)
(setq kwd-clause-end (point))))
(while
(cond ((looking-at c-decl-hangon-key)
(c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause))))
(setq id-start (point)))
(setq got-identifier (c-forward-name))
(setq name-start pos)))
- ;; Skip over type decl suffix operators.
- (while (if (looking-at c-type-decl-suffix-key)
+ ;; Skip over type decl suffix operators and trailing noise macros.
+ (while
+ (cond
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))
+
+ ((looking-at c-type-decl-suffix-key)
+ (if (eq (char-after) ?\))
+ (when (> paren-depth 0)
+ (setq paren-depth (1- paren-depth))
+ (forward-char)
+ t)
+ (when (if (save-match-data (looking-at "\\s("))
+ (c-safe (c-forward-sexp 1) t)
+ (goto-char (match-end 1))
+ t)
+ (when (and (not got-suffix-after-parens)
+ (= paren-depth 0))
+ (setq got-suffix-after-parens (match-beginning 0)))
+ (setq got-suffix t))))
- (if (eq (char-after) ?\))
- (when (> paren-depth 0)
- (setq paren-depth (1- paren-depth))
- (forward-char)
- t)
- (when (if (save-match-data (looking-at "\\s("))
- (c-safe (c-forward-sexp 1) t)
- (goto-char (match-end 1))
- t)
- (when (and (not got-suffix-after-parens)
- (= paren-depth 0))
- (setq got-suffix-after-parens (match-beginning 0)))
- (setq got-suffix t)))
-
- ;; No suffix matched. We might have matched the
- ;; identifier as a type and the open paren of a
- ;; function arglist as a type decl prefix. In that
- ;; case we should "backtrack": Reinterpret the last
- ;; type as the identifier, move out of the arglist and
- ;; continue searching for suffix operators.
- ;;
- ;; Do this even if there's no preceding type, to cope
- ;; with old style function declarations in K&R C,
- ;; (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)
+ (t
+ ;; No suffix matched. We might have matched the
+ ;; identifier as a type and the open paren of a
+ ;; function arglist as a type decl prefix. In that
+ ;; case we should "backtrack": Reinterpret the last
+ ;; type as the identifier, move out of the arglist and
+ ;; continue searching for suffix operators.
+ ;;
+ ;; Do this even if there's no preceding type, to cope
+ ;; with old style function declarations in K&R C,
+ ;; (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
(eq (char-before pos) ?\)))
(c-fdoc-shift-type-backward)
(goto-char pos)
- t))
+ t)))
(c-forward-syntactic-ws))
at-type
(or at-decl-end (looking-at "=[^=]"))
(not context)
- (not got-suffix))
- ;; Got something like "foo * bar;". Since we're not inside an
- ;; arglist it would be a meaningless expression because the
- ;; result isn't used. We therefore choose to recognize it as
- ;; a declaration. Do not allow a suffix since it could then
- ;; be a function call.
+ (or (not got-suffix)
+ at-decl-start))
+ ;; Got something like "foo * bar;". Since we're not inside
+ ;; an arglist it would be a meaningless expression because
+ ;; the result isn't used. We therefore choose to recognize
+ ;; it as a declaration. We only allow a suffix (which makes
+ ;; the construct look like a function call) when
+ ;; `at-decl-start' provides additional evidence that we do
+ ;; have a declaration.
+ (setq maybe-expression t)
(throw 'at-decl-or-cast t))
;; CASE 17
;; be an odd expression or it could be a declaration. Treat
;; it as a declaration if "a" has been used as a type
;; somewhere else (if it's a known type we won't get here).
+ (setq maybe-expression t)
(throw 'at-decl-or-cast t)))
;; CASE 18
(goto-char type-start)
(c-forward-type))))
- (cons id-start
+ (list id-start
(and (or at-type-decl at-typedef)
- (cons at-type-decl at-typedef))))
+ (cons at-type-decl at-typedef))
+ maybe-expression
+ type-start))
(t
;; False alarm. Restore the recorded ranges.
(c-syntactic-skip-backward c-block-prefix-charset limit t)
(eq (char-before) ?>))))))
+ ;; Skip back over noise clauses.
+ (while (and
+ c-opt-cpp-prefix
+ (eq (char-before) ?\))
+ (let ((after-paren (point)))
+ (if (and (c-go-list-backward)
+ (progn (c-backward-syntactic-ws)
+ (c-simple-skip-symbol-backward))
+ (or (looking-at c-paren-nontype-key)
+ (looking-at c-noise-macro-with-parens-name-re)))
+ (progn
+ (c-syntactic-skip-backward c-block-prefix-charset limit t)
+ t)
+ (goto-char after-paren)
+ nil))))
+
;; Note: Can't get bogus hits inside template arglists below since they
;; have gotten paren syntax above.
(when (and
(not (looking-at "=")))))
b-pos)))
-(defun c-backward-colon-prefixed-type ()
- ;; We're at the token after what might be a type prefixed with a colon. Try
- ;; moving backward over this type and the colon. On success, return t and
- ;; leave point before colon; on failure, leave point unchanged. Will clobber
- ;; match data.
+(defun c-backward-typed-enum-colon ()
+ ;; We're at a "{" which might be the opening brace of a enum which is
+ ;; strongly typed (by a ":" followed by a type). If this is the case, leave
+ ;; point before the colon and return t. Otherwise leave point unchanged and return nil.
+ ;; Match data will be clobbered.
(let ((here (point))
(colon-pos nil))
(save-excursion
(or (not (looking-at "\\s)"))
(c-go-up-list-backward))
(cond
- ((eql (char-after) ?:)
+ ((and (eql (char-after) ?:)
+ (save-excursion
+ (c-backward-syntactic-ws)
+ (c-on-identifier)))
(setq colon-pos (point))
(forward-char)
(c-forward-syntactic-ws)
(let ((here (point))
up-sexp-pos before-identifier)
(when c-recognize-post-brace-list-type-p
- (c-backward-colon-prefixed-type))
+ (c-backward-typed-enum-colon))
(while
(and
(eq (c-backward-token-2) 0)
((eq (char-after) ?\()
(and (eq (c-backward-token-2) 0)
(or (looking-at c-decl-hangon-key)
- (looking-at c-noise-macro-with-parens-name-re))))
+ (and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re)))))
((and c-recognize-<>-arglists
(eq (char-after) ?<)
(while (cond
((looking-at c-specifier-key)
(c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause))))
(setq placeholder (c-point 'boi))
(or (consp special-brace-list)
(while (cond
((looking-at c-specifier-key)
(c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause))))
(c-add-syntax 'defun-open (c-point 'boi))
;; Bogus to use bol here, but it's the legacy. (Resolved,
(while (cond
((looking-at c-specifier-key)
(c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause))))
(c-add-syntax 'brace-list-open (c-point 'boi))))