[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 622724e95d: CC Mode: Fontify cast types without adding them to c-
From: |
Alan Mackenzie |
Subject: |
master 622724e95d: CC Mode: Fontify cast types without adding them to c-found-types |
Date: |
Fri, 28 Oct 2022 13:53:55 -0400 (EDT) |
branch: master
commit 622724e95d6bcf858c52922e7d85423c8337bc06
Author: Alan Mackenzie <acm@muc.de>
Commit: Alan Mackenzie <acm@muc.de>
CC Mode: Fontify cast types without adding them to c-found-types
* lisp/progmodes/cc-engine.el (c-forward-type): Test for the special new
value `just-one' of c-promote-possible-types, and if found, fontify the
type,
but don't add it to c-found-types.
(c-forward-decl-or-cast-1): Add the new &optional parameter inside-macro.
Whilst checking for a cast construct, analyze the text following the closing
paren more rigorously.
Check for, and allow, the closing paren of a macro arglist before the
putative
cast construct.
* lisp/progmodes/cc-fonts.el (c-font-lock-declarations): In the lambda
function, pass the parameter inside-macro to c-forward-decl-or-cast-1.
* lisp/progmodes/cc-langs.el (c-primary-expr-regexp-details): New
c-lang-defvar which calculates `c-primary-expr-regexp' and three match
numbers for various sub-expressions in the regexp.
(c-primary-expr-regexp): Now extracted from `c-primary-expr-regexp-details'.
(c-per-++---match, c-per-&*+--match, c-per-\(-match): New
c-lang-defconsts/vars extracted from `c-primary-expr-regexp-details'.
---
lisp/progmodes/cc-engine.el | 62 +++++++++----
lisp/progmodes/cc-fonts.el | 2 +-
lisp/progmodes/cc-langs.el | 207 +++++++++++++++++++++++++++++++++-----------
3 files changed, 201 insertions(+), 70 deletions(-)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index ed06807a87..d730fddeb0 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -8194,7 +8194,8 @@ multi-line strings (but not C++, for example)."
;; treat possible types (i.e. those that it normally returns 'maybe or
;; 'found for) as actual types (and always return 'found for them).
;; This means that it records them in `c-record-type-identifiers' if
-;; that is set, and that it adds them to `c-found-types'.
+;; that is set, and that if its value is t (not 'just-one), it adds
+;; them to `c-found-types'.
(defvar c-promote-possible-types nil)
;; Dynamically bound variable that instructs `c-forward-<>-arglist' to
@@ -9191,10 +9192,11 @@ multi-line strings (but not C++, for example)."
(goto-char id-end)
(if (or res c-promote-possible-types)
(progn
- (c-add-type id-start (save-excursion
- (goto-char id-end)
- (c-backward-syntactic-ws)
- (point)))
+ (when (not (eq c-promote-possible-types 'just-one))
+ (c-add-type id-start (save-excursion
+ (goto-char id-end)
+ (c-backward-syntactic-ws)
+ (point))))
(when (and c-record-type-identifiers id-range)
(c-record-type-id id-range))
(unless res
@@ -10029,7 +10031,8 @@ This function might do hidden buffer changes."
;; This identifier is bound only in the inner let.
'(setq start id-start))))
-(defun c-forward-decl-or-cast-1 (preceding-token-end context last-cast-end)
+(defun c-forward-decl-or-cast-1 (preceding-token-end context last-cast-end
+ &optional inside-macro)
;; Move forward over a declaration or a cast if at the start of one.
;; The point is assumed to be at the start of some token. Nil is
;; returned if no declaration or cast is recognized, and the point
@@ -10118,6 +10121,10 @@ This function might do hidden buffer changes."
;; matched. In that case it's used to discover chains of casts like
;; "(a) (b) c".
;;
+ ;; INSIDE-MACRO is t when we definitely know we're inside a macro, nil
+ ;; otherwise. We use it to disambiguate things like "(a) (b);", which is
+ ;; likely a function call in a macro, but a cast outside of one.
+ ;;
;; This function records identifier ranges on
;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
;; `c-record-type-identifiers' is non-nil.
@@ -11102,11 +11109,17 @@ This function might do hidden buffer changes."
;; Check if the expression begins with a prefix keyword.
(match-beginning 2)
(if (match-beginning 1)
- ;; Expression begins with an ambiguous operator. Treat
- ;; it as a cast if it's a type decl or if we've
- ;; recognized the type somewhere else.
- (or at-decl-or-cast
- (memq at-type '(t known found)))
+ ;; Expression begins with an ambiguous operator.
+ (cond
+ ((match-beginning c-per-&*+--match)
+ (memq at-type '(t known found)))
+ ((match-beginning c-per-++---match)
+ t)
+ ((match-beginning c-per-\(-match)
+ (or
+ (memq at-type '(t known found))
+ (not inside-macro)))
+ (t nil))
;; Unless it's a keyword, it's the beginning of a primary
;; expression.
(not (looking-at c-keywords-regexp)))))
@@ -11132,18 +11145,33 @@ This function might do hidden buffer changes."
;; surrounding parens).
(looking-at c-simple-stmt-key)
(and
- ;; Check that it isn't a close paren (block close is ok,
- ;; though).
- (not (memq (char-before) '(?\) ?\])))
+ ;; Check that it isn't a close paren (block close , or a
+ ;; macro arglist is ok, though).
+ (or
+ (not (memq (char-before) '(?\) ?\])))
+ ;; Have we moved back to a macro arglist?
+ (and c-opt-cpp-prefix
+ (eq (char-before) ?\))
+ (save-excursion
+ (and
+ (c-go-list-backward)
+ (let (pos)
+ (c-backward-syntactic-ws)
+ (and (setq pos (c-on-identifier))
+ (goto-char pos)))
+ (zerop (c-backward-token-2 2))
+ (looking-at c-opt-cpp-macro-define-start)))))
+
;; Check that it isn't a nonsymbol identifier.
(not (c-on-identifier)))))))))
;; Handle the cast.
(when (and c-record-type-identifiers
at-type
- (not (memq at-type '(t maybe)))) ; 'maybe isn't strong enough
- ; evidence to promote the type.
- (let ((c-promote-possible-types t))
+ (not (eq at-type t)))
+ (let ((c-promote-possible-types (if (eq at-type 'maybe)
+ 'just-one
+ t)))
(goto-char type-start)
(c-forward-type)))
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 5bb3e2e0b4..608919d0c9 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1585,7 +1585,7 @@ casts and declarations are fontified. Used on level 2
and higher."
nil)
(setq decl-or-cast
(c-forward-decl-or-cast-1
- match-pos context last-cast-end))
+ match-pos context last-cast-end inside-macro))
;; Ensure that c-<>-arg-sep c-type properties are in place
on the
;; commas separating the arguments inside template/generic
<..>s.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index fc3977967b..291af038b7 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -3489,76 +3489,179 @@ Note that Java specific rules are currently applied to
tell this from
(c-lang-defvar c-regular-keywords-regexp
(c-lang-const c-regular-keywords-regexp))
-(c-lang-defconst c-primary-expr-regexp
- ;; Regexp matching the start of any primary expression, i.e. any
- ;; literal, symbol, prefix operator, and '('. It doesn't need to
- ;; exclude keywords; they are excluded afterwards unless the second
- ;; submatch matches. If the first but not the second submatch
- ;; matches then it is an ambiguous primary expression; it could also
- ;; be a match of e.g. an infix operator. (The case with ambiguous
- ;; keyword operators isn't handled.)
-
+(c-lang-defconst c-primary-expr-regexp-details
+ ;; A list of c-primary-expr-regexp and three numbers identifying particular
+ ;; matches in it.
t (let* ((prefix-ops
+ ;All prefix ops
(c-filter-ops (c-lang-const c-operators)
'(prefix)
(lambda (op)
;; Filter out the special case prefix
;; operators that are close parens.
(not (string-match "\\s)" op)))))
-
- (nonkeyword-prefix-ops
- (c-filter-ops prefix-ops
- t
- "\\`\\(\\s.\\|\\s(\\|\\s)\\)+\\'"))
+ (postfix-ops
+ ;; All postfix ops.
+ (c-filter-ops (c-lang-const c-operators)
+ '(postfix)
+ (lambda (op) (not (string-match "\\s)" op)))))
(in-or-postfix-ops
+ ;; All ops which are postfix, etc.
(c-filter-ops (c-lang-const c-operators)
'(postfix
postfix-if-paren
left-assoc
right-assoc
right-assoc-sequence)
- t)))
+ t))
- (concat
- "\\("
- ;; Take out all symbol class operators from `prefix-ops' and make the
- ;; first submatch from them together with `c-primary-expr-kwds'.
- (c-make-keywords-re t
- (append (c-lang-const c-primary-expr-kwds)
- (c--set-difference prefix-ops nonkeyword-prefix-ops
- :test 'string-equal)))
-
- "\\|"
- ;; Match all ambiguous operators.
- (c-make-keywords-re nil
- (c--intersection nonkeyword-prefix-ops in-or-postfix-ops
- :test 'string-equal))
- "\\)"
-
- "\\|"
- ;; Now match all other symbols.
- (c-lang-const c-symbol-start)
-
- "\\|"
- ;; The chars that can start integer and floating point
- ;; constants.
- "\\.?[0-9]"
-
- "\\|"
- ;; The unambiguous operators from `prefix-ops'.
- (c-make-keywords-re nil
- (c--set-difference nonkeyword-prefix-ops in-or-postfix-ops
- :test 'string-equal))
-
- "\\|"
- ;; Match string and character literals.
- "\\s\""
- (if (memq 'gen-string-delim c-emacs-features)
- "\\|\\s|"
- ""))))
+ (nonkeyword-prefix-ops
+ ;; All prefix ops apart from those which are keywords.
+ (c-filter-ops prefix-ops
+ t
+ "\\`\\(\\s.\\|\\s(\\|\\s)\\)+\\'"))
+ (nonkeyword-postfix-ops
+ ;; All postfix ops apart from those which are keywords.
+ (c-filter-ops postfix-ops
+ t
+ "\\`\\(\\s.\\|\\s(\\|\\s)\\)+\\'"))
+
+ (cast-ops
+ ;; All prefix ops which have syntax open-paren.
+ (c-filter-ops prefix-ops
+ t
+ "\\`\\s(\\'"))
+
+ (ambiguous-pre/postfix-ops
+ ;; All non-keyword ops which are both prefix and postfix, apart
+ ;; from (.
+ (c--set-difference (c--intersection nonkeyword-prefix-ops
+ nonkeyword-postfix-ops
+ :test 'string-equal)
+ cast-ops :test 'string-equal))
+ (unambiguous-prefix-ops
+ ;; All non-keyword ops which are prefix ops and not any other type
+ ;; of op.
+ (c--set-difference nonkeyword-prefix-ops
+ in-or-postfix-ops
+ :test 'string-equal))
+ (ambiguous-prefix-ops
+ ;; All non-keyword ops which are prefix ops and also some other
+ ;; type of op.
+ (c--intersection nonkeyword-prefix-ops
+ in-or-postfix-ops
+ :test 'string-equal)) ; This has everything we
+ ; need, plus (, ++, --.
+
+ (ambiguous-prefix-non-postfix-ops
+ ;; All non-keyword prefix ops which are also other types of ops
+ ;; apart from postfix ops.
+ (c--set-difference (c--set-difference ambiguous-prefix-ops
+ ambiguous-pre/postfix-ops
+ :test 'string-equal)
+ cast-ops :test 'string-equal))
+
+ (primary-expression-keywords-string
+ ;; Take out all symbol class operators from `prefix-ops' and make
+ ;; the first submatch from them together with
+ ;; `c-primary-expr-kwds'.
+ (c-make-keywords-re t
+ (append (c-lang-const c-primary-expr-kwds)
+ (c--set-difference prefix-ops nonkeyword-prefix-ops
+ :test 'string-equal))))
+ (primary-expression-keywords-string-depth
+ (regexp-opt-depth primary-expression-keywords-string))
+
+ (ambiguous-pre/postfix-string
+ (c-make-keywords-re nil ambiguous-pre/postfix-ops))
+ (ambiguous-pre/postfix-string-depth
+ (regexp-opt-depth ambiguous-pre/postfix-string))
+
+ (ambiguous-prefix-non-postfix-string
+ (c-make-keywords-re nil ambiguous-prefix-non-postfix-ops))
+ (ambiguous-prefix-non-postfix-string-depth
+ (regexp-opt-depth ambiguous-prefix-non-postfix-string))
+
+ (per-++---match (+ 2 primary-expression-keywords-string-depth))
+ (per-&*+--match (+ 1 per-++---match
+ ambiguous-pre/postfix-string-depth))
+ (per-\(-match (+ 1 per-&*+--match
+ ambiguous-prefix-non-postfix-string-depth)))
+
+ (list
+ (concat
+ "\\(" ; 1
+ primary-expression-keywords-string
+ "\\|"
+ ;; Match all ambiguous operators.
+ "\\(" ; 2 + primary-expression-keywords-string-depth
+ ambiguous-pre/postfix-string
+ "\\)\\|\\(" ; 3 + primary-expression-keywords-string-depth
+ ; + ambiguous-pre/postfix-string-depth
+ ambiguous-prefix-non-postfix-string
+ "\\)\\|"
+ "\\((\\)" ; 4 + primary-expression-keywords-string-depth
+ ; + ambiguous-pre/postfix-string-depth
+ ; + ambiguous-prefix-non-postfix-string-depth
+ "\\)"
+
+ "\\|"
+ ;; Now match all other symbols.
+ (c-lang-const c-symbol-start)
+
+ "\\|"
+ ;; The chars that can start integer and floating point
+ ;; constants.
+ "\\.?[0-9]"
+
+ "\\|"
+ ;; The unambiguous operators from `prefix-ops'.
+ (c-make-keywords-re nil
+ ;; (c--set-difference nonkeyword-prefix-ops in-or-postfix-ops
+ ;; :test 'string-equal)
+ unambiguous-prefix-ops
+ )
+
+ "\\|"
+ ;; Match string and character literals.
+ "\\s\""
+ (if (memq 'gen-string-delim c-emacs-features)
+ "\\|\\s|"
+ ""))
+ per-++---match
+ per-&*+--match
+ per-\(-match)))
+
+(c-lang-defconst c-primary-expr-regexp
+ ;; Regexp matching the start of any primary expression, i.e. any
+ ;; literal, symbol, prefix operator, and '('. It doesn't need to
+ ;; exclude keywords; they are excluded afterwards unless the second
+ ;; submatch matches. If the first but not the second submatch
+ ;; matches then it is an ambiguous primary expression; it could also
+ ;; be a match of e.g. an infix operator. (The case with ambiguous
+ ;; keyword operators isn't handled.)
+ t (car (c-lang-const c-primary-expr-regexp-details)))
(c-lang-defvar c-primary-expr-regexp (c-lang-const c-primary-expr-regexp))
+(c-lang-defconst c-per-++---match
+ ;; Match number for group in `c-primary-expr-regexp' which matches (in C)
+ ;; the ++ and -- operators, and any similar ones in other languages.
+ t (cadr (c-lang-const c-primary-expr-regexp-details)))
+(c-lang-defvar c-per-++---match (c-lang-const c-per-++---match))
+
+(c-lang-defconst c-per-&*+--match
+ ;; Match number for group in `c-primary-expr-regexp' which matches (in C)
+ ;; the &, *, +, and - operators, and any similar ones in other languages.
+ t (car (cddr (c-lang-const c-primary-expr-regexp-details))))
+(c-lang-defvar c-per-&*+--match (c-lang-const c-per-&*+--match))
+
+(c-lang-defconst c-per-\(-match
+ ;; Match number for group in `c-primary-expr-regexp' which matches (in C)
+ ;; the ( operator, and any similar ones in other languages.
+ t (cadr (cddr (c-lang-const c-primary-expr-regexp-details))))
+(c-lang-defvar c-per-\(-match (c-lang-const c-per-\(-match))
+
;;; Additional constants for parser-level constructs.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 622724e95d: CC Mode: Fontify cast types without adding them to c-found-types,
Alan Mackenzie <=