Optionally, fontify them with font-lock-warning-face.
This fixes bug#64204.
* lisp/progmodes/cc-fonts.el (c-font-lock-ids-with-dollar):
New function.
(c-simple-decl-matchers, c-complex-decl-matchers): invoke
c-font-lock-ids-with-dollar for pertinent languages.
* lisp/progmodes/cc-langs.el (c-symbol-start): Add `$' to the
character list.
(c-dollar-in-ids): New lang const.
(c-symbol-key): For the Pike value, use the AWK value rather
than the C value as the basis, as the latter is no longer
suitable.
* lisp/progmodes/cc-vars.el (c-warn-ids-with-dollar): New
customizable option.
* doc/misc/cc-mode.texi ("Miscellaneous Font Locking"): Add a
section on the new optional fontification of identifiers with
'font-lock-warning-face'.
@section Miscellaneous Font Locking
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Some compilers, notably GCC, allow the character @samp{$} to be a
+constituent of identifiers in the languages C, C++, and Objective C.
+CC Mode defaults to accepting these @samp{$} characters and fontifying
+the identifiers in which they appear like any others.
+
+However, the compiler you're using, or your project coding standards
+may disallow such use. In such cases, you can set
+@code{c-warn-ids-with-dollar} to non-@code{nil}. This causes these
+invalid identifiers to be fontified distinctively.
+
+@defvar c-warn-ids-with-dollar
+@vindex warn-ids-with-dollar (c-)
+When this customization option is non-@code{nil}, identifiers
+containing the @samp{$} character are fontified with
+@code{font-lock-warning-face}.
+@end defvar
+
In some languages, particularly in C++, there are constructs which are
syntactically ambiguous---they could be either declarations or
expressions, and @ccmode{} cannot tell for sure which. Often such a
(c-font-lock-declarators limit t in-typedef
(not (c-bs-at-toplevel-p (point)))))))))))
+(defun c-font-lock-ids-with-dollar (limit)
+ ;; Maybe fontify identifiers with a dollar using `font-lock-warning-face'.
+ ;; This is done only for languages which tolerate a $ in ids, and only when
+ ;; the flag variable `c-warn-ids-with-dollar' is set to non-nil. This
+ ;; function only works after functions such as `c-font-lock-declarations'
+ ;; have already been run.
+ ;;
+ ;; This function will be called from font-lock for a region bounded by POINT
+ ;; and LIMIT, as though it were to identify a keyword for
+ ;; font-lock-keyword-face. It always returns NIL to inhibit this and
+ ;; prevent a repeat invocation. See elisp/lispref page "Search-based
+ ;; Fontification".
+ (when c-warn-ids-with-dollar
+ (let (id-start)
+ (while (and (< (point) limit)
+ (skip-chars-forward "^$" limit)
+ (< (point) limit)
+ (eq (char-after) ?$))
+ (if (and (memq (c-get-char-property (point) 'face)
+ '(font-lock-variable-name-face
+ font-lock-function-name-face
+ font-lock-type-face))
+ (setq id-start (c-on-identifier)))
+ (progn
+ (goto-char id-start)
+ (looking-at c-identifier-key)
+ (c-put-font-lock-face (match-beginning 0) (match-end 0)
+ 'font-lock-warning-face)
+ (goto-char (match-end 0)))
+ (forward-char)))
+ nil)))
+
(defun c-font-lock-ml-strings (limit)
;; Fontify multi-line strings.
;;
;; Fontify generic colon labels in languages that support them.
,@(when (c-lang-const c-recognize-colon-labels)
- '(c-font-lock-labels))))
+ '(c-font-lock-labels))
+
+ ;; Maybe fontify identifiers containing a dollar sign with
+ ;; `font-lock-warning-face'.
+ ,@(when (c-lang-const c-dollar-in-ids)
+ `(c-font-lock-ids-with-dollar))))
(c-lang-defconst c-complex-decl-matchers
"Complex font lock matchers for types and declarations. Used on level
;; (see Elisp page "Search-based Fontification").
'(("\\<new\\>"
(c-font-lock-c++-new))))
- ))
+
+ ;; Maybe fontify identifiers containing a dollar sign with
+ ;; `font-lock-warning-face'.
+ ,@(when (c-lang-const c-dollar-in-ids)
+ `(c-font-lock-ids-with-dollar))))
(defun c-font-lock-labels (limit)
;; Fontify all statement labels from the point to LIMIT. Assumes
keyword. It's unspecified how far it matches. Does not contain a \\|
operator at the top level."
t (concat "[" c-alpha "_]")
+ (c c++) (concat "[" c-alpha "_$]")
java (concat "[" c-alpha "_@]")
- objc (concat "[" c-alpha "_@]")
+ objc (concat "[" c-alpha "_@$]")
pike (concat "[" c-alpha "_`]"))
(c-lang-defvar c-symbol-start (c-lang-const c-symbol-start))
objc (concat c-alnum "_$@"))
(c-lang-defvar c-symbol-chars (c-lang-const c-symbol-chars))
+(c-lang-defconst c-dollar-in-ids
+ "Non-nil when a dollar (can be) a non-standard constituent of an identifier."
+ t (string-match (c-lang-const c-symbol-start) "$"))
+
(c-lang-defconst c-symbol-char-key
"Regexp matching a sequence of at least one identifier character."
t (concat "[" (c-lang-const c-symbol-chars) "]+"))
t (concat (c-lang-const c-symbol-start)
"[" (c-lang-const c-symbol-chars) "]\\{,1000\\}")
pike (concat
- ;; Use the value from C here since the operator backquote is
+ ;; Use the value from AWK here since the operator backquote is
;; covered by the other alternative.
- (c-lang-const c-symbol-key c)
+ (c-lang-const c-symbol-key awk)
"\\|"
(c-make-keywords-re nil
(c-lang-const c-overloadable-operators))))
:type 'boolean
:group 'c)
+(defcustom c-warn-ids-with-dollar nil
+ "Fontify identifiers with a dollar character in font-lock-warn-face.
+This has effect only for languages in which `c-dollar-in-ids' is
+non-nil, e.g. C, C++, Objective C. It covers languages where
+\"$\" is permitted in ids \"informally\", but only by some compilers."
+ :type 'boolean
+ :group 'c)
+
(defcustom-c-stylevar c-basic-offset 4
"Amount of basic offset used by + and - symbols in `c-offsets-alist'.
Also used as the indentation step when `c-syntactic-indentation' is