mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-23 07:19:15 +00:00
Correctly fontify C++ direct initializations with parens inside functions
Or, more clearly, when something looks like a function declaration and it's inside a function, fontify it as a direct initialization. For this purpose, introduce a "brace stack" for each buffer, where an entry on the brace stack states how deeply nested a particular position is inside braces inside a "top level", which includes classes and namespaces. Also introduce a new "context", "top", with which c-font-lock-declarations signals to c-forward-decl-or-cast-1 that point is at the top level. * lisp/progmodes/cc-langs.el (c-get-state-before-change-functions): add c-truncate-bs-cache. (c-flat-decl-block-kwds, c-brace-stack-thing-key, c-brace-stack-no-semi-key) (c-type-decl-operator-prefix-key): new language constants/variables. * lisp/progmodes/cc-engine.el (c-bs-interval, c-bs-cache, c-bs-cache-limit) (c-bs-prev-pos, c-bs-prev-stack): New mostly local variables for the brace stack cache. (c-init-bs-cache, c-truncate-bs-cache, c-truncate-bs-cache, c-brace-stack-at) (c-bs-at-toplevel-p): New functions which manipulate the brace stack (cache). (c-find-decl-prefix-search): Keep track of whether we're at top level. (c-find-decl-spots): New local variable cfd-top-level which records what it says. On calling cfd-fun, pass cfd-top-level as an additional argument. (c-forward-declarator): Add new element DECORATED to the result list. Set it to non-nil when a match for c-type-decl-operator-prefix-key is found. (c-forward-decl-or-cast-1): Handle the newly introduced context "top". Introduce "CASE 9.5", which recognizes direct initializations. * lisp/progmodes/cc-fonts.el (c-font-lock-complex-decl-prepare) (c-font-lock-enum-tail, c-font-lock-cut-off-declarators) (c-font-lock-enclosing-decls, c-simple-decl-matchers, c-basic-matchers-after): Add appropriate `not-top' argument to calls to c-font-lock-declarators. (c-font-lock-declarators): Additional parameter `not-top'. Use not-top to participate in the decision whether to fontify an identifier as a function or a variable. (c-font-lock-declarations): The internal lambda function takes an additional argument `toplev' from c-find-decl-spots, which it uses in determining the "context" of a declaration. Add appropriate `not-top' argument to calls to c-font-lock-declarators. (c-font-lock-objc-methods): Add extra parameter to internal lambda function, like for c-font-lock-declarators. * lisp/progmodes/cc-mode.el (c-basic-common-init): Initialize the brace stack cache.
This commit is contained in:
parent
f95ca1268d
commit
c417f08b16
@ -5128,6 +5128,211 @@ comment at the start of cc-engine.el for more info."
|
||||
(c-debug-remove-face ,beg ,end 'c-debug-decl-spot-face)
|
||||
(c-debug-remove-face ,beg ,end 'c-debug-decl-sws-face))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Machinery for determining when we're at top level (this including being
|
||||
;; directly inside a class or namespace, etc.)
|
||||
;;
|
||||
;; We maintain a stack of brace depths in structures like classes and
|
||||
;; namespaces. The car of this structure, when non-nil, indicates that the
|
||||
;; associated position is within a template (etc.) structure, and the value is
|
||||
;; the position where the (outermost) template ends. The other elements in
|
||||
;; the structure are stacked elements, one each for each enclosing "top level"
|
||||
;; structure.
|
||||
;;
|
||||
;; At the very outermost level, the value of the stack would be (nil 1), the
|
||||
;; "1" indicating an enclosure in a notional all-enclosing block. After
|
||||
;; passing a keyword such as "namespace", the value would become (nil 0 1).
|
||||
;; At this point, passing a semicolon would cause the 0 to be dropped from the
|
||||
;; stack (at any other time, a semicolon is ignored). Alternatively, on
|
||||
;; passing an opening brace, the stack would become (nil 1 1). Each opening
|
||||
;; brace passed causes the cadr to be incremented, and passing closing braces
|
||||
;; causes it to be decremented until it reaches 1. On passing a closing brace
|
||||
;; when the cadr of the stack is at 1, this causes it to be removed from the
|
||||
;; stack, the corresponding namespace (etc.) structure having been closed.
|
||||
;;
|
||||
;; There is a special stack value -1 which means the C++ colon operator
|
||||
;; introducing a list of inherited classes has just been parsed. The value
|
||||
;; persists on the stack until the next open brace or semicolon.
|
||||
;;
|
||||
;; When the car of the stack is non-nil, i.e. when we're in a template (etc.)
|
||||
;; structure, braces are not counted. The counting resumes only after passing
|
||||
;; the template's closing position, which is recorded in the car of the stack.
|
||||
;;
|
||||
;; The test for being at top level consists of the cadr being 0 or 1.
|
||||
;;
|
||||
;; The values of this stack throughout a buffer are cached in a simple linear
|
||||
;; cache, every 5000 characters.
|
||||
;;
|
||||
;; Note to maintainers: This cache mechanism is MUCH faster than recalculating
|
||||
;; the stack at every entry to `c-find-decl-spots' using `c-at-toplevel-p' or
|
||||
;; the like.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; The approximate interval at which we cache the value of the brace stack.
|
||||
(defconst c-bs-interval 5000)
|
||||
;; The list of cached values of the brace stack. Each value in the list is a
|
||||
;; cons of the position it is valid for and the value of the stack as
|
||||
;; described above.
|
||||
(defvar c-bs-cache nil)
|
||||
(make-variable-buffer-local 'c-bs-cache)
|
||||
;; The position of the buffer at and below which entries in `c-bs-cache' are
|
||||
;; valid.
|
||||
(defvar c-bs-cache-limit 1)
|
||||
(make-variable-buffer-local 'c-bs-cache-limit)
|
||||
;; The previous buffer position for which the brace stack value was
|
||||
;; determined.
|
||||
(defvar c-bs-prev-pos most-positive-fixnum)
|
||||
(make-variable-buffer-local 'c-bs-prev-pos)
|
||||
;; The value of the brace stack at `c-bs-prev-pos'.
|
||||
(defvar c-bs-prev-stack nil)
|
||||
(make-variable-buffer-local 'c-bs-prev-stack)
|
||||
|
||||
(defun c-init-bs-cache ()
|
||||
;; Initialize the cache in `c-bs-cache' and related variables.
|
||||
(setq c-bs-cache nil
|
||||
c-bs-cache-limit 1
|
||||
c-bs-prev-pos most-positive-fixnum
|
||||
c-bs-prev-stack nil))
|
||||
|
||||
(defun c-truncate-bs-cache (pos &rest _ignore)
|
||||
;; Truncate the upper bound of the cache `c-bs-cache' to POS, if it is
|
||||
;; higher than that position. This is called as either a before- or
|
||||
;; after-change-function.
|
||||
(setq c-bs-cache-limit
|
||||
(min c-bs-cache-limit pos)))
|
||||
|
||||
(defun c-update-brace-stack (stack from to)
|
||||
;; Give a brace-stack which has the value STACK at position FROM, update it
|
||||
;; to it's value at position TO, where TO is after (or equal to) FROM.
|
||||
;; Return a cons of either TO (if it is outside a literal) and this new
|
||||
;; value, or of the next position after TO outside a literal and the new
|
||||
;; value.
|
||||
(let (match kwd-sym (prev-match-pos 1)
|
||||
(s (cdr stack))
|
||||
(bound-<> (car stack))
|
||||
)
|
||||
(save-excursion
|
||||
(cond
|
||||
((and bound-<> (<= to bound-<>))
|
||||
(goto-char to)) ; Nothing to do.
|
||||
(bound-<>
|
||||
(goto-char bound-<>)
|
||||
(setq bound-<> nil))
|
||||
(t (goto-char from)))
|
||||
(while (and (< (point) to)
|
||||
(c-syntactic-re-search-forward
|
||||
(if (<= (car s) 0)
|
||||
c-brace-stack-thing-key
|
||||
c-brace-stack-no-semi-key)
|
||||
to 'after-literal)
|
||||
(> (point) prev-match-pos)) ; prevent infinite loop.
|
||||
(setq prev-match-pos (point))
|
||||
(setq match (match-string-no-properties 1)
|
||||
kwd-sym (c-keyword-sym match))
|
||||
(cond
|
||||
((and (equal match "{")
|
||||
(progn (backward-char)
|
||||
(prog1 (looking-at "\\s(")
|
||||
(forward-char))))
|
||||
(setq s (if s
|
||||
(cons (if (<= (car s) 0)
|
||||
1
|
||||
(1+ (car s)))
|
||||
(cdr s))
|
||||
(list 1))))
|
||||
((and (equal match "}")
|
||||
(progn (backward-char)
|
||||
(prog1 (looking-at "\\s)")
|
||||
(forward-char))))
|
||||
(setq s
|
||||
(cond
|
||||
((and s (> (car s) 1))
|
||||
(cons (1- (car s)) (cdr s)))
|
||||
((and (cdr s) (eq (car s) 1))
|
||||
(cdr s))
|
||||
(t s))))
|
||||
((and (equal match "<")
|
||||
(progn (backward-char)
|
||||
(prog1 (looking-at "\\s(")
|
||||
(forward-char))))
|
||||
(backward-char)
|
||||
(if (c-forward-<>-arglist nil) ; Should always work.
|
||||
(when (> (point) to)
|
||||
(setq bound-<> (point)))
|
||||
(forward-char)))
|
||||
((and (equal match ":")
|
||||
s
|
||||
(eq (car s) 0))
|
||||
(setq s (cons -1 (cdr s))))
|
||||
((and (equal match ",")
|
||||
(eq (car s) -1))) ; at "," in "class foo : bar, ..."
|
||||
((member match '(";" "," ")"))
|
||||
(when (and s (cdr s) (<= (car s) 0))
|
||||
(setq s (cdr s))))
|
||||
((c-keyword-member kwd-sym 'c-flat-decl-block-kwds)
|
||||
(push 0 s))))
|
||||
(cons (point)
|
||||
(cons bound-<> s)))))
|
||||
|
||||
(defun c-brace-stack-at (here)
|
||||
;; Given a buffer position HERE, Return the value of the brace stack there.
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let ((c c-bs-cache)
|
||||
(can-use-prev (<= c-bs-prev-pos c-bs-cache-limit))
|
||||
elt stack pos npos high-elt)
|
||||
;; Trim the cache to take account of buffer changes.
|
||||
(while (and c
|
||||
(> (caar c) c-bs-cache-limit))
|
||||
(setq c (cdr c)))
|
||||
(setq c-bs-cache c)
|
||||
|
||||
(while (and c
|
||||
(> (caar c) here))
|
||||
(setq high-elt (car c))
|
||||
(setq c (cdr c)))
|
||||
(setq pos (or (and c (caar c))
|
||||
(point-min)))
|
||||
|
||||
(setq elt (if c
|
||||
(car c)
|
||||
(cons (point-min)
|
||||
(cons nil (list 1)))))
|
||||
(when (not high-elt)
|
||||
(setq stack (cdr elt))
|
||||
(while
|
||||
;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration.
|
||||
(<= (setq npos (+ pos c-bs-interval)) here)
|
||||
(setq elt (c-update-brace-stack stack pos npos))
|
||||
(setq npos (car elt))
|
||||
(setq stack (cdr elt))
|
||||
(unless (eq npos (point-max)) ; NPOS could be in a literal at EOB.
|
||||
(setq c-bs-cache (cons elt c-bs-cache)))
|
||||
(setq pos npos)))
|
||||
|
||||
(if (> pos c-bs-cache-limit)
|
||||
(setq c-bs-cache-limit pos))
|
||||
|
||||
;; Can we just use the previous value?
|
||||
(if (and can-use-prev
|
||||
(<= c-bs-prev-pos here)
|
||||
(> c-bs-prev-pos (car elt)))
|
||||
(setq pos c-bs-prev-pos
|
||||
stack c-bs-prev-stack)
|
||||
(setq pos (car elt)
|
||||
stack (cdr elt)))
|
||||
(if (> here c-bs-cache-limit)
|
||||
(setq c-bs-cache-limit here))
|
||||
(setq elt (c-update-brace-stack stack pos here)
|
||||
c-bs-prev-pos (car elt)
|
||||
c-bs-prev-stack (cdr elt))))))
|
||||
|
||||
(defun c-bs-at-toplevel-p (here)
|
||||
;; Is position HERE at the top level, as indicated by the brace stack?
|
||||
(let ((stack (c-brace-stack-at here)))
|
||||
(or (null stack) ; Probably unnecessary.
|
||||
(<= (cadr stack) 1))))
|
||||
|
||||
(defmacro c-find-decl-prefix-search ()
|
||||
;; Macro used inside `c-find-decl-spots'. It ought to be a defun,
|
||||
;; but it contains lots of free variables that refer to things
|
||||
@ -5221,6 +5426,7 @@ comment at the start of cc-engine.el for more info."
|
||||
cfd-re-match nil)
|
||||
(setq cfd-match-pos cfd-prop-match
|
||||
cfd-prop-match nil))
|
||||
(setq cfd-top-level (c-bs-at-toplevel-p cfd-match-pos))
|
||||
|
||||
(goto-char cfd-match-pos)
|
||||
|
||||
@ -5319,7 +5525,11 @@ comment at the start of cc-engine.el for more info."
|
||||
;; comments.
|
||||
(cfd-token-pos 0)
|
||||
;; The end position of the last entered macro.
|
||||
(cfd-macro-end 0))
|
||||
(cfd-macro-end 0)
|
||||
;; Whether the last position returned from `c-find-decl-prefix-search'
|
||||
;; is at the top-level (including directly in a class or namespace,
|
||||
;; etc.).
|
||||
cfd-top-level)
|
||||
|
||||
;; Initialize by finding a syntactically relevant start position
|
||||
;; before the point, and do the first `c-decl-prefix-or-start-re'
|
||||
@ -5627,7 +5837,7 @@ comment at the start of cc-engine.el for more info."
|
||||
nil)))) ; end of when condition
|
||||
|
||||
(c-debug-put-decl-spot-faces cfd-match-pos (point))
|
||||
(if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0))
|
||||
(if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0) cfd-top-level)
|
||||
(setq cfd-prop-match nil))
|
||||
|
||||
(when (/= cfd-macro-end 0)
|
||||
@ -7552,10 +7762,12 @@ comment at the start of cc-engine.el for more info."
|
||||
;; Assuming point is at the start of a declarator, move forward over it,
|
||||
;; leaving point at the next token after it (e.g. a ) or a ; or a ,).
|
||||
;;
|
||||
;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT), where ID-START and
|
||||
;; ID-END are the bounds of the declarator's identifier, and
|
||||
;; BRACKETS-AFTER-ID is non-nil if a [...] pair is present after the id.
|
||||
;; GOT-INIT is non-nil when the declarator is followed by "=" or "(".
|
||||
;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT DECORATED),
|
||||
;; where ID-START and ID-END are the bounds of the declarator's identifier,
|
||||
;; and BRACKETS-AFTER-ID is non-nil if a [...] pair is present after the id.
|
||||
;; GOT-INIT is non-nil when the declarator is followed by "=" or "(",
|
||||
;; DECORATED is non-nil when the identifier is embellished by an operator,
|
||||
;; like "*x", or "(*x)".
|
||||
;;
|
||||
;; If ACCEPT-ANON is non-nil, move forward over any "anonymous declarator",
|
||||
;; i.e. something like the (*) in int (*), such as might be found in a
|
||||
@ -7574,7 +7786,7 @@ comment at the start of cc-engine.el for more info."
|
||||
;; array/struct initialization) or "=" or terminating delimiter
|
||||
;; (e.g. "," or ";" or "}").
|
||||
(let ((here (point))
|
||||
id-start id-end brackets-after-id paren-depth)
|
||||
id-start id-end brackets-after-id paren-depth decorated)
|
||||
(or limit (setq limit (point-max)))
|
||||
(if (and
|
||||
(< (point) limit)
|
||||
@ -7614,6 +7826,8 @@ comment at the start of cc-engine.el for more info."
|
||||
(setq got-identifier t)
|
||||
nil))
|
||||
t))
|
||||
(if (looking-at c-type-decl-operator-prefix-key)
|
||||
(setq decorated t))
|
||||
(if (eq (char-after) ?\()
|
||||
(progn
|
||||
(setq paren-depth (1+ paren-depth))
|
||||
@ -7668,7 +7882,7 @@ comment at the start of cc-engine.el for more info."
|
||||
(setq brackets-after-id t))
|
||||
(backward-char)
|
||||
found))
|
||||
(list id-start id-end brackets-after-id (match-beginning 1))
|
||||
(list id-start id-end brackets-after-id (match-beginning 1) decorated)
|
||||
|
||||
(goto-char here)
|
||||
nil)))
|
||||
@ -7744,6 +7958,9 @@ comment at the start of cc-engine.el for more info."
|
||||
;; inside a function declaration arglist).
|
||||
;; '<> In an angle bracket arglist.
|
||||
;; 'arglist Some other type of arglist.
|
||||
;; 'top Some other context and point is at the top-level (either
|
||||
;; outside any braces or directly inside a class or namespace,
|
||||
;; etc.)
|
||||
;; nil Some other context or unknown context. Includes
|
||||
;; within the parens of an if, for, ... construct.
|
||||
;; 'not-decl This value is never supplied to this function. It
|
||||
@ -8152,7 +8369,7 @@ comment at the start of cc-engine.el for more info."
|
||||
maybe-typeless
|
||||
backup-maybe-typeless
|
||||
(when c-recognize-typeless-decls
|
||||
(and (not context)
|
||||
(and (memq context '(nil top))
|
||||
;; Deal with C++11's "copy-initialization"
|
||||
;; where we have <type>(<constant>), by
|
||||
;; contrasting with a typeless
|
||||
@ -8215,7 +8432,7 @@ comment at the start of cc-engine.el for more info."
|
||||
|
||||
(setq at-decl-end
|
||||
(looking-at (cond ((eq context '<>) "[,>]")
|
||||
(context "[,)]")
|
||||
((not (memq context '(nil top))) "[,\)]")
|
||||
(t "[,;]"))))
|
||||
|
||||
;; Now we've collected info about various characteristics of
|
||||
@ -8344,7 +8561,7 @@ comment at the start of cc-engine.el for more info."
|
||||
|
||||
(if (and got-parens
|
||||
(not got-prefix)
|
||||
(not context)
|
||||
(memq context '(nil top))
|
||||
(not (eq at-type t))
|
||||
(or backup-at-type
|
||||
maybe-typeless
|
||||
@ -8394,6 +8611,18 @@ comment at the start of cc-engine.el for more info."
|
||||
;; instantiation expression).
|
||||
(throw 'at-decl-or-cast nil))))
|
||||
|
||||
;; CASE 9.5
|
||||
(when (and (not context) ; i.e. not at top level.
|
||||
(c-major-mode-is 'c++-mode)
|
||||
(eq at-decl-or-cast 'ids)
|
||||
after-paren-pos)
|
||||
;; We've got something like "foo bar (...)" in C++ which isn't at
|
||||
;; the top level. This is probably a uniform initialization of bar
|
||||
;; to the contents of the parens. In this case the declarator ends
|
||||
;; at the open paren.
|
||||
(goto-char (1- after-paren-pos))
|
||||
(throw 'at-decl-or-cast t))
|
||||
|
||||
;; CASE 10
|
||||
(when at-decl-or-cast
|
||||
;; By now we've located the type in the declaration that we know
|
||||
@ -8402,7 +8631,7 @@ comment at the start of cc-engine.el for more info."
|
||||
|
||||
;; CASE 11
|
||||
(when (and got-identifier
|
||||
(not context)
|
||||
(memq context '(nil top))
|
||||
(looking-at c-after-suffixed-type-decl-key)
|
||||
(if (and got-parens
|
||||
(not got-prefix)
|
||||
@ -8498,7 +8727,7 @@ comment at the start of cc-engine.el for more info."
|
||||
(when (and got-prefix-before-parens
|
||||
at-type
|
||||
(or at-decl-end (looking-at "=[^=]"))
|
||||
(not context)
|
||||
(memq context '(nil top))
|
||||
(or (not got-suffix)
|
||||
at-decl-start))
|
||||
;; Got something like "foo * bar;". Since we're not inside
|
||||
@ -8524,7 +8753,7 @@ comment at the start of cc-engine.el for more info."
|
||||
(throw 'at-decl-or-cast t)))
|
||||
|
||||
;; CASE 18
|
||||
(when (and context
|
||||
(when (and (not (memq context '(nil top)))
|
||||
(or got-prefix
|
||||
(and (eq context 'decl)
|
||||
(not c-recognize-paren-inits)
|
||||
|
@ -899,7 +899,8 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
(c-get-char-property (1- (point)) 'c-type)))))
|
||||
(when (memq prop '(c-decl-id-start c-decl-type-start))
|
||||
(c-forward-syntactic-ws limit)
|
||||
(c-font-lock-declarators limit t (eq prop 'c-decl-type-start))))
|
||||
(c-font-lock-declarators limit t (eq prop 'c-decl-type-start)
|
||||
(c-bs-at-toplevel-p (point)))))
|
||||
|
||||
(setq c-font-lock-context ;; (c-guess-font-lock-context)
|
||||
(save-excursion
|
||||
@ -991,7 +992,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
(goto-char pos)))))
|
||||
nil)
|
||||
|
||||
(defun c-font-lock-declarators (limit list types)
|
||||
(defun c-font-lock-declarators (limit list types not-top)
|
||||
;; Assuming the point is at the start of a declarator in a declaration,
|
||||
;; fontify the identifier it declares. (If TYPES is set, it does this via
|
||||
;; the macro `c-fontify-types-and-refs'.)
|
||||
@ -1001,7 +1002,9 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
;; additionally, mark the commas with c-type property 'c-decl-id-start or
|
||||
;; 'c-decl-type-start (according to TYPES). Stop at LIMIT.
|
||||
;;
|
||||
;; If TYPES is non-nil, fontify all identifiers as types.
|
||||
;; If TYPES is non-nil, fontify all identifiers as types. If NOT-TOP is
|
||||
;; non-nil, we are not at the top-level ("top-level" includes being directly
|
||||
;; inside a class or namespace, etc.).
|
||||
;;
|
||||
;; Nil is always returned. The function leaves point at the delimiter after
|
||||
;; the last declarator it processes.
|
||||
@ -1025,6 +1028,14 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
(setq next-pos (point)
|
||||
id-start (car decl-res)
|
||||
id-face (if (and (eq (char-after) ?\()
|
||||
(or (not (c-major-mode-is 'c++-mode))
|
||||
(not not-top)
|
||||
(car (cddr (cddr decl-res))) ; Id is in
|
||||
; parens, etc.
|
||||
(save-excursion
|
||||
(forward-char)
|
||||
(c-forward-syntactic-ws)
|
||||
(looking-at "[*&]")))
|
||||
(not (car (cddr decl-res))) ; brackets-after-id
|
||||
(or (not (c-major-mode-is 'c++-mode))
|
||||
(save-excursion
|
||||
@ -1199,7 +1210,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
c-decl-start-re
|
||||
(eval c-maybe-decl-faces)
|
||||
|
||||
(lambda (match-pos inside-macro)
|
||||
(lambda (match-pos inside-macro &optional toplev)
|
||||
;; Note to maintainers: don't use `limit' inside this lambda form;
|
||||
;; c-find-decl-spots sometimes narrows to less than `limit'.
|
||||
(setq start-pos (point))
|
||||
@ -1223,7 +1234,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
(let ((type (and (> match-pos (point-min))
|
||||
(c-get-char-property (1- match-pos) 'c-type))))
|
||||
(cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{)))
|
||||
(setq context nil
|
||||
(setq context (and toplev 'top)
|
||||
c-restricted-<>-arglists nil))
|
||||
;; A control flow expression or a decltype
|
||||
((and (eq (char-before match-pos) ?\()
|
||||
@ -1273,7 +1284,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
'c-not-decl))
|
||||
;; We're inside an "ordinary" open brace.
|
||||
((eq (char-before match-pos) ?{)
|
||||
(setq context nil
|
||||
(setq context (and toplev 'top)
|
||||
c-restricted-<>-arglists nil))
|
||||
;; Inside an angle bracket arglist.
|
||||
((or (eq type 'c-<>-arg-sep)
|
||||
@ -1411,7 +1422,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
(goto-char (car decl-or-cast))
|
||||
|
||||
(let ((decl-list
|
||||
(if context
|
||||
(if (not (memq context '(nil top)))
|
||||
;; Should normally not fontify a list of
|
||||
;; declarators inside an arglist, but the first
|
||||
;; argument in the ';' separated list of a "for"
|
||||
@ -1437,7 +1448,8 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
'c-decl-id-start)))))
|
||||
|
||||
(c-font-lock-declarators
|
||||
(min limit (point-max)) decl-list (cadr decl-or-cast)))
|
||||
(min limit (point-max)) decl-list
|
||||
(cadr decl-or-cast) (not toplev)))
|
||||
|
||||
;; A declaration has been successfully identified, so do all the
|
||||
;; fontification of types and refs that've been recorded.
|
||||
@ -1498,7 +1510,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
(c-put-char-property (1- (point)) 'c-type 'c-decl-id-start)
|
||||
|
||||
(c-forward-syntactic-ws)
|
||||
(c-font-lock-declarators limit t nil)))
|
||||
(c-font-lock-declarators limit t nil t)))
|
||||
nil)
|
||||
|
||||
(defun c-font-lock-cut-off-declarators (limit)
|
||||
@ -1512,6 +1524,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
;; fontification".
|
||||
(let ((decl-search-lim (c-determine-limit 1000))
|
||||
paren-state bod-res is-typedef encl-pos
|
||||
(here (point))
|
||||
c-recognize-knr-p) ; Strictly speaking, bogus, but it
|
||||
; speeds up lisp.h tremendously.
|
||||
(save-excursion
|
||||
@ -1539,7 +1552,8 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
(c-forward-syntactic-ws))
|
||||
;; At a real declaration?
|
||||
(if (memq (c-forward-type t) '(t known found decltype))
|
||||
(c-font-lock-declarators limit t is-typedef)))))))
|
||||
(c-font-lock-declarators
|
||||
limit t is-typedef (not (c-bs-at-toplevel-p here)))))))))
|
||||
nil))
|
||||
|
||||
(defun c-font-lock-enclosing-decls (limit)
|
||||
@ -1573,7 +1587,8 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||
(goto-char ps-elt)
|
||||
(when (c-safe (c-forward-sexp))
|
||||
(c-forward-syntactic-ws)
|
||||
(c-font-lock-declarators limit t in-typedef))))))))
|
||||
(c-font-lock-declarators limit t in-typedef
|
||||
(not (c-bs-at-toplevel-p (point)))))))))))
|
||||
|
||||
(defun c-font-lock-raw-strings (limit)
|
||||
;; Fontify C++ raw strings.
|
||||
@ -1741,7 +1756,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
|
||||
(eval . (list ,(c-make-font-lock-search-function
|
||||
'c-known-type-key
|
||||
'(1 'font-lock-type-face t)
|
||||
'((c-font-lock-declarators limit t nil)
|
||||
'((c-font-lock-declarators limit t nil nil)
|
||||
(save-match-data
|
||||
(goto-char (match-end 1))
|
||||
(c-forward-syntactic-ws))
|
||||
@ -1763,7 +1778,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
|
||||
"\\)"))
|
||||
`(,type-match
|
||||
'font-lock-type-face t)
|
||||
`((c-font-lock-declarators limit t nil)
|
||||
`((c-font-lock-declarators limit t nil nil)
|
||||
(save-match-data
|
||||
(goto-char (match-end ,type-match))
|
||||
(c-forward-syntactic-ws))
|
||||
@ -1775,7 +1790,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
|
||||
(concat "\\<\\("
|
||||
(regexp-opt (c-lang-const c-typeless-decl-kwds))
|
||||
"\\)\\>")
|
||||
'((c-font-lock-declarators limit t nil)
|
||||
'((c-font-lock-declarators limit t nil nil)
|
||||
(save-match-data
|
||||
(goto-char (match-end 1))
|
||||
(c-forward-syntactic-ws))
|
||||
@ -2014,7 +2029,7 @@ higher."
|
||||
;; before the '{' of the enum list, to avoid searching too far.
|
||||
"[^][{};/#=]*"
|
||||
"{")
|
||||
'((c-font-lock-declarators limit t nil)
|
||||
'((c-font-lock-declarators limit t nil t)
|
||||
(save-match-data
|
||||
(goto-char (match-end 0))
|
||||
(c-put-char-property (1- (point)) 'c-type
|
||||
@ -2413,7 +2428,7 @@ need for `c++-font-lock-extra-types'.")
|
||||
limit
|
||||
"[-+]"
|
||||
nil
|
||||
(lambda (match-pos inside-macro)
|
||||
(lambda (match-pos inside-macro &optional top-level)
|
||||
(forward-char)
|
||||
(c-font-lock-objc-method))))
|
||||
nil)
|
||||
|
@ -479,10 +479,12 @@ so that all identifiers are recognized as words.")
|
||||
c-before-change-check-<>-operators
|
||||
c-depropertize-CPP
|
||||
c-before-after-change-digit-quote
|
||||
c-invalidate-macro-cache)
|
||||
c-invalidate-macro-cache
|
||||
c-truncate-bs-cache)
|
||||
(c objc) '(c-extend-region-for-CPP
|
||||
c-depropertize-CPP
|
||||
c-invalidate-macro-cache)
|
||||
c-invalidate-macro-cache
|
||||
c-truncate-bs-cache)
|
||||
;; java 'c-before-change-check-<>-operators
|
||||
awk 'c-awk-record-region-clear-NL)
|
||||
(c-lang-defvar c-get-state-before-change-functions
|
||||
@ -2588,6 +2590,41 @@ Note that Java specific rules are currently applied to tell this from
|
||||
(c-lang-defvar c-opt-inexpr-brace-list-key
|
||||
(c-lang-const c-opt-inexpr-brace-list-key))
|
||||
|
||||
(c-lang-defconst c-flat-decl-block-kwds
|
||||
;; Keywords that can introduce another declaration level, i.e. where a
|
||||
;; following "{" isn't a function block or brace list. Note that, for
|
||||
;; historical reasons, `c-decl-block-key' is NOT constructed from this lang
|
||||
;; const.
|
||||
t (c--delete-duplicates
|
||||
(append (c-lang-const c-class-decl-kwds)
|
||||
(c-lang-const c-other-block-decl-kwds)
|
||||
(c-lang-const c-inexpr-class-kwds))
|
||||
:test 'string-equal))
|
||||
|
||||
(c-lang-defconst c-brace-stack-thing-key
|
||||
;; Regexp matching any keyword or operator relevant to the brace stack (see
|
||||
;; `c-update-brace-stack' in cc-engine.el).
|
||||
t (c-make-keywords-re 'appendable
|
||||
(append
|
||||
(c-lang-const c-flat-decl-block-kwds)
|
||||
(if (c-lang-const c-recognize-<>-arglists)
|
||||
'("{" "}" ";" "," ")" ":" "<")
|
||||
'("{" "}" ";" "," ")" ":")))))
|
||||
(c-lang-defvar c-brace-stack-thing-key (c-lang-const c-brace-stack-thing-key))
|
||||
|
||||
(c-lang-defconst c-brace-stack-no-semi-key
|
||||
;; Regexp matching any keyword or operator relevant to the brace stack when
|
||||
;; a semicolon is not relevant (see `c-update-brace-stack' in
|
||||
;; cc-engine.el).
|
||||
t (c-make-keywords-re 'appendable
|
||||
(append
|
||||
(c-lang-const c-flat-decl-block-kwds)
|
||||
(if (c-lang-const c-recognize-<>-arglists)
|
||||
'("{" "}" "<")
|
||||
'("{" "}")))))
|
||||
(c-lang-defvar c-brace-stack-no-semi-key
|
||||
(c-lang-const c-brace-stack-no-semi-key))
|
||||
|
||||
(c-lang-defconst c-decl-block-key
|
||||
;; Regexp matching keywords in any construct that contain another
|
||||
;; declaration level, i.e. that isn't followed by a function block
|
||||
@ -3031,6 +3068,28 @@ Identifier syntax is in effect when this is matched \(see
|
||||
(c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key)
|
||||
'dont-doc)
|
||||
|
||||
(c-lang-defconst c-type-decl-operator-prefix-key
|
||||
"Regexp matching any declarator operator which isn't a keyword
|
||||
that might precede the identifier in a declaration, e.g. the
|
||||
\"*\" in \"char *argv\". The end of the first submatch is taken
|
||||
as the end of the operator. Identifier syntax is in effect when
|
||||
this is matched \(see `c-identifier-syntax-table')."
|
||||
t ;; Default to a regexp that never matches.
|
||||
"\\<\\>"
|
||||
;; Check that there's no "=" afterwards to avoid matching tokens
|
||||
;; like "*=".
|
||||
(c objc) (concat "\\(\\*\\)"
|
||||
"\\([^=]\\|$\\)")
|
||||
c++ (concat "\\("
|
||||
"\\.\\.\\."
|
||||
"\\|"
|
||||
"\\*"
|
||||
"\\)"
|
||||
"\\([^=]\\|$\\)")
|
||||
pike "\\(\\*\\)\\([^=]\\|$\\)")
|
||||
(c-lang-defvar c-type-decl-operator-prefix-key
|
||||
(c-lang-const c-type-decl-operator-prefix-key))
|
||||
|
||||
(c-lang-defconst c-type-decl-suffix-key
|
||||
"Regexp matching the declarator operators that might follow after the
|
||||
identifier in a declaration, e.g. the \"[\" in \"char argv[]\". This
|
||||
|
@ -557,6 +557,8 @@ that requires a literal mode spec at compile time."
|
||||
|
||||
;; Initialize the cache of brace pairs, and opening braces/brackets/parens.
|
||||
(c-state-cache-init)
|
||||
;; Initialize the "brace stack" cache.
|
||||
(c-init-bs-cache)
|
||||
|
||||
(when (or c-recognize-<>-arglists
|
||||
(c-major-mode-is 'awk-mode)
|
||||
|
Loading…
Reference in New Issue
Block a user