;; 'syntax-table
;; Used to modify the syntax of some characters. It is used to
;; mark the "<" and ">" of angle bracket parens with paren syntax, to
-;; "hide" obtrusive characters in preprocessor lines, and to mark C++
-;; raw strings to enable their fontification.
+;; "hide" obtrusive characters in preprocessor lines, to mark C++ raw
+;; strings to enable their fontification, and to mark syntactically
+;; wrong single quotes, again for their fontification.
;;
;; This property is used on single characters and is therefore
;; always treated as front and rear nonsticky (or start and end open
;; Put on the brace which introduces a brace list and on the commas
;; which separate the elements within it.
;;
-;; 'c-typedef This property is applied to the first character of a
-;; "typedef" keyword. It's value is a list of the identifiers that
-;; the "typedef" declares as types.
+;; 'c-digit-separator
+;; Used for digit separators in numeric literals, where it gets set
+;; with the value t.
+;;
+;; 'c-typedef
+;; This property is applied to the first character of a "typedef"
+;; keyword. It's value is a list of the identifiers that the "typedef"
+;; declares as types.
;;
;; 'c-awk-NL-prop
;; Used in AWK mode to mark the various kinds of newlines. See
\f
(defmacro c-looking-at-c++-attribute ()
- ;; If we're in C++ Mode, and point is at the [[ introducing an attribute,
- ;; return the position of the end of the attribute, otherwise return nil.
- ;; The match data are NOT preserved over this macro.
+ ;; If we're in C or C++ Mode, and point is at the [[ introducing an
+ ;; attribute, return the position of the end of the attribute, otherwise
+ ;; return nil. The match data are NOT preserved over this macro.
`(and
- (c-major-mode-is 'c++-mode)
+ (c-major-mode-is '(c-mode c++-mode))
(looking-at "\\[\\[")
(save-excursion
(and
;; In a string/comment?
((setq lit-range (c-literal-limits from))
(goto-char (cdr lit-range)))
- ;; Skip over a C++ attribute?
+ ;; Skip over a C or C++ attribute?
((eq (char-after) ?\[)
(if (setq attr-end (c-looking-at-c++-attribute))
(goto-char attr-end)
(defvar c-sws-lit-limits nil)
(defun c-enclosing-c++-attribute ()
- ;; If we're in C++ Mode, and point is within a correctly balanced [[ ... ]]
- ;; attribute structure, return a cons of its starting and ending positions.
- ;; Otherwise, return nil.
+ ;; If we're in C or C++ Mode, and point is within a correctly balanced [[
+ ;; ... ]] attribute structure, return a cons of its starting and ending
+ ;; positions. Otherwise, return nil.
(and
- (c-major-mode-is 'c++-mode)
+ (c-major-mode-is '(c-mode c++-mode))
(save-excursion
(let ((lim (max (- (point) 200) (point-min)))
cand)
(when (or (looking-at c-syntactic-ws-start)
(and c-opt-cpp-prefix
(looking-at c-noise-macro-name-re))
- (and (c-major-mode-is 'c++-mode)
+ (and (c-major-mode-is '(c-mode c++-mode))
(looking-at "\\[\\["))
(looking-at c-doc-line-join-re))
(re-search-backward doc-line-join-here
(c-point 'bopl) t))
(and
- (c-major-mode-is 'c++-mode)
+ (c-major-mode-is '(c-mode c++-mode))
(eq (char-before) ?\])
(eq (char-before (1- (point))) ?\])
(save-excursion
(goto-char next-rung-pos)
t)
- ((and (c-major-mode-is 'c++-mode)
+ ((and (c-major-mode-is '(c-mode c++-mode))
(eq (char-before) ?\])
(eq (char-before (1- (point))) ?\])
(save-excursion
(goto-char here)
nil)))
+(defmacro c-forward-align-clause-throw-if-invalid (throw-tag)
+ ;; If we are at a `c-type-modifier-with-parens-key' keyword, try to go
+ ;; forward over the clause it introduces, and return t. If the clause is
+ ;; ill formed (or absent), move point to START, set RES to nil, and throw
+ ;; nil to the tag THROW-TAG. Otherwise, return nil. The match data are
+ ;; preserved.
+ ;; This macro is intended only for use withing `c-forward-type'.
+ `(if (save-match-data
+ (looking-at c-type-modifier-with-parens-key))
+ (if (and (zerop (c-forward-token-2))
+ (eq (char-after) ?\()
+ (c-safe (c-go-list-forward))
+ (eq (char-before) ?\))
+ (setq pos (point))
+ (progn (c-forward-syntactic-ws) t))
+ t
+ (setq res nil)
+ (goto-char start)
+ (throw ,throw-tag nil))
+ nil))
+
(defun c-forward-keyword-clause (match &optional stop-at-end)
- ;; Submatch MATCH in the current match data is assumed to surround a
- ;; token. If it's a keyword, move over it and any immediately
- ;; following clauses associated with it, stopping either at the start
- ;; of the next token, or (when STOP-AT-END is non-nil) at the end
- ;; of the clause. t is returned in that case, otherwise the point
- ;; stays and nil is returned. The kind of clauses that are
- ;; recognized are those specified by `c-type-list-kwds',
- ;; `c-ref-list-kwds', `c-colon-type-list-kwds',
+ ;; Submatch MATCH in the current match data is assumed to surround a token.
+ ;; If it's a keyword, move over it and, if present, over any immediately
+ ;; following clauses associated with it, stopping either at the start of the
+ ;; next token, or (when STOP-AT-END is non-nil) at the end of the clause. t
+ ;; is returned in that case, otherwise the point stays and nil is returned.
+ ;; The kind of clauses that are recognized are those specified by
+ ;; `c-type-list-kwds', `c-ref-list-kwds', `c-colon-type-list-kwds',
;; `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds',
;; `c-<>-arglist-kwds', and `c-protection-kwds'.
;;
;; o - 'found if it's a type that matches one in `c-found-types';
;; o - 'maybe if it's an identifier that might be a type;
;; o - 'decltype if it's a decltype(variable) declaration; - or
- ;; o - 'no-id if "auto" precluded parsing a type identifier (C++)
+ ;; o - 'no-id if "auto" precluded parsing a type identifier (C or C++)
;; or the type int was implicit (C).
;; o - nil if it can't be a type (the point isn't moved then).
;;
(c-forward-syntactic-ws))
(let ((start (point)) pos res name-res id-start id-end id-range
- post-prefix-pos prefix-end-pos)
+ post-prefix-pos prefix-end-pos equals-makes-type)
;; Skip leading type modifiers. If any are found we know it's a
;; prefix of a type.
- (when c-maybe-typeless-specifier-re
- (while (looking-at c-maybe-typeless-specifier-re)
- (save-match-data
- (when (looking-at c-no-type-key)
- (setq res 'no-id)))
+ (catch 'type-error
+ (when c-maybe-typeless-specifier-re
+ (while (looking-at c-maybe-typeless-specifier-re)
+ (save-match-data
+ (when (looking-at c-no-type-key)
+ (setq res 'no-id))
+ (when (looking-at c-no-type-with-equals-key)
+ (setq equals-makes-type t)))
+ (if (c-forward-align-clause-throw-if-invalid 'type-error)
+ (setq prefix-end-pos pos)
+ (goto-char (match-end 1))
+ (setq prefix-end-pos (point))
+ (setq pos (point))
+ (c-forward-syntactic-ws)
+ (or (eq res 'no-id)
+ (setq res 'prefix)))))
+ (setq post-prefix-pos (point))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ (cond
+ ((looking-at c-typeof-key) ; e.g. C++'s "decltype".
(goto-char (match-end 1))
- (setq prefix-end-pos (point))
(setq pos (point))
(c-forward-syntactic-ws)
- (or (eq res 'no-id)
- (setq res 'prefix))))
- (setq post-prefix-pos (point))
+ (setq res (and (eq (char-after) ?\()
+ (c-safe (c-forward-sexp))
+ 'decltype))
+ (if res
+ (progn
+ (setq pos (point))
+ (c-forward-syntactic-ws))
+ (goto-char start)))
- (cond
- ((looking-at c-typeof-key) ; e.g. C++'s "decltype".
- (goto-char (match-end 1))
- (setq pos (point))
- (c-forward-syntactic-ws)
- (setq res (and (eq (char-after) ?\()
- (c-safe (c-forward-sexp))
- 'decltype))
- (if res
- (progn
- (setq pos (point))
- (c-forward-syntactic-ws))
- (goto-char start)))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ((looking-at c-type-prefix-key) ; e.g. "struct", "class", but NOT
- ; "typedef".
- (goto-char (match-end 1))
- (setq pos (point))
- (c-forward-syntactic-ws)
+ ((looking-at c-type-prefix-key) ; e.g. "struct", "class", but NOT
+ ; "typedef".
+ (goto-char (match-end 1))
+ (setq pos (point))
+ (c-forward-syntactic-ws)
- (while (cond
- ((looking-at c-decl-hangon-key)
- (c-forward-keyword-clause 1 t)
- (setq pos (point))
- (c-forward-syntactic-ws))
- ((looking-at c-pack-key)
- (goto-char (match-end 1))
- (setq pos (point))
- (c-forward-syntactic-ws))
- ((and c-opt-cpp-prefix
- (looking-at c-noise-macro-with-parens-name-re))
- (c-forward-noise-clause t)
- (setq pos (point))
- (c-forward-syntactic-ws))))
+ (while (cond
+ ((looking-at c-decl-hangon-key)
+ (c-forward-keyword-clause 1 t)
+ (setq pos (point))
+ (c-forward-syntactic-ws))
+ ((looking-at c-pack-key)
+ (goto-char (match-end 1))
+ (setq pos (point))
+ (c-forward-syntactic-ws))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause t)
+ (setq pos (point))
+ (c-forward-syntactic-ws))))
- (setq id-start (point))
- (setq name-res (c-forward-name t))
- (setq pos (point))
- (setq res (not (null name-res)))
- (when (eq name-res t)
- ;; With some keywords the name can be used without the prefix, so we
- ;; add the name to `c-found-types' when this is the case.
- (when (save-excursion
- (goto-char post-prefix-pos)
- (looking-at c-self-contained-typename-key))
- (c-add-type id-start
- (point)))
- (when (and c-record-type-identifiers
- c-last-identifier-range)
- (c-record-type-id c-last-identifier-range)))
- (c-forward-syntactic-ws)
- (when (and brace-block-too
- (memq res '(t nil))
- (eq (char-after) ?\{)
- (save-excursion
- (c-safe
- (progn (c-forward-sexp)
- (setq pos (point))))))
- (goto-char pos)
+ (setq id-start (point))
+ (setq name-res (c-forward-name t))
+ (setq pos (point))
+ (setq res (not (null name-res)))
+ (when (eq name-res t)
+ ;; With some keywords the name can be used without the prefix, so we
+ ;; add the name to `c-found-types' when this is the case.
+ (when (save-excursion
+ (goto-char post-prefix-pos)
+ (looking-at c-self-contained-typename-key))
+ (c-add-type id-start
+ (point)))
+ (when (and c-record-type-identifiers
+ c-last-identifier-range)
+ (c-record-type-id c-last-identifier-range)))
(c-forward-syntactic-ws)
- (setq res t))
- (unless res (goto-char start))) ; invalid syntax
+ (when (and brace-block-too
+ (memq res '(t nil))
+ (eq (char-after) ?\{)
+ (save-excursion
+ (c-safe
+ (progn (c-forward-sexp)
+ (setq pos (point))))))
+ (goto-char pos)
+ (c-forward-syntactic-ws)
+ (setq res t))
+ (unless res (goto-char start))) ; invalid syntax
- ((and
- (not (eq res 'no-id))
- (progn
- (setq pos nil)
- (while (and c-opt-cpp-prefix
- (looking-at c-noise-macro-with-parens-name-re))
- (c-forward-noise-clause))
- (if (looking-at c-identifier-start)
- (save-excursion
- (setq id-start (point)
- name-res (c-forward-name t))
- (when name-res
- (setq id-end (point)
- id-range c-last-identifier-range))))
- (and (cond ((looking-at c-primitive-type-key)
- (setq res t))
- ((c-with-syntax-table c-identifier-syntax-table
- (looking-at c-known-type-key))
- (setq res 'known)))
- (or (not id-end)
- (>= (save-excursion
- (save-match-data
- (goto-char (match-end 1))
- (setq pos (point))
- (c-forward-syntactic-ws)
- pos))
- id-end)
- (setq res nil)))))
- ;; Looking at a primitive or known type identifier. We've
- ;; checked for a name first so that we don't go here if the
- ;; known type match only is a prefix of another name.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (setq id-end (match-end 1))
+ ((looking-at c-type-with-paren-key) ; C's "_BitInt".
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (if (and (eq (char-after) ?\()
+ (c-go-list-forward nil (min (+ (point) 500) (point-max)))
+ (eq (char-before) ?\)))
+ (progn
+ (setq pos (point))
+ (c-forward-syntactic-ws)
+ (setq res t))
+ (goto-char start)
+ (setq res nil))) ; invalid syntax.
- (when (and c-record-type-identifiers
- (or c-promote-possible-types (eq res t)))
- (c-record-type-id (cons (match-beginning 1) (match-end 1))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (cond
- ((and c-opt-type-component-key
+ ((and
+ (not (eq res 'no-id))
+ (not (and equals-makes-type
+ (save-excursion
+ (and (zerop (c-forward-token-2))
+ (looking-at "=\\([^=]\\|$\\)")))
+ (setq res 'no-id)))
+ (progn
+ (setq pos nil)
+ (while (and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))
+ (if (looking-at c-identifier-start)
+ (save-excursion
+ (setq id-start (point)
+ name-res (c-forward-name t))
+ (when name-res
+ (setq id-end (point)
+ id-range c-last-identifier-range))))
+ (and (cond ((looking-at c-primitive-type-key)
+ (setq res t))
+ ((c-with-syntax-table c-identifier-syntax-table
+ (looking-at c-known-type-key))
+ (setq res 'known)))
+ (or (not id-end)
+ (>= (save-excursion
+ (save-match-data
+ (goto-char (match-end 1))
+ (setq pos (point))
+ (c-forward-syntactic-ws)
+ pos))
+ id-end)
+ (setq res nil)))))
+ ;; Looking at a primitive or known type identifier. We've
+ ;; checked for a name first so that we don't go here if the
+ ;; known type match only is a prefix of another name.
+
+ (setq id-end (match-end 1))
+
+ (when (and c-record-type-identifiers
+ (or c-promote-possible-types (eq res t)))
+ (c-record-type-id (cons (match-beginning 1) (match-end 1))))
+
+ (cond
+ ((and c-opt-type-component-key
(save-match-data
(looking-at c-opt-type-component-key)))
;; There might be more keywords for the type.
- (let (safe-pos)
- (c-forward-keyword-clause 1 t)
+ (let (safe-pos)
+ (c-forward-keyword-clause 1 t)
+ (while (progn
+ (setq safe-pos (point))
+ (c-forward-syntactic-ws)
+ (looking-at c-opt-type-component-key))
+ (when (and c-record-type-identifiers
+ (looking-at c-primitive-type-key))
+ (c-record-type-id (cons (match-beginning 1)
+ (match-end 1))))
+ (or (c-forward-align-clause-throw-if-invalid 'type-error)
+ (c-forward-keyword-clause 1 t)))
+ (if (looking-at c-primitive-type-key)
+ (progn
+ (when c-record-type-identifiers
+ (c-record-type-id (cons (match-beginning 1)
+ (match-end 1))))
+ (c-forward-keyword-clause 1 t)
+ (setq res t)
+ (while (progn
+ (setq safe-pos (point))
+ (c-forward-syntactic-ws)
+ (looking-at c-opt-type-component-key))
+ (c-forward-keyword-clause 1 t)))
+ (goto-char safe-pos)
+ (setq res 'prefix))
+ (setq pos (point))))
+ ((save-match-data (c-forward-keyword-clause 1 t))
(while (progn
- (setq safe-pos (point))
+ (setq pos (point))
(c-forward-syntactic-ws)
- (looking-at c-opt-type-component-key))
- (when (and c-record-type-identifiers
- (looking-at c-primitive-type-key))
- (c-record-type-id (cons (match-beginning 1)
- (match-end 1))))
- (c-forward-keyword-clause 1 t))
- (if (looking-at c-primitive-type-key)
- (progn
- (when c-record-type-identifiers
- (c-record-type-id (cons (match-beginning 1)
- (match-end 1))))
- (c-forward-keyword-clause 1 t)
- (setq res t)
- (while (progn
- (setq safe-pos (point))
- (c-forward-syntactic-ws)
- (looking-at c-opt-type-component-key))
- (c-forward-keyword-clause 1 t)))
- (goto-char safe-pos)
- (setq res 'prefix))
- (setq pos (point))))
- ((save-match-data (c-forward-keyword-clause 1 t))
- (while (progn
- (setq pos (point))
- (c-forward-syntactic-ws)
- (and c-opt-type-component-key
- (looking-at c-opt-type-component-key)))
- (c-forward-keyword-clause 1 t)))
- (pos (goto-char pos))
- (t (goto-char (match-end 1))
- (setq pos (point))))
- (c-forward-syntactic-ws))
-
- ((and (eq name-res t)
- (eq res 'prefix)
- (c-major-mode-is 'c-mode)
- (save-excursion
- (goto-char id-end)
- (setq pos (point))
- (c-forward-syntactic-ws)
- (and (not (looking-at c-symbol-start))
- (or
- (not (looking-at c-type-decl-prefix-key))
- (and (eq (char-after) ?\()
- (not (save-excursion
- (c-forward-declarator))))))))
- ;; A C specifier followed by an implicit int, e.g.
- ;; "register count;"
- (goto-char prefix-end-pos)
- (setq pos (point))
- (unless stop-at-end
+ (and c-opt-type-component-key
+ (looking-at c-opt-type-component-key)))
+ (or (c-forward-align-clause-throw-if-invalid 'type-error)
+ (c-forward-keyword-clause 1 t))))
+ (pos (goto-char pos))
+ (t (goto-char (match-end 1))
+ (setq pos (point))))
(c-forward-syntactic-ws))
- (setq res 'no-id))
- (name-res
- (cond ((eq name-res t)
- ;; A normal identifier.
- (goto-char id-end)
- (setq pos (point))
- (c-forward-syntactic-ws)
- (if (or res c-promote-possible-types)
- (progn
- (when (not (eq c-promote-possible-types 'just-one))
- (c-add-type id-start id-end))
- (when (and c-record-type-identifiers id-range)
- (c-record-type-id id-range))
- (unless res
- (setq res 'found))
- (when (eq res 'prefix)
- (setq res t)))
- (setq res (if (c-check-qualified-type id-start)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ ((and (eq name-res t)
+ (eq res 'prefix)
+ (c-major-mode-is 'c-mode)
+ (save-excursion
+ (goto-char id-end)
+ (setq pos (point))
+ (c-forward-syntactic-ws)
+ (and (not (looking-at c-symbol-start))
+ (or
+ (not (looking-at c-type-decl-prefix-key))
+ (and (eq (char-after) ?\()
+ (not (save-excursion
+ (c-forward-declarator))))))))
+ ;; A C specifier followed by an implicit int, e.g.
+ ;; "register count;"
+ (goto-char prefix-end-pos)
+ (setq pos (point))
+ (unless stop-at-end
+ (c-forward-syntactic-ws))
+ (setq res 'no-id))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ (name-res
+ (cond ((eq name-res t)
+ ;; A normal identifier.
+ (goto-char id-end)
+ (setq pos (point))
+ (c-forward-syntactic-ws)
+ (if (or res c-promote-possible-types)
+ (progn
+ (when (not (eq c-promote-possible-types 'just-one))
+ (c-add-type id-start id-end))
+ (when (and c-record-type-identifiers id-range)
+ (c-record-type-id id-range))
+ (unless res
+ (setq res 'found))
+ (when (eq res 'prefix)
+ (setq res t)))
+ (setq res (if (c-check-qualified-type id-start)
+ ;; It's an identifier that has been used as
+ ;; a type somewhere else.
+ 'found
+ ;; It's an identifier that might be a type.
+ 'maybe))))
+ ((eq name-res 'template)
+ ;; A template is sometimes a type.
+ (goto-char id-end)
+ (setq pos (point))
+ (c-forward-syntactic-ws)
+ (setq res
+ (if (eq (char-after) ?\()
+ (if (c-check-qualified-type id-start)
;; It's an identifier that has been used as
;; a type somewhere else.
'found
;; It's an identifier that might be a type.
- 'maybe))))
- ((eq name-res 'template)
- ;; A template is sometimes a type.
- (goto-char id-end)
- (setq pos (point))
- (c-forward-syntactic-ws)
- (setq res
- (if (eq (char-after) ?\()
- (if (c-check-qualified-type id-start)
- ;; It's an identifier that has been used as
- ;; a type somewhere else.
- 'found
- ;; It's an identifier that might be a type.
- 'maybe)
- t)))
- (t
- ;; Otherwise it's an operator identifier, which is not a type.
- (goto-char start)
- (setq res nil))))
-
- ((eq res 'prefix)
- ;; Deal with "extern "C" foo_t my_foo;"
- (setq res nil)))
-
- (when (not (memq res '(nil no-id)))
- ;; Skip trailing type modifiers. If any are found we know it's
- ;; a type.
- (when c-opt-type-modifier-key
- (while (looking-at c-opt-type-modifier-key) ; e.g. "const", "volatile"
+ 'maybe)
+ t)))
+ (t
+ ;; Otherwise it's an operator identifier, which is not a type.
+ (goto-char start)
+ (setq res nil))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ ((eq res 'prefix)
+ ;; Deal with "extern "C" foo_t my_foo;"
+ (setq res nil)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ (when (not (memq res '(nil no-id)))
+ ;; Skip trailing type modifiers. If any are found we know it's
+ ;; a type.
+ (when c-opt-type-modifier-key
+ (while (looking-at c-opt-type-modifier-key) ; e.g. "const", "volatile"
+ (unless (c-forward-align-clause-throw-if-invalid 'type-error)
+ (goto-char (match-end 1))
+ (setq pos (point))
+ (c-forward-syntactic-ws)
+ (setq res t))))
+
+ ;; Step over any type suffix operator. Do not let the existence
+ ;; of these alter the classification of the found type, since
+ ;; these operators typically are allowed in normal expressions
+ ;; too.
+ (when c-opt-type-suffix-key ; e.g. "..."
+ (while (looking-at c-opt-type-suffix-key)
+ (goto-char (match-end 1))
+ (setq pos (point))
+ (c-forward-syntactic-ws)))
+
+ ;; Skip any "WS" identifiers (e.g. "final" or "override" in C++)
+ (while (looking-at c-type-decl-suffix-ws-ids-key)
(goto-char (match-end 1))
(setq pos (point))
(c-forward-syntactic-ws)
- (setq res t)))
-
- ;; Step over any type suffix operator. Do not let the existence
- ;; of these alter the classification of the found type, since
- ;; these operators typically are allowed in normal expressions
- ;; too.
- (when c-opt-type-suffix-key ; e.g. "..."
- (while (looking-at c-opt-type-suffix-key)
- (goto-char (match-end 1))
+ (setq res t))
+
+ (when c-opt-type-concat-key ; Only/mainly for pike.
+ ;; Look for a trailing operator that concatenates the type
+ ;; with a following one, and if so step past that one through
+ ;; a recursive call. Note that we don't record concatenated
+ ;; types in `c-found-types' - it's the component types that
+ ;; are recorded when appropriate.
(setq pos (point))
- (c-forward-syntactic-ws)))
-
- ;; Skip any "WS" identifiers (e.g. "final" or "override" in C++)
- (while (looking-at c-type-decl-suffix-ws-ids-key)
- (goto-char (match-end 1))
- (setq pos (point))
- (c-forward-syntactic-ws)
- (setq res t))
-
- (when c-opt-type-concat-key ; Only/mainly for pike.
- ;; Look for a trailing operator that concatenates the type
- ;; with a following one, and if so step past that one through
- ;; a recursive call. Note that we don't record concatenated
- ;; types in `c-found-types' - it's the component types that
- ;; are recorded when appropriate.
- (setq pos (point))
- (let* ((c-promote-possible-types (or (memq res '(t known))
- c-promote-possible-types))
- ;; If we can't promote then set `c-record-found-types' so that
- ;; we can merge in the types from the second part afterwards if
- ;; it turns out to be a known type there.
- (c-record-found-types (and c-record-type-identifiers
- (not c-promote-possible-types)))
- subres)
- (if (and (looking-at c-opt-type-concat-key)
+ (let* ((c-promote-possible-types (or (memq res '(t known))
+ c-promote-possible-types))
+ ;; If we can't promote then set `c-record-found-types' so that
+ ;; we can merge in the types from the second part afterwards if
+ ;; it turns out to be a known type there.
+ (c-record-found-types (and c-record-type-identifiers
+ (not c-promote-possible-types)))
+ subres)
+ (if (and (looking-at c-opt-type-concat-key)
- (progn
- (goto-char (match-end 1))
- (c-forward-syntactic-ws)
- (setq subres (c-forward-type nil t))
- (setq pos (point))))
-
- (progn
- ;; If either operand certainly is a type then both are, but we
- ;; don't let the existence of the operator itself promote two
- ;; uncertain types to a certain one.
- (cond ((eq res t))
- ((eq subres t)
- (unless (eq name-res 'template)
- (c-add-type id-start id-end))
- (when (and c-record-type-identifiers id-range)
- (c-record-type-id id-range))
- (setq res t))
- ((eq res 'known))
- ((eq subres 'known)
- (setq res 'known))
- ((eq res 'found))
- ((eq subres 'found)
- (setq res 'found))
- (t
- (setq res 'maybe)))
-
- (when (and (eq res t)
- (consp c-record-found-types))
- ;; Cause the confirmed types to get fontified.
- (let ((cur c-record-found-types))
- (while (consp (car-safe cur))
- (c-fontify-new-found-type
- (buffer-substring-no-properties (caar cur) (cdar cur)))
- (setq cur (cdr cur))))
- ;; Merge in the ranges of any types found by the second
- ;; `c-forward-type'.
- (setq c-record-type-identifiers
- ;; `nconc' doesn't mind that the tail of
- ;; `c-record-found-types' is t.
- (nconc c-record-found-types
- c-record-type-identifiers)))))))
+ (progn
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (setq subres (c-forward-type nil t))
+ (setq pos (point))))
- (goto-char pos)
- (unless stop-at-end
- (c-forward-syntactic-ws))
+ (progn
+ ;; If either operand certainly is a type then both are, but we
+ ;; don't let the existence of the operator itself promote two
+ ;; uncertain types to a certain one.
+ (cond ((eq res t))
+ ((eq subres t)
+ (unless (eq name-res 'template)
+ (c-add-type id-start id-end))
+ (when (and c-record-type-identifiers id-range)
+ (c-record-type-id id-range))
+ (setq res t))
+ ((eq res 'known))
+ ((eq subres 'known)
+ (setq res 'known))
+ ((eq res 'found))
+ ((eq subres 'found)
+ (setq res 'found))
+ (t
+ (setq res 'maybe)))
+
+ (when (and (eq res t)
+ (consp c-record-found-types))
+ ;; Cause the confirmed types to get fontified.
+ (let ((cur c-record-found-types))
+ (while (consp (car-safe cur))
+ (c-fontify-new-found-type
+ (buffer-substring-no-properties (caar cur) (cdar cur)))
+ (setq cur (cdr cur))))
+ ;; Merge in the ranges of any types found by the second
+ ;; `c-forward-type'.
+ (setq c-record-type-identifiers
+ ;; `nconc' doesn't mind that the tail of
+ ;; `c-record-found-types' is t.
+ (nconc c-record-found-types
+ c-record-type-identifiers)))))))
- (when (and c-record-found-types (memq res '(known found)) id-range)
- (setq c-record-found-types
- (cons id-range c-record-found-types))))
+ (goto-char pos)
+ (unless stop-at-end
+ (c-forward-syntactic-ws))
+ (when (and c-record-found-types (memq res '(known found)) id-range)
+ (setq c-record-found-types
+ (cons id-range c-record-found-types)))))
;;(message "c-forward-type %s -> %s: %s" start (point) res)
res))
(and (zerop (c-forward-token-2)) ; over "requires".
(c-forward-constraint-clause limit stop-at-end)))
+(defun c-in-id-arglist ()
+ ;; If point is inside a paren delimited non-empty arglist, all of whose
+ ;; arguments are identifiers, return a cons of the start and (after) the end
+ ;; of the arglist. Otherwise return nil.
+ (let* ((paren-state (c-parse-state))
+ (enclosing-paren-pos (c-most-enclosing-brace paren-state)))
+ (save-excursion
+ (and
+ enclosing-paren-pos
+ (eq (char-after enclosing-paren-pos) ?\()
+ (progn
+ (goto-char (1+ enclosing-paren-pos))
+ (c-forward-syntactic-ws)
+ (catch 'in-arglist
+ (while
+ (and
+ (c-on-identifier)
+ (zerop (c-forward-token-2))
+ (progn
+ (when (eq (char-after) ?\))
+ (throw 'in-arglist
+ (cons enclosing-paren-pos (1+ (point)))))
+ (eq (char-after) ?\,))
+ (zerop (c-forward-token-2))))
+ nil))))))
+
(defun c-forward-decl-arglist (not-top id-in-parens &optional limit)
;; Point is at an open parenthesis, assumed to be the arglist of a function
;; declaration. Move over this arglist and following syntactic whitespace,
;; style declarations and parenthesis style initializers
;; aren't allowed then the single identifier must be a
;; type, else we require that it's known or found
- ;; (primitive types are handled above).
+ ;; (primitive types are handled above). We also allow
+ ;; 'maybe types when nameless types can be in arglists.
(or (and (not c-recognize-knr-p)
(not c-recognize-paren-inits))
- (memq at-type '(known found))))
+ (memq at-type '(known found))
+ (and c-recognize-nameless-type-decls
+ (eq at-type 'maybe))))
((eq context '<>)
;; Inside a template arglist. Accept known and found
;; types; other identifiers could just as well be
(c-put-font-lock-face (car elem) (cdr elem)
c-reference-face-name))))
+(defun c-font-lock-cpp-messages (limit)
+ ;; Font lock #error and #warning messages between point and LIMIT.
+ ;; Always return nil to prevent a further call to this function.
+ ;; The position of point at the end of this function is random.
+ (while
+ (and (< (point) limit)
+ (re-search-forward c-cpp-messages-re limit t))
+ (let ((beg (match-beginning c-cpp-message-match-no))
+ (end (match-end c-cpp-message-match-no)))
+ (c-put-font-lock-string-face beg end)
+ ;; We replace '(1) (punctuation) syntax-table text properties on ' by
+ ;; '(3) (symbol), so that these characters won't later get the warning
+ ;; face.
+ (goto-char beg)
+ (while (and
+ (< (point) end)
+ (c-search-forward-char-property-with-value-on-char
+ 'syntax-table '(1) ?\' end))
+ (c-put-char-property ;; -trim-caches
+ (1- (point)) 'syntax-table '(3)))
+ (goto-char end)))
+ nil)
+
(c-lang-defconst c-cpp-matchers
"Font lock matchers for preprocessor directives and purely lexical
stuff. Used on level 1 and higher."
;; sets `font-lock-type-face' in languages where
;; `c-recognize-<>-arglists' is set.
- t `(,@(when (c-lang-const c-opt-cpp-prefix)
+ t `(;; Fontify "invalid" comment delimiters
+ ,@(when (and (c-lang-const c-block-comment-starter)
+ (c-lang-const c-line-comment-starter))
+ `(c-maybe-font-lock-wrong-style-comments))
+ ,@(when (c-lang-const c-opt-cpp-prefix)
(let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)")
(ncle-depth (regexp-opt-depth noncontinued-line-end))
(sws-depth (c-lang-const c-syntactic-ws-depth))
(nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth)))
- `(;; Fontify "invalid" comment delimiters
- ,@(when (and (c-lang-const c-block-comment-starter)
- (c-lang-const c-line-comment-starter))
- `(c-maybe-font-lock-wrong-style-comments))
-
- ;; The stuff after #error and #warning is a message, so
+ `(;; The stuff after #error and #warning is a message, so
;; fontify it as a string.
,@(when (c-lang-const c-cpp-message-directives)
- (let* ((re (c-make-keywords-re 'appendable ; nil
- (c-lang-const c-cpp-message-directives)))
- (re-depth (regexp-opt-depth re)))
- `((,(concat noncontinued-line-end
- (c-lang-const c-opt-cpp-prefix)
- re
- "\\s +\\(.*\\)$")
- ,(+ ncle-depth re-depth 1) font-lock-string-face t))))
+ '(c-font-lock-cpp-messages))
;; Fontify filenames in #include <...> as strings.
,@(when (c-lang-const c-cpp-include-directives)
;; characters it allows within the list.
(let ((type (and (> match-pos (point-min))
(c-get-char-property (1- match-pos) 'c-type)))
- id-pos)
+ id-pos tok-end-pos)
(cond
;; Are we just after something like "(foo((bar))" ?
((and (eq (char-before match-pos) ?\))
(c-go-list-backward match-pos)
(progn
(c-backward-syntactic-ws)
- (and (setq id-pos (c-on-identifier))
- (goto-char id-pos)
- (progn
- (c-backward-syntactic-ws)
- (eq (char-before) ?\()))))
- (c-get-fontification-context (point) not-front-decl toplev))
+ (setq tok-end-pos (point))
+ (cond
+ ((and (setq id-pos (c-on-identifier))
+ (goto-char id-pos)
+ (progn
+ (c-backward-syntactic-ws)
+ (eq (char-before) ?\()))
+ (c-get-fontification-context (point) not-front-decl toplev))
+ ((progn
+ (goto-char tok-end-pos)
+ (and (zerop (c-backward-token-2))
+ (looking-at c-type-internal-paren-key)))
+ (cons 'not-decl nil))))))
((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{)))
(cons (and toplev 'top) nil))
- ;; A control flow expression or a decltype
+ ;; A control flow expression or a decltype, etc.
((and (eq (char-before match-pos) ?\()
(save-excursion
(goto-char match-pos)
(cons nil nil))
((or (looking-at c-block-stmt-2-key)
(looking-at c-block-stmt-1-2-key)
- (looking-at c-typeof-key))
+ (looking-at c-typeof-key)
+ (looking-at c-type-internal-paren-key))
(cons nil t))
(t nil)))))
;; Near BOB.
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
(cc-eval-when-compile
- (boundp 'parse-sexp-lookup-properties))
- ))
+ (boundp 'parse-sexp-lookup-properties)))
+ list-bounds)
;; Below we fontify a whole declaration even when it crosses the limit,
;; to avoid gaps when jit/lazy-lock fontifies the file a block at a
nil)
((eq context 'generic)
(c-font-lock-c11-generic-clause))
+
+ ;; K&R parameters.
+ ((and
+ c-recognize-knr-p
+ (or toplev inside-macro)
+ (eq context 'decl)
+ (setq list-bounds (c-in-id-arglist))
+ (save-excursion
+ (goto-char (car list-bounds))
+ (and (zerop (c-backward-token-2))
+ (eq (point) (c-on-identifier))))
+ (save-excursion
+ (goto-char (cdr list-bounds))
+ (c-forward-syntactic-ws)
+ (not (memq (char-after) '(?\; ?{ ?\? ?: ?\,)))))
+ ;; Nothing to fontify.
+ (goto-char (cdr list-bounds)))
+
(t
(setq decl-or-cast
(c-forward-decl-or-cast-1
;; Fontify basic types.
,(let ((re (c-make-keywords-re nil
- (c-lang-const c-primitive-type-kwds))))
+ (cl-delete-duplicates
+ (append (c-lang-const c-primitive-type-kwds)
+ (c-lang-const c-type-with-paren-kwds))
+ :test #'equal))))
(if (c-major-mode-is 'pike-mode)
;; No symbol is a keyword after "->" in Pike.
`(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
(c-lang-defconst c-has-quoted-numbers
"Whether the language has numbers quoted like 4'294'967'295."
t nil
- c++ t)
+ (c c++) t)
(c-lang-defvar c-has-quoted-numbers (c-lang-const c-has-quoted-numbers))
(c-lang-defconst c-has-compound-literals
'("error"))
(c c++ objc pike) '("error" "warning"))
+(c-lang-defconst c-cpp-message-directives-re
+ ;; Appendable regexp matching any of the tokens in `c-cpp-message-directives'.
+ t (c-make-keywords-re 'appendable (c-lang-const c-cpp-message-directives)))
+
+(c-lang-defconst noncontinued-line-end
+ t "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)")
+(c-lang-defconst ncle-depth
+ t (regexp-opt-depth (c-lang-const noncontinued-line-end)))
+
+(c-lang-defconst c-cpp-messages-re
+ ;; Regexp to match a #error or #warning construct. See
+ ;; `c-cpp-message-directives'.
+ t (if (c-lang-const c-cpp-message-directives)
+ (concat (c-lang-const noncontinued-line-end)
+ (c-lang-const c-opt-cpp-prefix)
+ (c-lang-const c-cpp-message-directives-re)
+ "\\s +\\(\\(\\\\\\(\\\\?\n\\|.\\)\\|[^\n]\\)*\\)$")))
+(c-lang-defvar c-cpp-messages-re (c-lang-const c-cpp-messages-re))
+
+(c-lang-defconst c-cpp-message-match-no
+ t (if (c-lang-const c-cpp-messages-re)
+ (+ 1 (c-lang-const ncle-depth)
+ (regexp-opt-depth (c-lang-const c-cpp-message-directives-re)))))
+(c-lang-defvar c-cpp-message-match-no (c-lang-const c-cpp-message-match-no))
+
(c-lang-defconst c-cpp-include-directives
"List of cpp directives (without the prefix) that are followed by a
file name in angle brackets or quotes."
t (if (c-lang-const c-opt-cpp-prefix)
'("include"))
+ c '("include" "embed")
objc '("include" "import"))
(c-lang-defconst c-cpp-include-key
"List of cpp directives (without the prefix) that are followed by an
expression."
t (if (c-lang-const c-opt-cpp-prefix)
- '("if" "elif")))
+ '("if" "elif"
+ "elifdef" "elifndef")))
(c-lang-defconst c-cpp-expr-intro-re
"Regexp which matches the start of a CPP directive which contains an
(c-lang-const c-opt-cpp-symbol) ; usually #
(substring (c-lang-const c-stmt-delim-chars) 1)) ; ";{}?:"
(c-lang-const c-stmt-delim-chars))
- c++ (concat (substring (c-lang-const c-stmt-boundary-skip-chars) 0 1) ; "^"
- "["
- (substring (c-lang-const c-stmt-boundary-skip-chars) 1))) ; ";{}?:"
+ (c c++) (concat
+ (substring (c-lang-const c-stmt-boundary-skip-chars) 0 1) ; "^"
+ "["
+ (substring (c-lang-const c-stmt-boundary-skip-chars) 1))) ; ";{}?:"
(c-lang-defvar c-stmt-boundary-skip-chars
(c-lang-const c-stmt-boundary-skip-chars))
;; `c-kwds-lang-consts' list below and used to build `c-keywords' etc.
(c-lang-defconst c-primitive-type-kwds
- "Primitive type keywords. As opposed to the other keyword lists, the
+ "Primitive type keywords. As opposed to most other keyword lists, the
keywords listed here are fontified with the type face instead of the
keyword face.
t '("char" "double" "float" "int" "long" "short" "signed"
"unsigned" "void")
c (append
- '("_Bool" "_Complex" "_Imaginary") ; Conditionally defined in C99.
+ '("_Bool" "_Complex" "_Imaginary" ;) Conditionally defined in C99.
+ "_Decimal32" "_Decimal64" "_Decimal128"
+ "bool" "char8_t" "char16_t" "char32_t" "nullptr_t")
(c-lang-const c-primitive-type-kwds))
c++ (append
- '("bool" "wchar_t" "char8_t" "char16_t" "char32_t")
+ '("bool" "wchar_t" "char8_t" "char16_t" "char32_t" "nullptr_t")
(c-lang-const c-primitive-type-kwds))
;; Objective-C extends C, but probably not the new stuff in C99.
objc (append
"Keywords followed by a parenthesized expression, which stands for
the type of that expression."
t nil
- c '("typeof") ; longstanding GNU C(++) extension.
+ c '("typeof" "typeof_unqual")
c++ '("decltype" "typeof"))
(c-lang-defconst c-typeof-key
(c-lang-defvar c-self-contained-typename-key
(c-lang-const c-self-contained-typename-key))
+(c-lang-defconst c-type-with-paren-kwds
+ "Keywords followed by a parenthesis expression, which form types."
+ t nil
+ c '("_BitInt"))
+
+(c-lang-defconst c-type-with-paren-key
+ "Adorned regexp which matches an element of `c-type-with-paren-kwds'."
+ t (c-make-keywords-re t (c-lang-const c-type-with-paren-kwds)))
+(c-lang-defvar c-type-with-paren-key (c-lang-const c-type-with-paren-key))
+
(c-lang-defconst c-type-prefix-kwds
"Keywords where the following name - if any - is a type name, and
where the keyword together with the symbol works as a type in
t (c-make-keywords-re t (c-lang-const c-type-prefix-kwds)))
(c-lang-defvar c-type-prefix-key (c-lang-const c-type-prefix-key))
+(c-lang-defconst c-type-modifier-with-parens-kwds
+ "Keywords which have parenthesis expressions which modify a type.
+They can appear anywhere in the type. Not included here are kwds which
+stand in place of a type, namely those in `c-no-type-kwds'."
+ t nil
+ c '("alignof" "alignas" "_Alignas" "_Alignof"))
+
+(c-lang-defconst c-type-modifier-with-parens-key
+ ;; Adorned regexp matching `c-type-modifier-with-parens-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-type-modifier-with-parens-kwds)))
+(c-lang-defvar c-type-modifier-with-parens-key
+ (c-lang-const c-type-modifier-with-parens-key))
+
+(c-lang-defconst c-type-internal-paren-kwds
+ ;; Keywords which can be followed by a parenthesis expression inside a type
+ ;; specification.
+ t (append (c-lang-const c-type-with-paren-kwds)
+ (c-lang-const c-type-modifier-with-parens-kwds)))
+
+(c-lang-defconst c-type-internal-paren-key
+ ;; Adorned regexp matching any member of `c-type-internal-paren-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-type-internal-paren-kwds)))
+(c-lang-defvar c-type-internal-paren-key
+ (c-lang-const c-type-internal-paren-key))
+
(c-lang-defconst c-type-modifier-prefix-kwds
"Type modifier keywords which can appear in front of a type. These can
also occur almost anywhere in types but they don't build a type of
objc '("const" "volatile")
java '("final")
t (append (c-lang-const c-no-type-kwds)
+ (c-lang-const c-type-modifier-with-parens-kwds)
(c-lang-const c-type-modifier-prefix-kwds)))
(c-lang-defconst c-opt-type-modifier-prefix-key
;; or a complete type).
t (c--delete-duplicates (append (c-lang-const c-primitive-type-kwds)
(c-lang-const c-type-prefix-kwds)
- (c-lang-const c-type-modifier-kwds))
+ (c-lang-const c-type-modifier-kwds)
+ (c-lang-const c-type-with-paren-kwds))
:test 'string-equal))
(c-lang-defconst c-type-decl-suffix-ws-ids-kwds
"Set to t when we recognize a colon and then a type after an enum,
e.g., enum foo : int { A, B, C };"
t nil
- c++ t)
+ (c c++) t)
(c-lang-defvar c-recognize-post-brace-list-type-p
(c-lang-const c-recognize-post-brace-list-type-p))
t (c-make-keywords-re t (c-lang-const c-no-type-kwds)))
(c-lang-defvar c-no-type-key (c-lang-const c-no-type-key))
+(c-lang-defconst c-no-type-with-equals-kwds
+ "Keywords after which no type is needed when there's an = sign."
+ t nil
+ c '("auto"))
+
+(c-lang-defconst c-no-type-with-equals-key
+ ;; Regexp mathing an entry from `c-no-type-with-equals-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-no-type-with-equals-kwds)))
+(c-lang-defvar c-no-type-with-equals-key
+ (c-lang-const c-no-type-with-equals-key))
+
(c-lang-defconst c-typeless-decl-kwds
"Keywords introducing declarations where the (first) identifier
\(declarator) follows directly after the keyword, without any type.
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled."
t nil
- (c c++) '("extern" "inline" "register" "static")
- c (append '("auto") (c-lang-const c-modifier-kwds))
- c++ (append '("consteval" "constexpr" "constinit" "explicit"
- "friend" "mutable" "template" "thread_local" "virtual")
+ (c c++) '("constexpr" "extern" "inline" "register"
+ "static" "thread_local")
+ c (append '("auto" "_Thread_local")
+ (c-lang-const c-modifier-kwds))
+ c++ (append '("consteval" "constinit" "explicit"
+ "friend" "mutable" "template" "virtual")
;; "using" is now handled specially (2020-09-14).
(c-lang-const c-modifier-kwds))
objc '("auto" "bycopy" "byref" "extern" "in" "inout" "oneway" "out" "static")
(c c++) '(;; GCC extension.
"__attribute__"
;; MSVC extension.
- "__declspec")
+ "__declspec"
+ "static_assert")
+ c (append (c-lang-const c-paren-nontype-kwds) '("_Static_assert"))
c++ (append (c-lang-const c-paren-nontype-kwds) '("noexcept" "alignas")))
(c-lang-defconst c-paren-nontype-key
(c-lang-defconst c-constant-kwds
"Keywords for constants."
t nil
- c '("NULL" ;; Not a keyword, but practically works as one.
- "false" "true") ; Defined in C99.
- c++ (append
- '("nullptr")
- (c-lang-const c-constant-kwds c))
+ (c c++) '("NULL" ;; Not a keyword, but practically works as one.
+ "false" "true" ; Defined in C99.
+ "nullptr")
objc '("nil" "Nil" "YES" "NO" "IBAction" "IBOutlet"
"NS_DURING" "NS_HANDLER" "NS_ENDHANDLER")
idl '("TRUE" "FALSE")
t (c-make-keywords-re t
(c--set-difference (c-lang-const c-keywords)
(append (c-lang-const c-primitive-type-kwds)
- (c-lang-const c-constant-kwds))
+ (c-lang-const c-constant-kwds)
+ (c-lang-const c-type-with-paren-kwds))
:test 'string-equal)))
(c-lang-defvar c-regular-keywords-regexp
(c-lang-const c-regular-keywords-regexp))
(c-lang-defvar c-pre-brace-non-bracelist-key
(c-lang-const c-pre-brace-non-bracelist-key))
+(c-lang-defconst c-recognize-nameless-type-decls
+ "Non-nil means a type may be used in an arglist without an identifier."
+ t nil
+ c t)
+(c-lang-defvar c-recognize-nameless-type-decls
+ (c-lang-const c-recognize-nameless-type-decls))
+
(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