Handle C++11's "auto" and "decltype" constructions.
cc-engine.el (c-forward-type): Enhance to recognise and return 'decltype. (c-forward-decl-or-cast-1): New let variables backup-kwd-sym, prev-kwd-sym, new-style-auto. Enhance to handle the new "auto" keyword. cc-fonts.el (c-font-lock-declarations): Handle the "decltype" keyword. (c-font-lock-c++-new): Handle "decltype" constructions. cc-langs.el (c-auto-ops, c-auto-ops-re): New c-lang-defconsts/defvars. (c-haskell-op, c-haskell-op-re): New c-lang-defconsts/defvars. (c-typeof-kwds, c-typeof-key): New c-lang-defconsts/defvars. (c-typeless-decl-kwds): Append "auto" onto the C++ value. (c-not-decl-init-keywords): Also exclude c-typeof-kwds from value.
This commit is contained in:
parent
66bb9533fc
commit
4031fb7bac
4 changed files with 118 additions and 15 deletions
|
@ -1,5 +1,21 @@
|
|||
2014-08-24 Alan Mackenzie <acm@muc.de>
|
||||
|
||||
Handle C++11's "auto" and "decltype" constructions.
|
||||
* progmodes/cc-engine.el (c-forward-type): Enhance to recognise
|
||||
and return 'decltype.
|
||||
(c-forward-decl-or-cast-1): New let variables backup-kwd-sym,
|
||||
prev-kwd-sym, new-style-auto. Enhance to handle the new "auto"
|
||||
keyword.
|
||||
* progmodes/cc-fonts.el (c-font-lock-declarations): Handle the
|
||||
"decltype" keyword.
|
||||
(c-font-lock-c++-new): Handle "decltype" constructions.
|
||||
* progmodes/cc-langs.el (c-auto-ops, c-auto-ops-re): New
|
||||
c-lang-defconsts/defvars.
|
||||
(c-haskell-op, c-haskell-op-re): New c-lang-defconsts/defvars.
|
||||
(c-typeof-kwds, c-typeof-key): New c-lang-defconsts/defvars.
|
||||
(c-typeless-decl-kwds): Append "auto" onto the C++ value.
|
||||
(c-not-decl-init-keywords): Also exclude c-typeof-kwds from value.
|
||||
|
||||
Make ">>" act as double template ender in C++ Mode.
|
||||
* progmodes/cc-langs.el (c->-op-cont-tokens): New lang-const split
|
||||
off from c->-op-cont-re.
|
||||
|
|
|
@ -6286,7 +6286,8 @@ comment at the start of cc-engine.el for more info."
|
|||
;; `*-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.
|
||||
|
@ -6316,6 +6317,16 @@ comment at the start of cc-engine.el for more info."
|
|||
(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))
|
||||
|
@ -6442,7 +6453,7 @@ comment at the start of cc-engine.el for more info."
|
|||
;; 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)))
|
||||
|
@ -6654,6 +6665,13 @@ comment at the start of cc-engine.el for more info."
|
|||
;; 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
|
||||
|
@ -6719,6 +6737,10 @@ comment at the start of cc-engine.el for more info."
|
|||
;; 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
|
||||
|
@ -6727,6 +6749,10 @@ comment at the start of cc-engine.el for more info."
|
|||
;; 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
|
||||
|
@ -6744,6 +6770,8 @@ comment at the start of cc-engine.el for more info."
|
|||
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
|
||||
|
@ -6762,11 +6790,12 @@ comment at the start of cc-engine.el for more info."
|
|||
(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)
|
||||
|
@ -6774,6 +6803,12 @@ comment at the start of cc-engine.el for more info."
|
|||
|
||||
(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
|
||||
|
@ -6792,6 +6827,7 @@ comment at the start of cc-engine.el for more info."
|
|||
(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)
|
||||
|
@ -6847,6 +6883,7 @@ comment at the start of cc-engine.el for more info."
|
|||
;; 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))))
|
||||
|
||||
|
@ -7038,15 +7075,26 @@ comment at the start of cc-engine.el for more info."
|
|||
|
||||
(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
|
||||
|
@ -7371,6 +7419,7 @@ comment at the start of cc-engine.el for more info."
|
|||
;; 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.
|
||||
|
@ -7460,6 +7509,8 @@ comment at the start of cc-engine.el for more info."
|
|||
;; 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
|
||||
|
|
|
@ -1306,14 +1306,15 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
(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.
|
||||
|
@ -1513,7 +1514,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
|||
(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)
|
||||
|
@ -2130,7 +2131,7 @@ need for `c-font-lock-extra-types'.")
|
|||
;; 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)
|
||||
|
@ -2165,6 +2166,9 @@ need for `c-font-lock-extra-types'.")
|
|||
;; 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)
|
||||
|
|
|
@ -940,10 +940,13 @@ Note that operators like \".\" and \"->\" which in language references
|
|||
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 "#"
|
||||
|
@ -1266,6 +1269,21 @@ operators."
|
|||
(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))
|
||||
|
||||
;;; Syntactic whitespace.
|
||||
|
||||
|
@ -1673,6 +1691,18 @@ of a variable declaration."
|
|||
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
|
||||
|
@ -1856,6 +1886,7 @@ will be handled."
|
|||
;; {...}").
|
||||
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)
|
||||
|
@ -2005,7 +2036,8 @@ one of `c-type-list-kwds', `c-ref-list-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))
|
||||
|
|
Loading…
Add table
Reference in a new issue