emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master a718e15: Fix some errors in c-display-defun-name wh


From: Alan Mackenzie
Subject: [Emacs-diffs] master a718e15: Fix some errors in c-display-defun-name when the type is "struct {..}", etc.
Date: Sun, 28 Jan 2018 13:05:40 -0500 (EST)

branch: master
commit a718e1593ae7332fafe734f880181e2d8ecc34df
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>

    Fix some errors in c-display-defun-name when the type is "struct {..}", etc.
    
    Also fix some errors with c-display-defun-name when there are nested 
classes.
    
    * lisp/progmodes/cc-cmds.el (c-in-function-trailer-p): Deal with a struct 
{..}
    being merely the type of a function.
    (c-where-wrt-brace-construct): Deal with a struct {..} being merely the type
    of a function.  Rearrange the order of some Lisp forms.  Insert a check for
    c-protection-key ("private", etc.) alongside the checking for a label.
    (c-defun-name-1): New function extracted form c-defun-name, which works 
within
    the existing restriction.  Don't regard 'at-function-end as being within the
    defun any more.  Recognize "struct", etc., with the new
    c-defun-type-name-decl-key rather than c-type-prefix-key.  Make the
    recognition of a normal function more accurate.
    (c-defun-name): Part left after extracting the above function.  It now just
    widens and calls c-defun-name-1.
    (c-declaration-limits-1): New function extracted from c-declaration-limits,
    which works within the existing restriction.  Move LIM back one block to
    account for the possibility of struct {..} as a function type.  Check we're
    not inside a declaration without braces.
    (c-declaration-limits): Part left after extracting the above function.  It 
now
    just narrows to an enclosing decl block and calls c-declaration-limits-1.
    (c-defun-name-and-limits): New function which identifies the name and limits
    of the most nested enclosing declaration or macro.
    (c-display-defun-name): Use c-defun-name-and-limits rather than two separate
    functions (which didn't always agree on which function).
    
    * lisp/progmodes/cc-engine.el (c-beginning-of-statement-1): If we have 
struct
    {..} as the type of a function, go back over this, too.
    
    * lisp/progmodes/cc-langs.el (c-defun-type-name-decl-kwds)
    (c-defun-type-name-decl-key): New lang const/var.
---
 lisp/progmodes/cc-cmds.el   | 548 +++++++++++++++++++++++++-------------------
 lisp/progmodes/cc-engine.el |  11 +-
 lisp/progmodes/cc-langs.el  |  12 +
 3 files changed, 329 insertions(+), 242 deletions(-)

diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 0c4829e..31cf0b1 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1397,6 +1397,16 @@ No indentation or other \"electric\" behavior is 
performed."
                (not (eq (char-before) ?_))
                (c-syntactic-re-search-forward "[;=([{]" eo-block t t t)
                (eq (char-before) ?\{)
+               ;; Exclude the entire "struct {...}" being the type of a
+               ;; function being declared.
+               (not
+                (and
+                 (c-go-up-list-forward)
+                 (eq (char-before) ?})
+                 (progn (c-forward-syntactic-ws)
+                        (c-syntactic-re-search-forward
+                         "[;=([{]" nil t t t))
+                 (eq (char-before) ?\()))
                bod)))))
 
 (defun c-where-wrt-brace-construct ()
@@ -1434,7 +1444,11 @@ No indentation or other \"electric\" behavior is 
performed."
        ((and (not least-enclosing)
             (consp paren-state)
             (consp (car paren-state))
-            (eq start (cdar paren-state)))
+            (eq start (cdar paren-state))
+            (not
+             (progn
+               (c-forward-syntactic-ws)
+               (looking-at c-symbol-start))))
        'at-function-end)
        (t
        ;; Find the start of the current declaration.  NOTE: If we're in the
@@ -1450,6 +1464,18 @@ No indentation or other \"electric\" behavior is 
performed."
 "\\([;#]\\|\\'\\|\\s(\\|\\s)\\|\\s\"\\|\\s\\\\|\\s$\\|\\s<\\|\\s>\\|\\s!\\)")))
            (forward-char))
        (setq kluge-start (point))
