emacs-diffs
[Top][All Lists]
Advanced

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

master 8dd588b: CC Mode: Fix analysis of brace lists, particularly in C+


From: Alan Mackenzie
Subject: master 8dd588b: CC Mode: Fix analysis of brace lists, particularly in C++ Mode
Date: Tue, 2 Mar 2021 15:35:56 -0500 (EST)

branch: master
commit 8dd588b1fb51bb9178bf34a6be9f35de84e95045
Author: Alan Mackenzie <acm@muc.de>
Commit: Alan Mackenzie <acm@muc.de>

    CC Mode: Fix analysis of brace lists, particularly in C++ Mode
    
    Fix some alignment functionality in cc-align.el.
    
    * lisp/progmodes/cc-align.el (c-lineup-arglist-intro-after-paren): Align the
    next line under the previous entry rather than one to the right of the 
paren.
    (c-lineup-2nd-brace-entry-in-arglist): Take the anchor point from the
    brace-list-entry element, not the brace-list-intro one.
    
    * lisp/progmodes/cc-engine.el (c-looking-at-decl-block): Use
    c-looking-at-statement-block to test whether "struct A {" begins a brace 
list
    or a struct declaration.
    (c-looking-at-or-maybe-in-bracelist): Several detailed amendments, correctly
    to recognize brace lists.
    (c-looking-at-statement-block): No longer search for commas, as they are not
    reliable indicators of a brace list.  Search now for a restricted set of
    keywords, since some can appear in brace lists in C++ mode.
    
    * lisp/progmodes/cc-langs.el (c-stmt-block-only-keywords)
    (c-stmt-block-only-keywords-regexp): New lang consts/vars.
    (c-pre-id-bracelist-kwds): New lang const.
    (c-pre-id-bracelist-key): Derive now from the above.
    (c-pre-brace-non-bracelist-key): New lang const/var.
---
 lisp/progmodes/cc-align.el  |   7 ++-
 lisp/progmodes/cc-engine.el | 125 +++++++++++++++++++++++++-------------------
 lisp/progmodes/cc-langs.el  |  50 ++++++++++++++++--
 3 files changed, 122 insertions(+), 60 deletions(-)

diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index d14ef17..51d51de 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -274,8 +274,10 @@ statement-block-intro, statement-case-intro, 
arglist-intro."
   (save-excursion
     (beginning-of-line)
     (backward-up-list 1)
+    (forward-char)
     (skip-chars-forward " \t" (c-point 'eol))
-    (vector (1+ (current-column)))))
+    (if (eolp) (skip-chars-backward " \t"))
+    (vector (current-column))))
 
 (defun c-lineup-arglist-close-under-paren (langelem)
   "Line up a line under the enclosing open paren.
@@ -1145,7 +1147,8 @@ Works with brace-list-intro."
                                                             ; the line.
           (save-excursion              ; "{" earlier on the line
             (goto-char (c-langelem-pos
-                        (assq 'brace-list-intro c-syntactic-context)))
+                        (assq 'brace-list-entry
+                              c-syntactic-context)))
             (and
              (eq (c-backward-token-2
                   1 nil
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 4cf7af8..079985a 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -11410,7 +11410,9 @@ comment at the start of cc-engine.el for more info."
               ;; also might be part of a declarator expression.  Currently
               ;; there's no such language.
               (not (or (looking-at c-symbol-start)
-                       (looking-at c-type-decl-prefix-key))))))
+                       (looking-at c-type-decl-prefix-key)
+                       (and (eq (char-after) ?{)
+                            (not (c-looking-at-statement-block))))))))
 
            ;; In Pike a list of modifiers may be followed by a brace
            ;; to make them apply to many identifiers.  Note that the
@@ -11817,15 +11819,17 @@ comment at the start of cc-engine.el for more info."
   ;; POINT, or nil if there is no such position, or we do not know it.  LIM is
   ;; a backward search limit.
   ;;
