;; `*-font-lock-extra-types');
;; o - 'prefix if it's a known prefix of a type;
;; 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; or
+ ;; o - 'maybe if it's an identfier that might be a type;
+ ;; o - 'decltype if it's a decltype(variable) declaration; - or
;; o - nil if it can't be a type (the point isn't moved then).
;;
;; The point is assumed to be at the beginning of a token.
(setq res 'prefix)))
(cond
+ ((looking-at c-typeof-key) ; e.g. C++'s "decltype".
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws)
+ (setq res (and (eq (char-after) ?\()
+ (c-safe (c-forward-sexp))
+ 'decltype))
+ (if res
+ (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))
;; 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
+ (when c-opt-type-suffix-key ; e.g. "..."
(while (looking-at c-opt-type-suffix-key)
(goto-char (match-end 1))
(c-forward-syntactic-ws)))
;; Foo::Foo (int b) : Base (b) {}
;; car ^ ^ point
;;
+ ;; auto foo = 5;
+ ;; car ^ ^ point
+ ;; auto cplusplus_11 (int a, char *b) -> decltype (bar):
+ ;; car ^ ^ point
+ ;;
+ ;;
+ ;;
;; The cdr of the return value is non-nil when a
;; `c-typedef-decl-kwds' specifier is found in the declaration.
;; Specifically it is a dotted pair (A . B) where B is t when a
;; If `backup-at-type' is nil then the other variables have
;; undefined values.
backup-at-type backup-type-start backup-id-start
+ ;; This stores `kwd-sym' of the symbol before the current one.
+ ;; This is needed to distinguish the C++11 version of "auto" from
+ ;; the pre C++11 meaning.
+ backup-kwd-sym
;; Set if we've found a specifier (apart from "typedef") that makes
;; the defined identifier(s) types.
at-type-decl
;; Set if we've found a specifier that can start a declaration
;; where there's no type.
maybe-typeless
+ ;; Save the value of kwd-sym between loops of the "Check for a
+ ;; type" loop. Needed to distinguish a C++11 "auto" from a pre
+ ;; C++11 one.
+ prev-kwd-sym
;; If a specifier is found that also can be a type prefix,
;; these flags are set instead of those above. If we need to
;; back up an identifier, they are copied to the real flag
backup-if-not-cast
;; For casts, the return position.
cast-end
+ ;; Have we got a new-style C++11 "auto"?
+ new-style-auto
;; Save `c-record-type-identifiers' and
;; `c-record-ref-identifiers' since ranges are recorded
;; speculatively and should be thrown away if it turns out
(let* ((start (point)) kwd-sym kwd-clause-end found-type)
;; Look for a specifier keyword clause.
- (when (or (looking-at c-prefix-spec-kwds-re)
+ (when (or (looking-at c-prefix-spec-kwds-re) ;FIXME!!! includes auto
(and (c-major-mode-is 'java-mode)
(looking-at "@[A-Za-z0-9]+")))
- (if (looking-at c-typedef-key)
- (setq at-typedef t))
+ (save-match-data
+ (if (looking-at c-typedef-key)
+ (setq at-typedef t)))
(setq kwd-sym (c-keyword-sym (match-string 1)))
(save-excursion
(c-forward-keyword-clause 1)
(when (setq found-type (c-forward-type t)) ; brace-block-too
;; Found a known or possible type or a prefix of a known type.
+ (when (and (c-major-mode-is 'c++-mode) ; C++11 style "auto"?
+ (eq prev-kwd-sym (c-keyword-sym "auto"))
+ (looking-at "[=(]")) ; FIXME!!! proper regexp.
+ (setq new-style-auto t)
+ (setq found-type nil)
+ (goto-char start)) ; position of foo in "auto foo"
(when at-type
;; Got two identifiers with nothing but whitespace
(setq backup-at-type at-type
backup-type-start type-start
backup-id-start id-start
+ backup-kwd-sym kwd-sym
at-type found-type
type-start start
id-start (point)
;; specifier keyword and we know we're in a
;; declaration.
(setq at-decl-or-cast t)
+ (setq prev-kwd-sym kwd-sym)
(goto-char kwd-clause-end))))
(c-forward-syntactic-ws))
- (when (and (or maybe-typeless backup-maybe-typeless)
- (not got-identifier)
- (not got-prefix)
- at-type)
+ (when (or (and new-style-auto
+ (looking-at c-auto-ops-re))
+ (and (or maybe-typeless backup-maybe-typeless)
+ (not got-identifier)
+ (not got-prefix)
+ at-type))
;; Have found no identifier but `c-typeless-decl-kwds' has
;; matched so we know we're inside a declaration. The
;; preceding type must be the identifier instead.
(c-fdoc-shift-type-backward))
+ ;; Prepare the "-> type;" for fontification later on.
+ (when (and new-style-auto
+ (looking-at c-haskell-op-re))
+ (save-excursion
+ (goto-char (match-end 0))
+ (c-forward-syntactic-ws)
+ (setq type-start (point))
+ (setq at-type (c-forward-type))))
+
(setq
at-decl-or-cast
(catch 'at-decl-or-cast
;; is a declaration. Now we're being more defensive and prefer to
;; highlight things like "foo (bar);" as a declaration only if we're
;; inside an arglist that contains declarations.
+ ;; CASE 19
(eq context 'decl))))
;; The point is now after the type decl expression.
;; interactive refontification.
(c-put-c-type-property (point) 'c-decl-arg-start))
+ ;; Record the type's coordinates in `c-record-type-identifiers' for
+ ;; later fontification.
(when (and c-record-type-identifiers at-type ;; (not (eq at-type t))
;; There seems no reason to exclude a token from
;; fontification just because it's "a known type that can't
(cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<)))
(setq context nil
c-restricted-<>-arglists nil))
- ;; A control flow expression
+ ;; A control flow expression or a decltype
((and (eq (char-before match-pos) ?\()
(save-excursion
(goto-char match-pos)
(backward-char)
(c-backward-token-2)
(or (looking-at c-block-stmt-2-key)
- (looking-at c-block-stmt-1-2-key))))
+ (looking-at c-block-stmt-1-2-key)
+ (looking-at c-typeof-key))))
(setq context nil
c-restricted-<>-arglists t))
;; Near BOB.
(goto-char (match-end 0))
(c-forward-syntactic-ws))
;; At a real declaration?
- (if (memq (c-forward-type t) '(t known found))
+ (if (memq (c-forward-type t) '(t known found decltype))
(progn
(c-font-lock-declarators limit t is-typedef)
nil)
;; Got two parenthesized expressions, so we have to look
;; closer at them to decide which is the type. No need to
;; handle `c-record-ref-identifiers' since all references
- ;; has already been handled by other fontification rules.
+ ;; have already been handled by other fontification rules.
(let (expr1-res expr2-res)
(goto-char expr1-pos)
;; unusual than an initializer.
(cond ((memq expr1-res '(t known prefix)))
((memq expr2-res '(t known prefix)))
+ ;; Presumably 'decltype's will be fontified elsewhere.
+ ((eq expr1-res 'decltype))
+ ((eq expr2-res 'decltype))
((eq expr1-res 'found)
(let ((c-promote-possible-types t))
(goto-char expr1-pos)
often are described as postfix operators are considered binary here,
since CC Mode treats every identifier as an expression."
- ;; There's currently no code in CC Mode that exploit all the info
+ ;; There's currently no code in CC Mode that exploits all the info
;; in this variable; precedence, associativity etc are present as a
;; preparation for future work.
+ ;; FIXME!!! C++11's "auto" operators "=" and "->" need to go in here
+ ;; somewhere. 2012-03-24.
+
t `(;; Preprocessor.
,@(when (c-lang-const c-opt-cpp-prefix)
`((prefix "#"
(c-lang-defvar c-stmt-delim-chars-with-comma
(c-lang-const c-stmt-delim-chars-with-comma))
+(c-lang-defconst c-auto-ops
+ ;; Ops which signal C++11's new auto uses.
+ t nil
+ c++ '("=" "->"))
+(c-lang-defconst c-auto-ops-re
+ t (c-make-keywords-re nil (c-lang-const c-auto-ops)))
+(c-lang-defvar c-auto-ops-re (c-lang-const c-auto-ops-re))
+
+(c-lang-defconst c-haskell-op
+ ;; Op used in the new C++11 auto function definition, indicating type.
+ t nil
+ c++ '("->"))
+(c-lang-defconst c-haskell-op-re
+ t (c-make-keywords-re nil (c-lang-const c-haskell-op)))
+(c-lang-defvar c-haskell-op-re (c-lang-const c-haskell-op-re))
\f
;;; Syntactic whitespace.
t (c-make-keywords-re t (c-lang-const c-typedef-kwds)))
(c-lang-defvar c-typedef-key (c-lang-const c-typedef-key))
+(c-lang-defconst c-typeof-kwds
+ "Keywords followed by a parenthesized expression, which stands for
+the type of that expression."
+ t nil
+ c '("typeof") ; longstanding GNU C(++) extension.
+ c++ '("decltype" "typeof"))
+
+(c-lang-defconst c-typeof-key
+ ;; Adorned regexp matching `c-typeof-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-typeof-kwds)))
+(c-lang-defvar c-typeof-key (c-lang-const c-typeof-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 (append (c-lang-const c-class-decl-kwds)
(c-lang-const c-brace-list-decl-kwds))
+ c++ (append (c-lang-const c-typeless-decl-kwds) '("auto")) ; C++11.
;; Note: "manages" for CORBA CIDL clashes with its presence on
;; `c-type-list-kwds' for IDL.
idl (append (c-lang-const c-typeless-decl-kwds)
t (c-make-keywords-re t
(set-difference (c-lang-const c-keywords)
(append (c-lang-const c-type-start-kwds)
- (c-lang-const c-prefix-spec-kwds))
+ (c-lang-const c-prefix-spec-kwds)
+ (c-lang-const c-typeof-kwds))
:test 'string-equal)))
(c-lang-defvar c-not-decl-init-keywords
(c-lang-const c-not-decl-init-keywords))