emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH, re-sent] partial c++0x support for cc-mode


From: Daniel Colascione
Subject: [PATCH, re-sent] partial c++0x support for cc-mode
Date: Fri, 26 Mar 2010 00:18:12 -0400
User-agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.8) Gecko/20100227 Thunderbird/3.0.3

-----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)
+
 
 ;;; 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-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]