-  ;; The determination of whether the brace starts a brace list is solely by
-  ;; the context of the brace, not by its contents.
+  ;; The determination of whether the brace starts a brace list is mainly by
+  ;; the context of the brace, not by its contents.  In exceptional
+  ;; circumstances (e.g. "struct A {" in C++ Mode), the contents are examined,
+  ;; too.
   ;;
   ;; Here, "brace list" does not include the body of an enum.
   (save-excursion
     (let ((start (point))
          (braceassignp 'dontknow)
          inexpr-brace-list bufpos macro-start res pos after-type-id-pos
-         in-paren parens-before-brace
+         pos2 in-paren parens-before-brace
          paren-state paren-pos)
 
       (setq res (c-backward-token-2 1 t lim))
@@ -11841,12 +11845,16 @@ comment at the start of cc-engine.el for more info."
                 (goto-char paren-pos)
                 (setq braceassignp 'c++-noassign
                       in-paren 'in-paren))
-               ((looking-at c-pre-id-bracelist-key)
+               ((looking-at c-pre-brace-non-bracelist-key)
                 (setq braceassignp nil))
                ((looking-at c-return-key))
                ((and (looking-at c-symbol-start)
                      (not (looking-at c-keywords-regexp)))
-                (setq after-type-id-pos (point)))
+                (if (save-excursion
+                      (and (zerop (c-backward-token-2 1 t lim))
+                           (looking-at c-pre-id-bracelist-key)))
+                    (setq braceassignp 'c++-noassign)
+                  (setq after-type-id-pos (point))))
                ((eq (char-after) ?\()
                 (setq parens-before-brace t)
                 nil)
@@ -11860,8 +11868,13 @@ comment at the start of cc-engine.el for more info."
                        (eq (char-after paren-pos) ?\()
                        (setq in-paren 'in-paren)
                        (goto-char paren-pos)))
-                 ((looking-at c-pre-id-bracelist-key))
+                 ((looking-at c-pre-brace-non-bracelist-key))
                  ((looking-at c-return-key))
+                 ((and (looking-at c-symbol-start)
+                       (not (looking-at c-keywords-regexp))
+                       (save-excursion
+                         (and (zerop (c-backward-token-2 1 t lim))
+                              (looking-at c-pre-id-bracelist-key)))))
                  (t (setq after-type-id-pos (point))
                     nil))))
          (setq braceassignp 'c++-noassign))
@@ -11946,8 +11959,12 @@ comment at the start of cc-engine.el for more info."
        (cond
         (braceassignp
          ;; We've hit the beginning of the aggregate list.
-         (c-beginning-of-statement-1 containing-sexp)
-         (cons (point) (or in-paren inexpr-brace-list)))
+         (setq pos2 (point))
+         (cons
+          (if (eq (c-beginning-of-statement-1 containing-sexp) 'same)
+              (point)
+            pos2)
+          (or in-paren inexpr-brace-list)))
         ((and after-type-id-pos
               (save-excursion
                 (when (eq (char-after) ?\;)
@@ -11959,34 +11976,36 @@ comment at the start of cc-engine.el for more info."
                              (c-get-char-property (point) 'syntax-table))
                     (c-go-list-forward nil after-type-id-pos)
                     (c-forward-syntactic-ws)))
-                (and
-                 (or (not (looking-at c-class-key))
-                     (save-excursion
-                       (goto-char (match-end 1))
-                       (c-forward-syntactic-ws)
-                       (not (eq (point) after-type-id-pos))))
-                 (progn
-                   (setq res
-                         (c-forward-decl-or-cast-1
-                          (save-excursion (c-backward-syntactic-ws) (point))
-                          nil nil))
-                   (and (consp res)
-                        (cond
-                         ((eq (car res) after-type-id-pos))
-                         ((> (car res) after-type-id-pos) nil)
-                         (t
-                          (catch 'find-decl
-                            (save-excursion
-                              (goto-char (car res))
-                              (c-do-declarators
-                               (point-max) t nil nil
-                               (lambda (id-start _id-end _tok _not-top _func 
_init)
-                                 (cond
-                                  ((> id-start after-type-id-pos)
-                                   (throw 'find-decl nil))
-                                  ((eq id-start after-type-id-pos)
-                                   (throw 'find-decl t)))))
-                              nil)))))))))
+                (if (and (not (eq (point) after-type-id-pos))
+                         (or (not (looking-at c-class-key))
+                             (save-excursion
+                               (goto-char (match-end 1))
+                               (c-forward-syntactic-ws)
+                               (not (eq (point) after-type-id-pos)))))
+                    (progn
+                      (setq res
+                            (c-forward-decl-or-cast-1 (c-point 'bosws)
+                                                      nil nil))
+                      (and (consp res)
+                           (cond
+                            ((eq (car res) after-type-id-pos))
+                            ((> (car res) after-type-id-pos) nil)
+                            (t
+                             (catch 'find-decl
+                               (save-excursion
+                                 (goto-char (car res))
+                                 (c-do-declarators
+                                  (point-max) t nil nil
+                                  (lambda (id-start _id-end _tok _not-top 
_func _init)
+                                    (cond
+                                     ((> id-start after-type-id-pos)
+                                      (throw 'find-decl nil))
+                                     ((eq id-start after-type-id-pos)
+                                      (throw 'find-decl t)))))
+                                 nil))))))
+                  (save-excursion
+                    (goto-char start)
+                    (not (c-looking-at-statement-block))))))
          (cons bufpos (or in-paren inexpr-brace-list)))
         ((or (eq (char-after) ?\;)
              ;; Brace lists can't contain a semicolon, so we're done.
@@ -12136,33 +12155,31 @@ comment at the start of cc-engine.el for more info."
 (defun c-looking-at-statement-block ()
   ;; Point is at an opening brace.  If this is a statement block (i.e. the
   ;; elements in the block are terminated by semicolons, or the block is
-  ;; empty, or the block contains a keyword) return non-nil.  Otherwise,
-  ;; return nil.
+  ;; empty, or the block contains a characteristic keyword, or there is a
+  ;; nested statement block) return non-nil.  Otherwise, return nil.
   (let ((here (point)))
     (prog1
        (if (c-go-list-forward)
            (let ((there (point)))
              (backward-char)
-             (c-syntactic-skip-backward "^;," here t)
+             (c-syntactic-skip-backward "^;" here t)
              (cond
-              ((eq (char-before) ?\;) t)
-              ((eq (char-before) ?,) nil)
-              (t                       ; We're at (1+ here).
-               (cond
-                ((progn (c-forward-syntactic-ws)
-                        (eq (point) (1- there))))
-                ((c-syntactic-re-search-forward c-keywords-regexp there t))
-                ((c-syntactic-re-search-forward "{" there t t)
-                 (backward-char)
-                 (c-looking-at-statement-block))
-                (t nil)))))
+              ((eq (char-before) ?\;))
+              ((progn (c-forward-syntactic-ws)
+                      (eq (point) (1- there))))
+              ((c-syntactic-re-search-forward
+                c-stmt-block-only-keywords-regexp there t))
+              ((c-syntactic-re-search-forward "{" there t t)
+               (backward-char)
+               (c-looking-at-statement-block))
+              (t nil)))
          (forward-char)
          (cond
-          ((c-syntactic-re-search-forward "[;,]" nil t t)
-           (eq (char-before) ?\;))
+          ((c-syntactic-re-search-forward ";" nil t t))
           ((progn (c-forward-syntactic-ws)
                   (eobp)))
-          ((c-syntactic-re-search-forward c-keywords-regexp nil t t))
+          ((c-syntactic-re-search-forward c-stmt-block-only-keywords-regexp
+                                          nil t t))
           ((c-syntactic-re-search-forward "{" nil t t)
            (backward-char)
            (c-looking-at-statement-block))
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 0747938..fa4e730 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -3098,6 +3098,36 @@ Note that Java specific rules are currently applied to 
tell this from
   t (c-make-keywords-re t (c-lang-const c-keywords)))
 (c-lang-defvar c-keywords-regexp (c-lang-const c-keywords-regexp))
 
+(c-lang-defconst c-stmt-block-only-keywords
+  "All keywords which unambiguously signify a statement block (as opposed to
+   a brace list) when occurring inside braces."
+  t (c--set-difference
+     (c-lang-const c-keywords)
+     (append (c-lang-const c-primary-expr-kwds)
+            (c-lang-const c-constant-kwds)
+            `(,@(when (c-major-mode-is 'c++-mode)
+                  '("typeid" "dynamic_cast" "static_cast" "const_cast"
+                    "reinterpret_cast" "alignof")))
+            (c-lang-const c-type-modifier-prefix-kwds)
+            (c-lang-const c-overloadable-operators)
+            (c-lang-const c-template-typename-kwds)
+            `(,@(when (c-major-mode-is 'c++-mode)
+                  '("reflexpr")))
+            `(,@(when (c-major-mode-is '(c-mode c++-mode))
+                  '("sizeof")))
+            (c-lang-const c-pre-lambda-tokens)
+            (c-lang-const c-block-decls-with-vars)
+            (c-lang-const c-primitive-type-kwds))
+     :test 'string-equal))
+
+(c-lang-defconst c-stmt-block-only-keywords-regexp
+  ;; A regexp matching a keyword in `c-stmt-block-only-keywords'.  Such a
+  ;; match can start and end only at token boundaries.
+  t (concat "\\(^\\|\\=\\|[^" (c-lang-const c-symbol-chars) "]\\)"
+           (c-make-keywords-re t (c-lang-const c-stmt-block-only-keywords))))
+(c-lang-defvar c-stmt-block-only-keywords-regexp
+  (c-lang-const c-stmt-block-only-keywords-regexp))
+
 (c-lang-defconst c-keyword-member-alist
   ;; An alist with all the keywords in the cars.  The cdr for each
   ;; keyword is a list of the symbols for the `*-kwds' lists that
@@ -3650,13 +3680,25 @@ list."
   c t)
 (c-lang-defvar c-recognize-knr-p (c-lang-const c-recognize-knr-p))
 
+(c-lang-defconst c-pre-id-bracelist-kwds
+  "Keywords which, preceding an identifier and brace, signify a bracelist.
+This is only used in c++-mode."
+  t nil
+  c++ '("new" "throw"))
+
 (c-lang-defconst c-pre-id-bracelist-key
-  "A regexp matching tokens which, preceding an identifier, signify a 
bracelist.
-"
-  t regexp-unmatchable
-  c++ "new\\([^[:alnum:]_$]\\|$\\)\\|&&?\\(\\S.\\|$\\)")
+  ;; A regexp matching keywords which, preceding an identifier and brace,
+  ;; signify a bracelist.  Only used in c++-mode.
+  t (c-make-keywords-re t (c-lang-const c-pre-id-bracelist-kwds)))
 (c-lang-defvar c-pre-id-bracelist-key (c-lang-const c-pre-id-bracelist-key))
 
+(c-lang-defconst c-pre-brace-non-bracelist-key
+  "A regexp matching tokens which, preceding a brace, make it a non-bracelist."
+  t regexp-unmatchable
+  c++ "&&?\\(\\S.\\|$\\)")
+(c-lang-defvar c-pre-brace-non-bracelist-key
+  (c-lang-const c-pre-brace-non-bracelist-key))
+
 (c-lang-defconst c-recognize-typeless-decls
   "Non-nil means function declarations without return type should be
 recognized.  That can introduce an ambiguity with parenthesized macro



reply via email to

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