+(defun c-narrow-to-most-enclosing-decl-block (&optional inclusive)
+ ;; If we are inside a decl-block (in the sense of c-looking-at-decl-block),
+ ;; i.e. something like namespace{} or extern{}, narrow to the insides of
+ ;; that block (NOT including the enclosing braces) if INCLUSIVE is nil,
+ ;; otherwise include the braces. If the closing brace is missing,
+ ;; (point-max) is used instead.
+ (let ((paren-state (c-parse-state))
+ encl-decl)
+ (setq encl-decl (and paren-state (c-most-enclosing-decl-block paren-state)))
+ (if encl-decl
+ (save-excursion
+ (narrow-to-region
+ (if inclusive
+ (progn (goto-char encl-decl)
+ (c-beginning-of-decl-1)
+ (point))
+ (1+ encl-decl))
+ (progn
+ (goto-char encl-decl)
+ (or (c-safe (forward-list)
+ (if inclusive
+ (point)
+ (1- (point))))
+ (point-max))))))))
+
+(defun c-widen-to-enclosing-decl-scope (paren-state orig-point-min orig-point-max)
+ ;; Narrow the buffer to the innermost declaration scope (e.g. a class, a
+ ;; namespace or the "whole buffer") recorded in PAREN-STATE, the bounding
+ ;; braces NOT being included in the resulting region. On no account may the
+ ;; final region exceed that bounded by ORIG-POINT-MIN, ORIG-POINT-MAX.
+ ;; PAREN-STATE is a list of buffer positions in the style of
+ ;; (c-parse-state), one of which will be that of the desired opening brace,
+ ;; if there is one.
+ ;;
+ ;; Return the position of the enclosing opening brace, or nil
+ (let (encl-decl) ; putative position of decl-scope's opening brace.
+ (save-restriction
+ (narrow-to-region orig-point-min orig-point-max)
+ (setq encl-decl (and paren-state
+ (c-most-enclosing-decl-block paren-state))))
+ (if encl-decl
+ (progn
+ (widen)
+ (narrow-to-region (1+ encl-decl)
+ (save-excursion
+ (goto-char encl-decl)
+ (or (c-safe (forward-list)
+ (1- (point)))
+ orig-point-max)))
+ encl-decl)
+ (narrow-to-region orig-point-min orig-point-max)
+ nil)))
+
+(eval-and-compile
+ (defmacro c-while-widening-to-decl-block (condition)
+ ;; Repeatedly evaluate CONDITION until it returns nil. After each
+ ;; evaluation, if `c-defun-tactic' is set appropriately, widen to innards
+ ;; of the next enclosing declaration block (e.g. namespace, class), or the
+ ;; buffer's original restriction.
+ ;;
+ ;; This is a very special purpose macro, which assumes the existence of
+ ;; several variables. It is for use only in c-beginning-of-defun and
+ ;; c-end-of-defun.
+ `(while
+ (and ,condition
+ (eq c-defun-tactic 'go-outward)
+ lim)
+ (setq paren-state (c-whack-state-after lim paren-state))
+ (setq lim (c-widen-to-enclosing-decl-scope
+ paren-state orig-point-min orig-point-max))
+ (setq where 'in-block))))
+