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'.
This commit is contained in:
parent
d79cdcd4ff
commit
622724e95d
3 changed files with 209 additions and 78 deletions
|
@ -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)))
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -3489,6 +3489,150 @@ 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-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)))))
|
||||
(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))
|
||||
|
||||
(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
|
||||
|
@ -3497,68 +3641,27 @@ Note that Java specific rules are currently applied to tell this from
|
|||
;; 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 (let* ((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)\\)+\\'"))
|
||||
|
||||
(in-or-postfix-ops
|
||||
(c-filter-ops (c-lang-const c-operators)
|
||||
'(postfix
|
||||
postfix-if-paren
|
||||
left-assoc
|
||||
right-assoc
|
||||
right-assoc-sequence)
|
||||
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|"
|
||||
""))))
|
||||
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.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue