unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH, re-sent] partial c++0x support for cc-mode
@ 2010-03-26  4:18 Daniel Colascione
  0 siblings, 0 replies; only message in thread
From: Daniel Colascione @ 2010-03-26  4:18 UTC (permalink / raw)
  To: Emacs development discussions; +Cc: Alan Mackenzie

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This patch teaches cc-mode about C++0x variadic templates, rvalue
references, type attributes, and keywords.

=== modified file 'lisp/progmodes/cc-engine.el'
- --- lisp/progmodes/cc-engine.el	2010-03-22 17:21:22 +0000
+++ lisp/progmodes/cc-engine.el	2010-03-26 03:58:14 +0000
@@ -4669,6 +4669,7 @@
 	  (when (and cfd-match-pos (< cfd-match-pos syntactic-pos))
 	    (goto-char syntactic-pos)
 	    (c-forward-syntactic-ws)
+            (c-skip-c++-attributes)
 	    (and cfd-continue-pos
 		 (< cfd-continue-pos (point))
 		 (setq cfd-token-pos (point))))
@@ -5408,8 +5409,8 @@
       (forward-char)
       (unless (looking-at c-<-op-cont-regexp)
 	(while (and
+
 		(progn
- -
 		  (when c-record-type-identifiers
 		    (if all-types

@@ -5624,6 +5625,42 @@

       (/= (point) start))))

+(defun c-skip-variadic-dots ()
+  ;; Move forward over a C++ three-dot form if point is at one.
+  ;;
+  ;; Return true off we found and skipped a variadic template dots.
+  (when (and (c-lang-const c-dots-everywhere)
+             (looking-at "\\.\\.\\."))
+    (goto-char (match-end 0))
+    (c-forward-syntactic-ws)
+    t))
+
+(defun c-skip-c++-attributes ()
+  ;; Skip one N2761 C++1x attribute declaration if point is at one,
+  ;; returning true iff we actually found and skipped one.
+  (and (c-major-mode-is 'c++-mode)
+       (eq (char-after) ?\[)
+       (save-excursion
+         (forward-char)
+         (c-forward-syntactic-ws)
+         (eq (char-after) ?\[))
+       (or (ignore-errors
+             (c-forward-sexp)
+             (c-forward-syntactic-ws))
+           ;; DTRT on failure?
+           (end-of-line))))
+
+(defun c-skip-c++-crud ()
+  ;; Skip declarational C++ crud that doesn't matter for
+  ;; our parsing.
+  ;;
+  ;; XXX sometimes we shouldn't accept ... before a type intro, but
+  ;; that requires detecting whether we're in a header.
+  ;;
+  (while (or (c-skip-c++-attributes)
+             (c-skip-variadic-dots))))
+
+
 (defun c-forward-name ()
   ;; Move forward over a complete name if at the beginning of one,
   ;; stopping at the next following token.  If the point is not at
@@ -5652,6 +5689,9 @@
 	;; the caller only wants the top level type that it finds to
 	;; be promoted.
 	c-promote-possible-types)
+
+    (c-skip-c++-crud)
+
     (while
 	(and
 	 (looking-at c-identifier-key)
@@ -5698,7 +5738,7 @@
 			  ;; '*', '&' or a name followed by ":: *",
 			  ;; where each can be followed by a sequence
 			  ;; of `c-opt-type-modifier-key'.
- -			  (while (cond ((looking-at "[*&]")
+			  (while (cond ((looking-at "[*&]\\|&&")
 					(goto-char (match-end 0))
 					t)
 				       ((looking-at c-identifier-start)
@@ -5787,6 +5827,9 @@
 	      )))))

     (goto-char pos)
+
+    (c-skip-c++-crud)
+
     res))

 (defun c-forward-type ()
@@ -5812,6 +5855,8 @@

   (let ((start (point)) pos res name-res id-start id-end id-range)

+    (c-skip-c++-attributes)
+
     ;; Skip leading type modifiers.  If any are found we know it's a
     ;; prefix of a type.
     (when c-opt-type-modifier-key
@@ -5826,6 +5871,8 @@
       ;; e.g. "class".
       (goto-char (match-end 1))
       (c-forward-syntactic-ws)
+      (c-skip-c++-crud)
+
       (setq pos (point))
       (if (memq (setq name-res (c-forward-name)) '(t template))
 	  (progn
@@ -5841,6 +5888,23 @@
 	(goto-char start)
 	(setq res nil)))

+     ((and (c-major-mode-is 'c++-mode)
+           (looking-at "\\(typeof\\|decltype\\)\\_>"))
+      (goto-char (match-end 0))
+      (c-forward-syntactic-ws)
+      (c-skip-c++-crud)
+      (if (not (eq (char-after) ?\())
+          ;; Invalid syntax
+          (progn
+            (goto-char start)
+            (setq res nil))
+
+        ;; We found a type, but there's nothing to record
+        (c-forward-sexp)
+        (c-forward-syntactic-ws)
+        (c-skip-c++-crud)
+        (setq res t)))
+
      ((progn
 	(setq pos nil)
 	(if (looking-at c-identifier-start)
@@ -6000,6 +6064,8 @@

 	    (goto-char pos))))

+      (c-skip-c++-crud)
+
       (when (and c-record-found-types (memq res '(known found)) id-range)
 	(setq c-record-found-types
 	      (cons id-range c-record-found-types))))
@@ -6389,7 +6455,8 @@
 	    (setq got-prefix-before-parens (= paren-depth 0)))
 	  (setq got-prefix t)
 	  (goto-char (match-end 1)))
- -	(c-forward-syntactic-ws))
+	(c-forward-syntactic-ws)
+        (c-skip-c++-crud))

       (setq got-parens (> paren-depth 0))

@@ -7197,6 +7264,7 @@
   (c-with-syntax-table c++-template-syntax-table
     (c-backward-token-2 0 t lim)
     (while (and (or (looking-at c-symbol-start)
+                    (looking-at "\\.\\.\\.")
 		    (looking-at "[<,]\\|::"))
 		(zerop (c-backward-token-2 1 t lim))))))


=== modified file 'lisp/progmodes/cc-fonts.el'
- --- lisp/progmodes/cc-fonts.el	2010-01-14 18:37:23 +0000
+++ lisp/progmodes/cc-fonts.el	2010-03-26 03:56:52 +0000
@@ -854,7 +854,10 @@
 	      ;; code in `c-forward-decl-or-cast-1'.)
 	      (while (and (looking-at c-type-decl-prefix-key)
 			  (if (and (c-major-mode-is 'c++-mode)
- -				   (match-beginning 2))
+				   (match-beginning 2)
+                                   (not (looking-at
+                                         (c-lang-const
c-type-decl-prefix-key c))))
+
 			      ;; If the second submatch matches in C++ then
 			      ;; we're looking at an identifier that's a
 			      ;; prefix only if it specifies a member pointer.
@@ -876,7 +879,8 @@
 		      (setq paren-depth (1+ paren-depth))
 		      (forward-char))
 		  (goto-char (match-end 1)))
- -		(c-forward-syntactic-ws))
+		(c-forward-syntactic-ws)
+                (c-skip-c++-crud))

 	      ;; If we didn't pass the identifier above already, do it now.
 	      (unless got-identifier
@@ -893,8 +897,11 @@
 	    (<= (point) limit)

 	    (progn
+              (c-skip-c++-crud)
+	
 	      (when (looking-at c-decl-hangon-key)
 		(c-forward-keyword-clause 1))
+              (c-skip-c++-crud)
 	      (<= (point) limit))

 	    ;; Search syntactically to the end of the declarator (";",
@@ -1217,6 +1224,21 @@

       nil)))

+(defun c-font-lock-c++-attributes (limit)
+  ;; fontify new C++ attributes syntax. Need a function instead of a
+  ;; declaration because the things can have arbitrarily nested
+  ;; parenthesis
+  (while (and
+          (c-syntactic-re-search-forward "\\[\\s-*\\[" limit t nil t)
+          (ignore-errors
+            (goto-char (match-beginning 0))
+            (setq beg (point))
+            (c-forward-sexp)
+            (c-put-font-lock-face (match-beginning 0) (point)
+                                  'font-lock-keyword-face)
+            t)))
+  nil)
+
 (c-lang-defconst c-simple-decl-matchers
   "Simple font lock matchers for types and declarations.  These are used
 on level 2 only and so aren't combined with `c-complex-decl-matchers'."
@@ -1320,6 +1342,9 @@
 				       'c-type 'c-decl-end)))
 	      c-font-lock-objc-methods))

+      ,@(if (c-major-mode-is 'c++-mode)
+            '(c-font-lock-c++-attributes))
+
       ;; Fontify all declarations, casts and normal labels.
       c-font-lock-declarations


=== modified file 'lisp/progmodes/cc-langs.el'
- --- lisp/progmodes/cc-langs.el	2010-02-04 21:15:37 +0000
+++ lisp/progmodes/cc-langs.el	2010-03-26 03:58:14 +0000
@@ -880,7 +880,8 @@

       ;; Unary.
       (prefix "++" "--" "+" "-" "!" "~"
- -	      ,@(when (c-major-mode-is 'c++-mode) '("not" "compl"))
+	      ,@(when (c-major-mode-is 'c++-mode)
+                  '("not" "compl" "static_assert" "&&"))
 	      ,@(when (c-major-mode-is '(c-mode c++-mode))
 		  '("*" "&" "sizeof" "??-"))
 	      ,@(when (c-major-mode-is 'objc-mode)
@@ -1040,7 +1041,7 @@
 			 "::" "...")
 		       (c-lang-const c-other-op-syntax-tokens))
   (c c++) (append '("*") (c-lang-const c-other-op-syntax-tokens))
- -  c++  (append '("&" "<%" "%>" "<:" ":>" "%:" "%:%:")
+  c++  (append '("&" "&&"  "<%" "%>" "<:" ":>" "%:" "%:%:")
 	       (c-lang-const c-other-op-syntax-tokens))
   objc (append '("#" "##"		; Used by cpp.
 		 "+" "-") (c-lang-const c-other-op-syntax-tokens))
@@ -1523,7 +1524,7 @@
 	'("_Bool" "_Complex" "_Imaginary") ; Conditionally defined in C99.
 	(c-lang-const c-primitive-type-kwds))
   c++  (append
- -	'("bool" "wchar_t")
+	'("auto" "bool" "wchar_t")
 	(c-lang-const c-primitive-type-kwds))
   ;; Objective-C extends C, but probably not the new stuff in C99.
   objc (append
@@ -1582,7 +1583,7 @@
 not the type face."
   t    nil
   c    '("const" "restrict" "volatile")
- -  c++  '("const" "volatile" "throw")
+  c++  '("const" "volatile" "throw" "constexpr" )
   objc '("const" "volatile"))

 (c-lang-defconst c-opt-type-modifier-key
@@ -1758,9 +1759,10 @@
 `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
 will be handled."
   t    nil
- -  (c c++) '("auto" "extern" "inline" "register" "static")
- -  c++  (append '("explicit" "friend" "mutable" "template" "using"
"virtual")
- -	       (c-lang-const c-modifier-kwds))
+  c    '("extern" "inline" "register" "static" "auto")
+  c++  '("extern" "inline" "register" "static"
+         "explicit" "friend" "mutable" "template"
+         "using" "virtual")
   objc '("auto" "bycopy" "byref" "extern" "in" "inout" "oneway" "out"
"static")
   ;; FIXME: Some of those below ought to be on `c-other-decl-kwds' instead.
   idl  '("abstract" "attribute" "const" "consumes" "custom" "emits"
"import"
@@ -1831,7 +1833,9 @@
   (c c++) '(;; GCC extension.
 	    "__attribute__"
 	    ;; MSVC extension.
- -	    "__declspec"))
+            "__declspec"
+            ;; Standard C++ attributes handled elsewhere
+            ))

 (c-lang-defconst c-decl-hangon-key
   ;; Adorned regexp matching `c-decl-hangon-kwds'.
@@ -2001,8 +2005,11 @@
   "Keywords that may be followed by a parenthesis expression that doesn't
 contain type identifiers."
   t       nil
- -  (c c++) '(;; GCC extension.
+  (c c++) '(;; C++0x
+            "decltype"
+            ;; GCC extension.
 	    "__attribute__"
+            "typeof"
 	    ;; MSVC extension.
 	    "__declspec"))

@@ -2179,7 +2186,8 @@
   "Keywords for constants."
   t       nil
   (c c++) '("NULL" ;; Not a keyword, but practically works as one.
- -	    "false" "true")		; Defined in C99.
+            "false" "true")		; Defined in C99.
+  c++      (cons "nullptr" (c-lang-const c-constant-kwds c))
   objc    '("nil" "Nil" "YES" "NO" "NS_DURING" "NS_HANDLER"
"NS_ENDHANDLER")
   idl     '("TRUE" "FALSE")
   java    '("true" "false" "null") ; technically "literals", not keywords
@@ -2619,7 +2627,13 @@

   ;; Allow '"' for extern clauses (e.g. extern "C" {...}).
   (c c++ objc) (set-difference (c-lang-const
c-block-prefix-disallowed-chars)
- -			       '(?\" ?')))
+			       '(?\" ?'))
+
+  ;; Allow '.' for variadic templates and '[' and ']' for the new fun
+  ;; attribute syntax.
+  (c++) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
+			       '(?. ?\[ ?\])))
+

 (c-lang-defconst c-block-prefix-charset
   ;; `c-block-prefix-disallowed-chars' as an inverted charset suitable
@@ -2647,6 +2661,8 @@
 		   "\\)"
 		   "\\([^=]\\|$\\)")
   c++  (concat "\\("
+               "&&"
+               "\\|"
 	       "[*\(&]"
 	       "\\|"
 	       (concat "\\("	; 2
@@ -2985,6 +3001,12 @@
   objc t)
 (c-lang-defvar c-type-decl-end-used (c-lang-const c-type-decl-end-used))

+(c-lang-defconst c-dots-everywhere
+  ;; t if '...' should be allowed in most declarations and expressions.
+  ;; Used for C++ variadic templates.
+  t nil
+  c++ t)
+
 \f
 ;;; Wrap up the `c-lang-defvar' system.



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (Darwin)

iEYEARECAAYFAkusNYMACgkQ17c2LVA10Vs0wwCgrcE4G70PVd7+dQH27WZYELM8
iwIAoMgk9r++xmLc7RpdnZlPK/TcqL4W
=CTrl
-----END PGP SIGNATURE-----




^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-03-26  4:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-26  4:18 [PATCH, re-sent] partial c++0x support for cc-mode Daniel Colascione

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).