+       ;; First approximation as to whether the current "header" we're in is
+       ;; one followed by braces.
+       (setq brace-decl-p
+             (save-excursion
+               (and (c-syntactic-re-search-forward "[;{]" nil t t)
+                    (or (eq (char-before) ?\{)
+                        (and c-recognize-knr-p
+                             ;; Might have stopped on the
+                             ;; ';' in a K&R argdecl.  In
+                             ;; that case the declaration
+                             ;; should contain a block.
+                             (c-in-knr-argdecl))))))
        (setq decl-result
              (car (c-beginning-of-decl-1
                    ;; NOTE: If we're in a K&R region, this might be the start
@@ -1460,17 +1486,9 @@ No indentation or other \"electric\" behavior is 
performed."
                         (c-safe-position least-enclosing paren-state)))))
 
        ;; Has the declaration we've gone back to got braces?
-       (or (eq decl-result 'label)
-           (setq brace-decl-p
-                 (save-excursion
-                   (and (c-syntactic-re-search-forward "[;{]" nil t t)
-                        (or (eq (char-before) ?\{)
-                            (and c-recognize-knr-p
-                                 ;; Might have stopped on the
-                                 ;; ';' in a K&R argdecl.  In
-                                 ;; that case the declaration
-                                 ;; should contain a block.
-                                 (c-in-knr-argdecl)))))))
+       (if (or (eq decl-result 'label)
+               (looking-at c-protection-key))
+           (setq brace-decl-p nil))
 
        (cond
         ((or (eq decl-result 'label)   ; e.g. "private:" or invalid syntax.
@@ -1817,251 +1835,298 @@ the open-parenthesis that starts a defun; see 
`beginning-of-defun'."
       (c-keep-region-active)
       (= arg 0))))
 
-(defun c-defun-name ()
-  "Return the name of the current defun, or NIL if there isn't one.
-\"Defun\" here means a function, or other top level construct
-with a brace block."
+(defun c-defun-name-1 ()
+  "Return the name of the current defun, at the current narrowing,
+or NIL if there isn't one.  \"Defun\" here means a function, or
+other top level construct with a brace block."
   (c-save-buffer-state
       (beginning-of-defun-function end-of-defun-function
-       where pos name-end case-fold-search)
+       where pos decl name-start name-end case-fold-search)
+
+    (save-excursion
+      ;; Move back out of any macro/comment/string we happen to be in.
+      (c-beginning-of-macro)
+      (setq pos (c-literal-start))
+      (if pos (goto-char pos))
+
+      (setq where (c-where-wrt-brace-construct))
+
+      ;; Move to the beginning of the current defun, if any, if we're not
+      ;; already there.
+      (if (memq where '(outwith-function at-function-end))
+         nil
+       (unless (eq where 'at-header)
+         (c-backward-to-nth-BOF-{ 1 where)
+         (c-beginning-of-decl-1))
+       (when (looking-at c-typedef-key)
+         (goto-char (match-end 0))
+         (c-forward-syntactic-ws))
+
+       ;; Pick out the defun name, according to the type of defun.
+       (cond
+        ;; struct, union, enum, or similar:
+        ((save-excursion
+           (and
+            (looking-at c-defun-type-name-decl-key)
+            (consp (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil))
+            (or (not (or (eq (char-after) ?{)
+                         (and c-recognize-knr-p
+                              (c-in-knr-argdecl))))
+                (progn (c-backward-syntactic-ws)
+                       (not (eq (char-before) ?\)))))))
+         (let ((key-pos (point)))
+           (c-forward-over-token-and-ws) ; over "struct ".
+           (cond
+            ((looking-at c-symbol-key) ; "struct foo { ..."
+             (buffer-substring-no-properties key-pos (match-end 0)))
+            ((eq (char-after) ?{)      ; "struct { ... } foo"
+             (when (c-go-list-forward)
+               (c-forward-syntactic-ws)
+               (when (looking-at c-symbol-key) ; a bit bogus - there might
+                                       ; be several identifiers.
+                 (match-string-no-properties 0)))))))
+
+        ((looking-at "DEFUN\\s-*(")    ;"DEFUN\\_>") think of XEmacs!
+         ;; DEFUN ("file-name-directory", Ffile_name_directory, 
Sfile_name_directory, ...) ==> Ffile_name_directory
+         ;; DEFUN(POSIX::STREAM-LOCK, stream lockp &key BLOCK SHARED START 
LENGTH) ==> POSIX::STREAM-LOCK
+         (down-list 1)
+         (c-forward-syntactic-ws)
+         (when (eq (char-after) ?\")
+           (forward-sexp 1)
+           (c-forward-token-2))        ; over the comma and following WS.
+         (buffer-substring-no-properties
+          (point)
+          (progn
+            (c-forward-token-2)
+            (c-backward-syntactic-ws)
+            (point))))
+
+        (t
+         ;; Normal function or initializer.
+         (when
+             (and
+              (consp
+               (setq decl
+                     (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil)))
+              (setq name-start (car decl))
+              (progn (if (and (looking-at c-after-suffixed-type-decl-key)
+                              (match-beginning 1))
+                         (c-forward-keyword-clause 1))
+                     t)
+              (or (eq (char-after) ?{)
+                  (and c-recognize-knr-p
+                       (c-in-knr-argdecl)))
+              (goto-char name-start)
+              (c-forward-name)
+              (eq (char-after) ?\())
+           (c-backward-syntactic-ws)
+           (when (eq (char-before) ?\=) ; struct foo bar = {0, 0} ;
+             (c-backward-token-2)
+             (c-backward-syntactic-ws))
+           (setq name-end (point))
+           (c-back-over-compound-identifier)
+           (and (looking-at c-symbol-start)
+                (buffer-substring-no-properties (point) name-end)))))))))
 
+(defun c-defun-name ()
+  "Return the name of the current defun, or NIL if there isn't one.
+\"Defun\" here means a function, or other top level construct
+with a brace block, at the outermost level of nesting."
+  (c-save-buffer-state ()
     (save-restriction
       (widen)
-      (save-excursion
-       ;; Move back out of any macro/comment/string we happen to be in.
-       (c-beginning-of-macro)
-       (setq pos (c-literal-start))
-       (if pos (goto-char pos))
-
-       (setq where (c-where-wrt-brace-construct))
-
-       ;; Move to the beginning of the current defun, if any, if we're not
-       ;; already there.
-       (if (eq where 'outwith-function)
-           nil
-         (unless (eq where 'at-header)
-           (c-backward-to-nth-BOF-{ 1 where)
-           (c-beginning-of-decl-1))
-         (when (looking-at c-typedef-key)
-           (goto-char (match-end 0))
-           (c-forward-syntactic-ws))
-
-         ;; Pick out the defun name, according to the type of defun.
-         (cond
-          ;; struct, union, enum, or similar:
-          ((save-excursion
-             (and
-              (looking-at c-type-prefix-key)
-              (consp (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil))
-              (or (not (or (eq (char-after) ?{)
-                           (and c-recognize-knr-p
-                                (c-in-knr-argdecl))))
-                  (progn (c-backward-syntactic-ws)
-                         (not (eq (char-before) ?\)))))))
-           (let ((key-pos (point)))
-             (c-forward-over-token-and-ws) ; over "struct ".
-             (cond
-              ((looking-at c-symbol-key)       ; "struct foo { ..."
-               (buffer-substring-no-properties key-pos (match-end 0)))
-              ((eq (char-after) ?{)    ; "struct { ... } foo"
-               (when (c-go-list-forward)
-                 (c-forward-syntactic-ws)
-                 (when (looking-at c-symbol-key) ; a bit bogus - there might
-                                                 ; be several identifiers.
-                   (match-string-no-properties 0)))))))
-
-          ((looking-at "DEFUN\\s-*(") ;"DEFUN\\_>") think of XEmacs!
-           ;; DEFUN ("file-name-directory", Ffile_name_directory, 
Sfile_name_directory, ...) ==> Ffile_name_directory
-           ;; DEFUN(POSIX::STREAM-LOCK, stream lockp &key BLOCK SHARED START 
LENGTH) ==> POSIX::STREAM-LOCK
-           (down-list 1)
-           (c-forward-syntactic-ws)
-           (when (eq (char-after) ?\")
-             (forward-sexp 1)
-             (c-forward-token-2))      ; over the comma and following WS.
-           (buffer-substring-no-properties
-            (point)
-            (progn
-              (c-forward-token-2)
-              (when (looking-at ":")  ; CLISP: DEFUN(PACKAGE:LISP-SYMBOL,...)
-                (skip-chars-forward "^,"))
-              (c-backward-syntactic-ws)
-              (point))))
-
-          ((looking-at "DEF[a-zA-Z0-9_]* *( *\\([^, ]*\\) *,")
-           ;; DEFCHECKER(sysconf_arg,prefix=_SC,default=, ...) ==> sysconf_arg
-           ;; DEFFLAGSET(syslog_opt_flags,LOG_PID ...) ==> syslog_opt_flags
-           (match-string-no-properties 1))
-
-          ;; Objc selectors.
-          ((assq 'objc-method-intro (c-guess-basic-syntax))
-           (let ((bound (save-excursion (c-end-of-statement) (point)))
-                 (kw-re (concat "\\(?:" c-symbol-key "\\)?:"))
-                 (stretches))
-             (when (c-syntactic-re-search-forward c-symbol-key bound t t t)
-               (push (match-string-no-properties 0) stretches)
-               (while (c-syntactic-re-search-forward kw-re bound t t t)
-                 (push (match-string-no-properties 0) stretches)))
-             (apply 'concat (nreverse stretches))))
-
-          (t
-           ;; Normal function or initializer.
-           (when
-               (and
-                (consp (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil))
-                (or (eq (char-after) ?{)
-                    (and c-recognize-knr-p
-                         (c-in-knr-argdecl)))
-                (progn
-                  (c-backward-syntactic-ws)
-                  (eq (char-before) ?\)))
-                (c-go-list-backward))
-             (c-backward-syntactic-ws)
-             (when (eq (char-before) ?\=) ; struct foo bar = {0, 0} ;
-               (c-backward-token-2)
-               (c-backward-syntactic-ws))
-             (setq name-end (point))
-             (c-back-over-compound-identifier)
-             (and (looking-at c-symbol-start)
-                  (buffer-substring-no-properties (point) name-end))))))))))
+      (c-defun-name-1))))
 
-(defun c-declaration-limits (near)
-  ;; Return a cons of the beginning and end positions of the current
-  ;; top level declaration or macro.  If point is not inside any then
-  ;; nil is returned, unless NEAR is non-nil in which case the closest
-  ;; following one is chosen instead (if there is any).  The end
+(defun c-declaration-limits-1 (near)
+  ;; Return a cons of the beginning and end position of the current
+  ;; declaration or macro in the current narrowing.  If there is no current
+  ;; declaration or macro, return nil, unless NEAR is non-nil, in which case
+  ;; the closest following one is chosen instead (if there is any).  The end
   ;; position is at the next line, providing there is one before the
   ;; declaration.
   ;;
   ;; This function might do hidden buffer changes.
   (save-excursion
-    (save-restriction
-      (let ((start (point))
-           (paren-state (c-parse-state))
-           lim pos end-pos where)
-       ;; Narrow enclosing brace blocks out, as required by the values of
-       ;; `c-defun-tactic', `near', and the position of point.
-       (when (eq c-defun-tactic 'go-outward)
-         (let ((bounds
-                (save-restriction
-                  (if (and (not (save-excursion (c-beginning-of-macro)))
-                           (save-restriction
-                             (c-narrow-to-most-enclosing-decl-block)
-                             (memq (c-where-wrt-brace-construct)
-                                   '(at-function-end outwith-function)))
-                           (not near))
-                      (c-narrow-to-most-enclosing-decl-block nil 2)
-                    (c-narrow-to-most-enclosing-decl-block))
-                  (cons (point-min) (point-max)))))
-           (narrow-to-region (car bounds) (cdr bounds))))
-       (setq paren-state (c-parse-state))
-
-       (or
-        ;; Note: Some code duplication in `c-beginning-of-defun' and
-        ;; `c-end-of-defun'.
-        (catch 'exit
-          (unless (c-safe
-                    (goto-char (c-least-enclosing-brace paren-state))
-                    ;; If we moved to the outermost enclosing paren
-                    ;; then we can use c-safe-position to set the
-                    ;; limit. Can't do that otherwise since the
-                    ;; earlier paren pair on paren-state might very
-                    ;; well be part of the declaration we should go
-                    ;; to.
-                    (setq lim (c-safe-position (point) paren-state))
-                    t)
-            ;; At top level.  Make sure we aren't inside a literal.
-            (setq pos (c-literal-start
-                       (c-safe-position (point) paren-state)))
-            (if pos (goto-char pos)))
-
-          (when (c-beginning-of-macro)
+    (let ((start (point))
+         (paren-state (c-parse-state))
+         lim pos end-pos where)
+      (or
+       ;; Note: Some code duplication in `c-beginning-of-defun' and
+       ;; `c-end-of-defun'.
+       (catch 'exit
+        (unless (c-safe
+                  (goto-char (c-least-enclosing-brace paren-state))
+                  ;; If we moved to the outermost enclosing paren
+                  ;; then we can use c-safe-position to set the
+                  ;; limit. Can't do that otherwise since the
+                  ;; earlier paren pair on paren-state might very
+                  ;; well be part of the declaration we should go
+                  ;; to.
+                  (setq lim (c-safe-position (point) paren-state))
+                  ;; We might have a struct foo {...} as the type of the
+                  ;; function, so set LIM back one further block.
+                  (if (eq (char-before lim) ?})
+                      (setq lim
+                            (or
+                             (save-excursion
+                               (and
+                                (c-go-list-backward lim)
+                                (let ((paren-state-1 (c-parse-state)))
+                                  (c-safe-position
+                                   (point) paren-state-1))))
+                             (point-min))))
+                  t)
+          ;; At top level.  Make sure we aren't inside a literal.
+          (setq pos (c-literal-start
+                     (c-safe-position (point) paren-state)))
+          (if pos (goto-char pos)))
+
+        (when (c-beginning-of-macro)
+          (throw 'exit
+                 (cons (point)
+                       (save-excursion
+                         (c-end-of-macro)
+                         (forward-line 1)
+                         (point)))))
+
+        (setq pos (point))
+        (setq where (and (not (save-excursion (c-beginning-of-macro)))
+                         (c-where-wrt-brace-construct)))
+        (when (and (not (eq where 'at-header))
+                   (or (and near
+                            (memq where
+                                  '(at-function-end outwith-function))
+                            ;; Check we're not inside a declaration without
+                            ;; braces.
+                            (save-excursion
+                              (memq (car (c-beginning-of-decl-1 lim))
+                                    '(previous label))))
+                       (eq (car (c-beginning-of-decl-1 lim)) 'previous)
+                       (= pos (point))))
+          ;; We moved back over the previous defun.  Skip to the next
+          ;; one.  Not using c-forward-syntactic-ws here since we
+          ;; should not skip a macro.  We can also be directly after
+          ;; the block in a `c-opt-block-decls-with-vars-key'
+          ;; declaration, but then we won't move significantly far
+          ;; here.
+          (goto-char pos)
+          (c-forward-comments)
+
+          (when (and near (c-beginning-of-macro))
             (throw 'exit
                    (cons (point)
                          (save-excursion
                            (c-end-of-macro)
                            (forward-line 1)
-                           (point)))))
+                           (point))))))
 
-          (setq pos (point))
-          (setq where (and (not (save-excursion (c-beginning-of-macro)))
-                           (c-where-wrt-brace-construct)))
-          (when (and (not (eq where 'at-header))
-                     (or (and near
-                              (memq where
-                                    '(at-function-end outwith-function)))
-                         (eq (car (c-beginning-of-decl-1 lim)) 'previous)
-                         (= pos (point))))
-            ;; We moved back over the previous defun.  Skip to the next
-            ;; one.  Not using c-forward-syntactic-ws here since we
-            ;; should not skip a macro.  We can also be directly after
-            ;; the block in a `c-opt-block-decls-with-vars-key'
-            ;; declaration, but then we won't move significantly far
-            ;; here.
-            (goto-char pos)
-            (c-forward-comments)
-
-            (when (and near (c-beginning-of-macro))
-              (throw 'exit
-                     (cons (point)
-                           (save-excursion
-                             (c-end-of-macro)
-                             (forward-line 1)
-                             (point))))))
+        (if (eobp) (throw 'exit nil))
 
-          (if (eobp) (throw 'exit nil))
+        ;; Check if `c-beginning-of-decl-1' put us after the block in a
+        ;; declaration that doesn't end there.  We're searching back and
+        ;; forth over the block here, which can be expensive.
+        (setq pos (point))
+        (if (and c-opt-block-decls-with-vars-key
+                 (progn
+                   (c-backward-syntactic-ws)
+                   (eq (char-before) ?}))
+                 (eq (car (c-beginning-of-decl-1))
+                     'previous)
+                 (save-excursion
+                   (c-end-of-decl-1)
+                   (and (> (point) pos)
+                        (setq end-pos (point)))))
+            nil
+          (goto-char pos))
+
+        (if (or (and (not near) (> (point) start))
+                (not (eq (c-where-wrt-brace-construct) 'at-header)))
+            nil
+
+          ;; Try to be line oriented; position the limits at the
+          ;; closest preceding boi, and after the next newline, that
+          ;; isn't inside a comment, but if we hit a neighboring
+          ;; declaration then we instead use the exact declaration
+          ;; limit in that direction.
+          (cons (progn
+                  (setq pos (point))
+                  (while (and (/= (point) (c-point 'boi))
+                              (c-backward-single-comment)))
+                  (if (/= (point) (c-point 'boi))
+                      pos
+                    (point)))
+                (progn
+                  (if end-pos
+                      (goto-char end-pos)
+                    (c-end-of-decl-1))
+                  (setq pos (point))
+                  (while (and (not (bolp))
+                              (not (looking-at "\\s *$"))
+                              (c-forward-single-comment)))
+                  (cond ((bolp)
+                         (point))
+                        ((looking-at "\\s *$")
+                         (forward-line 1)
+                         (point))
+                        (t
+                         pos))))))
+       (and (not near)
+           (goto-char (point-min))
+           (c-forward-decl-or-cast-1 -1 nil nil)
+           (eq (char-after) ?\{)
+           (cons (point-min) (point-max)))))))
 
-          ;; Check if `c-beginning-of-decl-1' put us after the block in a
-          ;; declaration that doesn't end there.  We're searching back and
-          ;; forth over the block here, which can be expensive.
-          (setq pos (point))
-          (if (and c-opt-block-decls-with-vars-key
-                   (progn
-                     (c-backward-syntactic-ws)
-                     (eq (char-before) ?}))
-                   (eq (car (c-beginning-of-decl-1))
-                       'previous)
-                   (save-excursion
-                     (c-end-of-decl-1)
-                     (and (> (point) pos)
-                          (setq end-pos (point)))))
-              nil
-            (goto-char pos))
-
-          (if (and (not near) (> (point) start))
-              nil
-
-            ;; Try to be line oriented; position the limits at the
-            ;; closest preceding boi, and after the next newline, that
-            ;; isn't inside a comment, but if we hit a neighboring
-            ;; declaration then we instead use the exact declaration
-            ;; limit in that direction.
-            (cons (progn
-                    (setq pos (point))
-                    (while (and (/= (point) (c-point 'boi))
-                                (c-backward-single-comment)))
-                    (if (/= (point) (c-point 'boi))
-                        pos
-                      (point)))
-                  (progn
-                    (if end-pos
-                        (goto-char end-pos)
-                      (c-end-of-decl-1))
-                    (setq pos (point))
-                    (while (and (not (bolp))
-                                (not (looking-at "\\s *$"))
-                                (c-forward-single-comment)))
-                    (cond ((bolp)
-                           (point))
-                          ((looking-at "\\s *$")
-                           (forward-line 1)
-                           (point))
-                          (t
-                           pos))))))
-        (and (not near)
-             (goto-char (point-min))
-             (c-forward-decl-or-cast-1 -1 nil nil)
-             (eq (char-after) ?\{)
-             (cons (point-min) (point-max))))))))
+(defun c-declaration-limits (near)
+  ;; Return a cons of the beginning and end positions of the current
+  ;; top level declaration or macro.  If point is not inside any then
+  ;; nil is returned, unless NEAR is non-nil in which case the closest
+  ;; following one is chosen instead (if there is any).  The end
+  ;; position is at the next line, providing there is one before the
+  ;; declaration.
+  ;;
+  ;; This function might do hidden buffer changes.
+  (save-restriction
+    ;; Narrow enclosing brace blocks out, as required by the values of
+    ;; `c-defun-tactic', `near', and the position of point.
+    (when (eq c-defun-tactic 'go-outward)
+      (let ((bounds
+            (save-restriction
+              (if (and (not (save-excursion (c-beginning-of-macro)))
+                       (save-restriction
+                         (c-narrow-to-most-enclosing-decl-block)
+                         (memq (c-where-wrt-brace-construct)
+                               '(at-function-end outwith-function)))
+                       (not near))
+                  (c-narrow-to-most-enclosing-decl-block nil 2)
+                (c-narrow-to-most-enclosing-decl-block))
+              (cons (point-min) (point-max)))))
+       (narrow-to-region (car bounds) (cdr bounds))))
+    (c-declaration-limits-1 near)))
+
+(defun c-defun-name-and-limits (near)
+  ;; Return a cons of the name and limits (itself a cons) of the current
+  ;; top-level declaration or macro, or nil of there is none.
+  ;;
+  ;; If `c-defun-tactic' is 'go-outward, we return the name and limits of the
+  ;; most tightly enclosing declaration or macro.  Otherwise, we return that
+  ;; at the file level.
+  (save-restriction
+    (widen)
+    (if (eq c-defun-tactic 'go-outward)
+       (c-save-buffer-state ((paren-state (c-parse-state))
+                             (orig-point-min (point-min))
+                             (orig-point-max (point-max))
+                             lim name where limits fdoc)
+         (setq lim (c-widen-to-enclosing-decl-scope
+                    paren-state orig-point-min orig-point-max))
+         (and lim (setq lim (1- lim)))
+         (c-while-widening-to-decl-block (not (setq name (c-defun-name-1))))
+         (when name
+           (setq limits (c-declaration-limits-1 near))
+           (cons name limits)))
+      (c-save-buffer-state ((name (c-defun-name))
+                           (limits (c-declaration-limits near)))
+       (and name limits (cons name limits))))))
 
 (defun c-display-defun-name (&optional arg)
   "Display the name of the current CC mode defun and the position in it.
@@ -2069,12 +2134,13 @@ With a prefix arg, push the name onto the kill ring 
too."
   (interactive "P")
   (save-restriction
     (widen)
-    (c-save-buffer-state ((name (c-defun-name))
-                         (limits (c-declaration-limits t))
+    (c-save-buffer-state ((name-and-limits (c-defun-name-and-limits nil))
+                         (name (car name-and-limits))
+                         (limits (cdr name-and-limits))
                          (point-bol (c-point 'bol)))
       (when name
        (message "%s.  Line %s/%s." name
-                (1+ (count-lines (car limits) point-bol))
+                (1+ (count-lines (car limits) (max point-bol (car limits))))
                 (count-lines (car limits) (cdr limits)))
        (if arg (kill-new name))
        (sit-for 3 t)))))
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index b78e85a..ceeee6b 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1124,7 +1124,16 @@ comment at the start of cc-engine.el for more info."
                           (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))
+                             (not (looking-at
+                                   c-opt-block-decls-with-vars-key)))))
                          (save-excursion
                            (c-forward-sexp) (point)))
                         ;; Just gone back over some paren block?
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index c06dd21..f1ef89a 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -2107,6 +2107,18 @@ will be handled."
   "Alist associating keywords in c-other-decl-block-decl-kwds with
 their matching \"in\" syntactic symbols.")
 
+(c-lang-defconst c-defun-type-name-decl-kwds
+  "Keywords introducing a named block, where the name is a \"defun\"
+    name."
+  t (append (c-lang-const c-class-decl-kwds)
+           (c-lang-const c-brace-list-decl-kwds)))
+
+(c-lang-defconst c-defun-type-name-decl-key
+  ;; Regexp matching a keyword in `c-defun-name-decl-kwds'.
+  t (c-make-keywords-re t (c-lang-const c-defun-type-name-decl-kwds)))
+(c-lang-defvar c-defun-type-name-decl-key
+  (c-lang-const c-defun-type-name-decl-key))
+
 (c-lang-defconst c-typedef-decl-kwds
   "Keywords introducing declarations where the identifier(s) being
 declared are types.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]