]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-langs.el
Update copyright notice.
[gnu-emacs] / lisp / progmodes / cc-langs.el
index 03667e1870a7e3550186d498baf9e7cba541eeae..c61dcdabf9a1dd66fb422f0833c09a7b3ad4dc05 100644 (file)
@@ -1,13 +1,15 @@
-;;; cc-langs.el --- specific language support for CC Mode
+;;; cc-langs.el --- language specific settings for CC Mode
 
-;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
+;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
 
-;; Authors:    1992-1997 Barry A. Warsaw
+;; Authors:    2000- Martin Stjernholm
+;;            1998-1999 Barry A. Warsaw and Martin Stjernholm
+;;             1992-1997 Barry A. Warsaw
 ;;             1987 Dave Detlefs and Stewart Clamen
 ;;             1985 Richard M. Stallman
-;; Maintainer: cc-mode-help@python.org
+;; Maintainer: bug-cc-mode@gnu.org
 ;; Created:    22-Apr-1997 (split from cc-mode.el)
-;; Version:    5.12
+;; Version:    See cc-mode.el
 ;; Keywords:   c languages oop
 
 ;; This file is part of GNU Emacs.
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-\f
-;; Regular expressions and other values which must be parameterized on
-;; a per-language basis.
-
-;; Keywords defining protection levels
-(defconst c-protection-key "\\<\\(public\\|protected\\|private\\)\\>")
+;;; Commentary:
 
-;; Regex describing a `symbol' in all languages We cannot use just
-;; `word' syntax class since `_' cannot be in word class.  Putting
-;; underscore in word class breaks forward word movement behavior that
-;; users are familiar with.
-(defconst c-symbol-key "\\(\\w\\|\\s_\\)+")
+;;; Code:
 
-\f
-;; keywords introducing class definitions.  language specific
-(defconst c-C-class-key "\\(struct\\|union\\)")
-(defconst c-C++-class-key "\\(class\\|struct\\|union\\)")
-
-(defconst c-ObjC-class-key
-  (concat
-   "@\\(interface\\|implementation\\)\\s +"
-   c-symbol-key                                ;name of the class
-   "\\(\\s *:\\s *" c-symbol-key "\\)?"        ;maybe followed by the superclass
-   "\\(\\s *<[^>]+>\\)?"               ;and maybe the adopted protocols list
-   ))
-
-(defconst c-Java-class-key
-  (concat
-   "\\(" c-protection-key "\\s +\\)?"
-   "\\(interface\\|class\\)\\s +"
-   c-symbol-key                                      ;name of the class
-   "\\(\\s *extends\\s *" c-symbol-key "\\)?" ;maybe followed by superclass 
-   ;;"\\(\\s *implements *[^{]+{\\)?"        ;maybe the adopted protocols list
-   ))
-
-(defvar c-class-key c-C-class-key)
-(make-variable-buffer-local 'c-class-key)
+(eval-when-compile
+  (let ((load-path
+        (if (and (boundp 'byte-compile-dest-file)
+                 (stringp byte-compile-dest-file))
+            (cons (file-name-directory byte-compile-dest-file) load-path)
+          load-path)))
+    (require 'cc-bytecomp)))
 
-\f
-;; regexp describing access protection clauses.  language specific
-(defvar c-access-key nil)
-(make-variable-buffer-local 'c-access-key)
-(defconst c-C++-access-key (concat c-protection-key "[ \t]*:"))
-(defconst c-ObjC-access-key (concat "@" c-protection-key))
-(defconst c-Java-access-key nil)
+(cc-require 'cc-defs)
+(cc-require 'cc-vars)
 
-\f
-;; keywords introducing conditional blocks
-(defconst c-C-conditional-key nil)
-(defconst c-C++-conditional-key nil)
-(defconst c-Java-conditional-key nil)
-
-(let ((all-kws "for\\|if\\|do\\|else\\|while\\|switch")
-      (exc-kws "\\|try\\|catch")
-      (thr-kws "\\|finally\\|synchronized")
-      (front   "\\b\\(")
-      (back    "\\)\\b[^_]"))
-  (setq c-C-conditional-key (concat front all-kws back)
-       c-C++-conditional-key (concat front all-kws exc-kws back)
-       c-Java-conditional-key (concat front all-kws exc-kws thr-kws back)))
-
-(defvar c-conditional-key c-C-conditional-key)
-(make-variable-buffer-local 'c-conditional-key)
+(require 'cl)
 
 \f
-;; keywords describing method definition introductions
-(defvar c-method-key nil)
-(make-variable-buffer-local 'c-method-key)
-
-(defconst c-ObjC-method-key
-  (concat
-   "^\\s *[+-]\\s *"
-   "\\(([^)]*)\\)?"                    ; return type
-   ;; \\s- in objc syntax table does not include \n
-   ;; since it is considered the end of //-comments.
-   "[ \t\n]*" c-symbol-key))
-
-(defconst c-Java-method-key
-  (concat
-   "^\\s *[+-]\\s *"
-   "\\(([^)]*)\\)?"                    ; return type
-   ;; \\s- in java syntax table does not include \n
-   ;; since it is considered the end of //-comments.
-   "[ \t\n]*" c-symbol-key))
+;; Some support functions that are used when the language specific
+;; constants are built.  Since the constants are built during compile
+;; time, these need to be defined then too.
+
+(eval-and-compile
+  ;; `require' in XEmacs doesn't have the third NOERROR argument.
+  (condition-case nil (require 'regexp-opt) (file-error nil))
+
+  (if (fboundp 'regexp-opt)
+      (fset 'c-regexp-opt (symbol-function 'regexp-opt))
+    ;; Emacs 19.34 doesn't have the regexp-opt package.
+    (defun c-regexp-opt (strings &optional paren)
+      (if paren
+         (concat "\\(" (mapconcat 'regexp-quote strings "\\|") "\\)")
+       (mapconcat 'regexp-quote strings "\\|"))))
+
+  (if (fboundp 'regexp-opt-depth)
+      (fset 'c-regexp-opt-depth (symbol-function 'regexp-opt-depth))
+    ;; Emacs 19.34 doesn't have the regexp-opt package.
+    (defun c-regexp-opt-depth (regexp)
+      ;; This is the definition of `regexp-opt-depth' in Emacs 20.
+      (save-match-data
+       ;; Hack to signal an error if REGEXP does not have balanced
+       ;; parentheses.
+       (string-match regexp "")
+       ;; Count the number of open parentheses in REGEXP.
+       (let ((count 0) start)
+         (while (string-match "\\\\(" regexp start)
+           (setq count (1+ count) start (match-end 0)))
+         count))))
+
+  (defun c-make-keywords-re (adorn &rest lists)
+    "Make a regexp that matches all the strings in all the lists.
+Duplicates in the lists are removed.  The regexp may contain zero or
+more submatch expressions.  If ADORN is non-nil there will be at least
+one submatch which matches the whole keyword, and the regexp will also
+not match a prefix of any identifier.  Adorned regexps cannot be
+appended."
+    (setq lists (delete-duplicates (apply 'append (nconc lists '(nil)))
+                                  :test 'string-equal))
+    (if lists
+       (let ((re (c-regexp-opt lists)))
+         ;; Add our own grouping parenthesis around re instead of
+         ;; passing adorn to regexp-opt, since it in XEmacs makes the
+         ;; top level grouping "shy".
+         (if adorn
+             (concat "\\(" re "\\)\\>\\([^_]\\|$\\)")
+           re))
+      "\\<\\>"                         ; Matches nothing.
+      ))
+  (put 'c-make-keywords-re 'lisp-indent-function 1)
+  )
 
 \f
-;; comment starter definitions for various languages.  language specific
-(defconst c-C-comment-start-regexp "/[*]")
-(defconst c-C++-comment-start-regexp "/[/*]")
-;; We need to match all 3 Java style comments
-;; 1) Traditional C block; 2) javadoc /** ...; 3) C++ style
-(defconst c-Java-comment-start-regexp "/\\(/\\|[*][*]?\\)")
-(defvar c-comment-start-regexp c-C-comment-start-regexp)
-(make-variable-buffer-local 'c-comment-start-regexp)
+;; Building of constants that are parameterized on a per-language
+;; basis.
+
+(eval-and-compile
+  (defvar c-macroexpand-mode nil
+    ;; Dynamically bound to the mode symbol during `c-lang-defconst'
+    ;; so that `c-lang-var' can do the right expansion.
+    )
+
+  (defmacro c-lang-defconst (var &rest args)
+    ;; Sets the mode specific values of the constant VAR.  The rest of
+    ;; the arguments are one or more repetitions of MODE VAL.  MODE is
+    ;; the mode name without the "-mode" suffix, or a list of such
+    ;; mode names, or `all' as a shortcut for a list of all modes.
+    ;; VAL is evaluated (during compilation) for each mode with
+    ;; `c-macroexpand-mode' temporarily bound, so `c-lang-var' without
+    ;; an explicit mode may be used within it.  The assignments in
+    ;; ARGS are processed in sequence, similar to `setq'.
+    (let* ((res (list 'progn))
+          (res-tail res))
+      (while args
+       (let ((mode (car args)))
+         (cond ((eq mode 'all)
+                (setq mode '(c c++ objc java idl pike)))
+               ((symbolp mode)
+                (setq mode (list mode))))
+         (while mode
+           (let* ((c-macroexpand-mode
+                   (intern (concat (symbol-name (car mode)) "-mode")))
+                  (val (eval (car (cdr args)))))
+             ;; Need to install the value also during compilation,
+             ;; since val might refer to earlier mode specific
+             ;; values.
+             (put var c-macroexpand-mode val)
+             (setcdr res-tail (list `(put ',var ',c-macroexpand-mode ',val)))
+             (setq res-tail (cdr res-tail)))
+           (setq mode (cdr mode))))
+       (setq args (cdr (cdr args))))
+      res))
+  (put 'c-lang-defconst 'lisp-indent-function 1)
+
+  (defmacro c-lang-var (var &optional mode)
+    ;; Get the mode specific value of the variable VAR in mode MODE.
+    ;; MODE is the mode name without the "-mode" suffix.  It may also
+    ;; be nil to use the current value of `c-macroexpand-mode' (which
+    ;; is useful inside `c-lang-defconst') or `c-buffer-is-cc-mode'
+    ;; (which is useful inside `c-lang-defvar').
+    `(get ',var ,(if (eq mode 'nil)
+                    (if c-macroexpand-mode
+                        ;; In the macro expansion of c-lang-defconst.
+                        `(quote ,c-macroexpand-mode)
+                      `c-buffer-is-cc-mode)
+                  `(quote ,(intern (concat (symbol-name mode) "-mode"))))))
+
+  ;; These are used to collect the init forms from the subsequent
+  ;; `c-lang-defvar'.  They become a big setq in the
+  ;; `c-init-lang-defvars' lambda below.
+  (defconst c-lang-defvar-init-form (list 'setq))
+  (defconst c-lang-defvar-init-form-tail c-lang-defvar-init-form)
+
+  (defmacro c-lang-defvar (var val)
+    ;; Declares the buffer local variable VAR to get the value VAL at
+    ;; mode initialization, at which point VAL is evaluated.
+    ;; `c-lang-var' is typically used in VAL to get the right value
+    ;; according to `c-buffer-is-cc-mode'.
+    (setcdr c-lang-defvar-init-form-tail (list var val))
+    (setq c-lang-defvar-init-form-tail
+         (cdr (cdr c-lang-defvar-init-form-tail)))
+    `(progn
+       (defvar ,var nil)
+       (make-variable-buffer-local ',var)))
+  (put 'c-lang-defvar 'lisp-indent-function 1)
+  )
 
+;; Regexp describing a `symbol' in all languages, not excluding
+;; keywords.  We cannot use just `word' syntax class since `_' cannot
+;; be in word class.  Putting underscore in word class breaks forward
+;; word movement behavior that users are familiar with.  Besides, it
+;; runs counter to Emacs convention.
+;;
+;; This definition isn't correct for the first character in the
+;; languages that accept the full range of Unicode word constituents
+;; in identifiers (e.g. Java and Pike).  For that we'd need to make a
+;; regexp that matches all characters in the word constituent class
+;; except 0-9, and the regexp engine currently can't do that.
+(c-lang-defconst c-symbol-key
+  (c c++ objc java idl) "[_a-zA-Z]\\(\\w\\|\\s_\\)*"
+  pike (concat "\\(" (c-lang-var c-symbol-key c) "\\|"
+              (c-make-keywords-re nil
+                '("`+" "`-" "`&" "`|" "`^" "`<<" "`>>" "`*" "`/" "`%" "`~"
+                  "`==" "`<" "`>" "`!" "`[]" "`[]=" "`->" "`->=" "`()" "``+"
+                  "``-" "``&" "``|" "``^" "``<<" "``>>" "``*" "``/" "``%"
+                  "`+="))
+              "\\)"))
+(c-lang-defvar c-symbol-key (c-lang-var c-symbol-key))
+
+;; Number of regexp grouping parens in c-symbol-key.
+(c-lang-defvar c-symbol-key-depth (c-regexp-opt-depth c-symbol-key))
+
+(defvar c-stmt-delim-chars "^;{}?:")
+;; The characters that should be considered to bound statements.  To
+;; optimize c-crosses-statement-barrier-p somewhat, it's assumed to
+;; begin with "^" to negate the set.  If ? : operators should be
+;; detected then the string must end with "?:".
+
+(defvar c-stmt-delim-chars-with-comma "^;,{}?:")
+;; Variant of c-stmt-delim-chars that additionally contains ','.
+
+;; HELPME: Many of the following keyword lists are more or less bogus
+;; for some languages (notably ObjC and IDL).  The effects of the
+;; erroneous values in the language handling are mostly negligible
+;; since the constants that actually matter in the syntax detection
+;; code are mostly correct in the situations they are used, but I'd
+;; still appreciate help to get them correct for other uses.
+
+;; Primitive type keywords.
+(c-lang-defconst c-primitive-type-kwds
+  (c c++ objc idl) '("char" "double" "float" "int" "long" "short"
+                    "signed" "unsigned" "void")
+  java '("boolean" "byte" "char" "double" "float" "int" "long" "short" "void")
+  pike '("constant" "float" "int" "mapping" "multiset" "object" "program"
+        "string" "void"))
+
+;; Declaration specifier keywords.
+(c-lang-defconst c-specifier-kwds
+  c '("auto" "const" "extern" "register" "static" "volatile")
+  (c++ objc idl) (append '("friend" "inline" "virtual")
+                        (c-lang-var c-specifier-kwds c))
+  ;; Note: `const' is not used in Java, but it's still a reserved keyword.
+  java '("abstract" "const" "final" "native" "private" "protected"
+        "public" "static" "synchronized" "transient" "volatile")
+  pike '("final" "inline" "local" "nomask" "optional" "private"
+        "protected" "static" "variant"))
+
+;; Class/struct declaration keywords.
+(c-lang-defconst c-class-kwds
+  c '("struct" "union")
+  c++ '("class" "struct" "union")
+  objc '("interface" "implementation")
+  java '("class" "interface")
+  idl '("interface" "valuetype" "class" "struct" "union")
+  pike '("class"))
+
+;; Regexp matching the start of a class.
+(c-lang-defconst c-class-key
+  all (c-make-keywords-re t (c-lang-var c-class-kwds)))
+(c-lang-defconst c-class-key           ; ObjC needs some tuning of the regexp.
+   objc (concat "@" (c-lang-var c-class-key)))
+(c-lang-defvar c-class-key (c-lang-var c-class-key))
+
+;; Keywords introducing blocks besides classes that contain another
+;; declaration level.
+(c-lang-defconst c-other-decl-block-kwds
+  c '("extern")
+  c++ '("namespace" "extern")
+  idl '("module"))
+
+;; Regexp matching the start of blocks besides classes that contain
+;; another declaration level.
+(c-lang-defconst c-other-decl-block-key
+  all (c-make-keywords-re t (c-lang-var c-other-decl-block-kwds)))
+(c-lang-defvar c-other-decl-block-key (c-lang-var c-other-decl-block-key))
+
+;; Keywords introducing declarations that can contain a block which
+;; might be followed by variable declarations, e.g. like "foo" in
+;; "class Foo { ... } foo;".  So if there is a block in a declaration
+;; like that, it ends with the following ';' and not right away.
+(c-lang-defconst c-block-decls-with-vars
+  c '("struct" "union" "enum" "typedef")
+  c++ '("class" "struct" "union" "enum" "typedef"))
+
+;; Regexp matching the `c-block-decls-with-vars' keywords, or nil in
+;; languages without such constructs.
+(c-lang-defconst c-opt-block-decls-with-vars-key
+  all (and (c-lang-var c-block-decls-with-vars)
+          (c-make-keywords-re t (c-lang-var c-block-decls-with-vars))))
+(c-lang-defvar c-opt-block-decls-with-vars-key
+  (c-lang-var c-opt-block-decls-with-vars-key))
+
+;; Keywords introducing declarations that has not been accounted for
+;; by any of the above.
+(c-lang-defconst c-other-decl-kwds
+  ;; FIXME: Shouldn't "template" be moved to c-specifier-kwds for C++?
+  c++ '("template")
+  java '("import" "package")
+  pike '("import" "inherit"))
+
+;; Keywords introducing extra declaration specifiers in the region
+;; between the header and the body (i.e. the "K&R-region") in
+;; declarations.
+(c-lang-defconst c-decl-spec-kwds java '("extends" "implements" "throws"))
+
+;; Protection label keywords in classes.
+(c-lang-defconst c-protection-kwds
+  (c++ objc) '("private" "protected" "public"))
+
+;; Statement keywords followed directly by a substatement.
+(c-lang-defconst c-block-stmt-1-kwds
+  (c pike) '("do" "else")
+  (c++ objc) '("do" "else" "asm" "try")
+  java '("do" "else" "finally" "try"))
+
+;; Regexp matching the start of any statement followed directly by a
+;; substatement (doesn't match a bare block, however).
+(c-lang-defconst c-block-stmt-1-key
+  all (c-make-keywords-re t (c-lang-var c-block-stmt-1-kwds)))
+(c-lang-defvar c-block-stmt-1-key (c-lang-var c-block-stmt-1-key))
+
+;; Statement keywords followed by a paren sexp and then by a substatement.
+(c-lang-defconst c-block-stmt-2-kwds
+  c '("for" "if" "switch" "while")
+  (c++ objc) '("for" "if" "switch" "while" "catch")
+  java '("for" "if" "switch" "while" "catch" "synchronized")
+  pike '("for" "if" "switch" "while" "foreach"))
+
+;; Regexp matching the start of any statement followed by a paren sexp
+;; and then by a substatement.
+(c-lang-defconst c-block-stmt-2-key
+  all (c-make-keywords-re t (c-lang-var c-block-stmt-2-kwds)))
+(c-lang-defvar c-block-stmt-2-key (c-lang-var c-block-stmt-2-key))
+
+;; Regexp matching the start of any statement that has a substatement
+;; (except a bare block).  Nil in languages that doesn't have such
+;; constructs.
+(c-lang-defconst c-opt-block-stmt-key
+  all (if (or (c-lang-var c-block-stmt-1-kwds)
+             (c-lang-var c-block-stmt-2-kwds))
+         (c-make-keywords-re t
+           (c-lang-var c-block-stmt-1-kwds)
+           (c-lang-var c-block-stmt-2-kwds))))
+(c-lang-defvar c-opt-block-stmt-key (c-lang-var c-opt-block-stmt-key))
+
+;; Statement keywords followed by an expression or nothing.
+(c-lang-defconst c-simple-stmt-kwds
+  (c c++ objc) '("break" "continue" "goto" "return")
+  ;; Note: `goto' is not valid in Java, but the keyword is still reserved.
+  java '("break" "continue" "goto" "return" "throw")
+  pike '("break" "continue" "return"))
+
+;; Statement keywords followed by an assembler expression.
+(c-lang-defconst c-asm-stmt-kwds
+  (c c++) '("asm" "__asm__"))
+
+;; Regexp matching the start of an assembler statement.  Nil in
+;; languages that doesn't support that.
+(c-lang-defconst c-opt-asm-stmt-key
+  all (if (c-lang-var c-asm-stmt-kwds)
+         (c-make-keywords-re t (c-lang-var c-asm-stmt-kwds))))
+(c-lang-defvar c-opt-asm-stmt-key (c-lang-var c-opt-asm-stmt-key))
+
+;; Keywords introducing labels in blocks.
+(c-lang-defconst c-label-kwds (c c++ objc java pike) '("case" "default"))
+
+;; Regexp matching any keyword that introduces a label.
+(c-lang-defconst c-label-kwds-regexp
+  all (c-make-keywords-re t (c-lang-var c-label-kwds)))
+(c-lang-defvar c-label-kwds-regexp (c-lang-var c-label-kwds-regexp))
+
+;; Keywords that can occur anywhere in expressions.
+(c-lang-defconst c-expr-kwds
+  (c objc) '("sizeof")
+  c++ '("sizeof" "delete" "new" "operator" "this" "throw")
+  java '("instanceof" "new" "super" "this")
+  pike '("sizeof" "catch" "class" "gauge" "lambda" "predef"))
+
+;; Keywords that start lambda constructs, i.e. function definitions in
+;; expressions.
+(c-lang-defconst c-lambda-kwds pike '("lambda"))
+
+;; Regexp matching the start of lambda constructs, or nil in languages
+;; that doesn't have such things.
+(c-lang-defconst c-opt-lambda-key
+  pike (c-make-keywords-re t (c-lang-var c-lambda-kwds)))
+(c-lang-defvar c-opt-lambda-key (c-lang-var c-opt-lambda-key))
+
+;; Keywords that start constructs followed by statement blocks which
+;; can be used in expressions (the gcc extension for this in C and C++
+;; is handled separately).
+(c-lang-defconst c-inexpr-block-kwds pike '("catch" "gauge"))
+
+;; Regexp matching the start of in-expression statements, or nil in
+;; languages that doesn't have such things.
+(c-lang-defconst c-opt-inexpr-block-key
+  pike (c-make-keywords-re t (c-lang-var c-inexpr-block-kwds)))
+(c-lang-defvar c-opt-inexpr-block-key (c-lang-var c-opt-inexpr-block-key))
+
+;; Keywords that start classes in expressions.
+(c-lang-defconst c-inexpr-class-kwds
+  java '("new")
+  pike '("class"))
+
+;; Regexp matching the start of a class in an expression, or nil in
+;; languages that doesn't have such things.
+(c-lang-defconst c-opt-inexpr-class-key
+  (java pike) (c-make-keywords-re t (c-lang-var c-inexpr-class-kwds)))
+(c-lang-defvar c-opt-inexpr-class-key (c-lang-var c-opt-inexpr-class-key))
+
+;; Regexp matching the start of any class, both at top level and in
+;; expressions.
+(c-lang-defconst c-any-class-key
+  all (c-make-keywords-re t
+       (c-lang-var c-class-kwds)
+       (c-lang-var c-inexpr-class-kwds)))
+(c-lang-defconst c-any-class-key       ; ObjC needs some tuning of the regexp.
+  objc (concat "@" (c-lang-var c-any-class-key)))
+(c-lang-defvar c-any-class-key (c-lang-var c-any-class-key))
+
+;; Regexp matching the start of any declaration-level block that
+;; contain another declaration level, i.e. that isn't a function
+;; block.
+(c-lang-defconst c-decl-block-key
+  all (c-make-keywords-re t
+       (c-lang-var c-class-kwds)
+       (c-lang-var c-other-decl-block-kwds)
+       (c-lang-var c-inexpr-class-kwds)))
+(c-lang-defconst c-decl-block-key      ; ObjC needs some tuning of the regexp.
+  objc (concat "@" (c-lang-var c-decl-block-key)))
+(c-lang-defvar c-decl-block-key (c-lang-var c-decl-block-key))
+
+;; Keywords that can introduce bitfields.
+(c-lang-defconst c-bitfield-kwds
+  (c c++) '("char" "int" "long" "signed" "unsigned"))
+
+;; Regexp matching the start of a bitfield (not uniquely), or nil in
+;; languages without bitfield support.
+(c-lang-defconst c-opt-bitfield-key
+  (c c++) (c-make-keywords-re t (c-lang-var c-bitfield-kwds)))
+(c-lang-defvar c-opt-bitfield-key (c-lang-var c-opt-bitfield-key))
+
+;; All keywords as a list.
+(c-lang-defconst c-keywords
+  all (delete-duplicates (append (c-lang-var c-primitive-type-kwds)
+                                (c-lang-var c-specifier-kwds)
+                                (c-lang-var c-class-kwds)
+                                (c-lang-var c-other-decl-block-kwds)
+                                (c-lang-var c-block-decls-with-vars)
+                                (c-lang-var c-other-decl-kwds)
+                                (c-lang-var c-decl-spec-kwds)
+                                (c-lang-var c-protection-kwds)
+                                (c-lang-var c-block-stmt-1-kwds)
+                                (c-lang-var c-block-stmt-2-kwds)
+                                (c-lang-var c-simple-stmt-kwds)
+                                (c-lang-var c-asm-stmt-kwds)
+                                (c-lang-var c-label-kwds)
+                                (c-lang-var c-expr-kwds)
+                                (c-lang-var c-lambda-kwds)
+                                (c-lang-var c-inexpr-block-kwds)
+                                (c-lang-var c-inexpr-class-kwds)
+                                (c-lang-var c-bitfield-kwds)
+                                nil)
+                        :test 'string-equal))
+(c-lang-defvar c-keywords (c-lang-var c-keywords))
+
+;; All keywords as an adorned regexp.
+(c-lang-defconst c-keywords-regexp
+  all (c-make-keywords-re t (c-lang-var c-keywords)))
+(c-lang-defvar c-keywords-regexp (c-lang-var c-keywords-regexp))
+
+;; Regexp matching an access protection label in a class, or nil in
+;; languages that doesn't have such things.
+(c-lang-defconst c-opt-access-key
+  c++ (concat "\\("
+             (c-make-keywords-re nil (c-lang-var c-protection-kwds))
+             "\\)[ \t\n\r]*:"))
+(c-lang-defconst c-opt-access-key
+  objc (concat "@" (c-make-keywords-re t (c-lang-var c-protection-kwds))))
+(c-lang-defvar c-opt-access-key (c-lang-var c-opt-access-key))
+
+;; Regexp matching a normal label, i.e. not a label that's recognized
+;; with a keyword, like switch labels.  It's only used at the
+;; beginning of a statement.
+(c-lang-defconst c-label-key
+  all (concat (c-lang-var c-symbol-key) "[ \t\n\r]*:\\([^:]\\|$\\)"))
+(c-lang-defvar c-label-key (c-lang-var c-label-key))
+
+;; Regexp matching the beginning of a declaration specifier in the
+;; region between the header and the body of a declaration.
+;;
+;; FIXME: This is currently not used in a uniformly; c++-mode and
+;; java-mode each have their own ways of using it.
+(c-lang-defconst c-opt-decl-spec-key
+  c++ (concat ":?[ \t\n\r]*\\(virtual[ \t\n\r]+\\)?\\("
+             (c-make-keywords-re nil (c-lang-var c-protection-kwds))
+             "\\)[ \t\n\r]+"
+             (c-lang-var c-symbol-key))
+  java (c-make-keywords-re t (c-lang-var c-decl-spec-kwds)))
+(c-lang-defvar c-opt-decl-spec-key (c-lang-var c-opt-decl-spec-key))
+
+;; Regexp describing friend declarations classes, or nil in languages
+;; that doesn't have such things.
+(c-lang-defconst c-opt-friend-key
+  ;; FIXME: Ought to use c-specifier-kwds or similar, and the template
+  ;; skipping isn't done properly.
+  c++ "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+")
+(c-lang-defvar c-opt-friend-key (c-lang-var c-opt-friend-key))
+
+;; Special regexp to match the start of methods.
+(c-lang-defconst c-opt-method-key
+  objc (concat
+       "^\\s *[+-]\\s *"
+       "\\(([^)]*)\\)?"                ; return type
+       ;; \\s- in objc syntax table does not include \n
+       ;; since it is considered the end of //-comments.
+       "[ \t\n]*" (c-lang-var c-symbol-key)))
+(c-lang-defvar c-opt-method-key (c-lang-var c-opt-method-key))
+
+;; Name of functions in cpp expressions that take an identifier as the
+;; argument.
+(c-lang-defconst c-cpp-defined-fns
+  (c c++) '("defined")
+  pike '("defined" "efun" "constant"))
+
+;; List of open- and close-chars that makes up a pike-style brace
+;; list, i.e. for a `([ ])' list there should be a cons (?\[ . ?\]) in
+;; this list.
+(c-lang-defconst c-special-brace-lists pike '((?{ . ?})
+                                             (?\[ . ?\])
+                                             (?< . ?>)))
+(c-lang-defvar c-special-brace-lists (c-lang-var c-special-brace-lists))
 
-\f
-;; Regexp describing a switch's case or default label for all languages
-(defconst c-switch-label-key "\\(\\(case[( \t]+\\S .*\\)\\|default[ \t]*\\):")
-;; Regexp describing any label.
-(defconst c-label-key (concat c-symbol-key ":\\([^:]\\|$\\)"))
-
-;; Regexp describing class inheritance declarations.  TBD: this should
-;; be language specific, and only makes sense for C++
-(defconst c-inher-key
-  (concat "\\(\\<static\\>\\s +\\)?"
-         c-C++-class-key "[ \t]+" c-symbol-key
-         "\\([ \t]*:[ \t]*\\)\\s *[^;]"))
-
-;; Regexp describing C++ base classes in a derived class definition.
-;; TBD: this should be language specific, and only makes sense for C++
-(defvar c-baseclass-key
-  (concat
-   ":?[ \t]*\\(virtual[ \t]+\\)?\\("
-   c-protection-key "[ \t]+\\)" c-symbol-key))
-(make-variable-buffer-local 'c-baseclass-key)
-
-;; Regexp describing friend declarations in C++ classes.
-(defconst c-C++-friend-key
-  "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+")
-
-;; Regexp describing Java inheritance and throws clauses.
-(defconst c-Java-special-key "\\(implements\\|extends\\|throws\\)[^_]")
-
-;; Regexp describing the beginning of a Java top-level definition.
+;; Non-nil means K&R style argument declarations are valid.
+(c-lang-defconst c-recognize-knr-p c t)
+(c-lang-defvar c-recognize-knr-p (c-lang-var c-recognize-knr-p))
+
+;; Regexp to match the start of any type of comment.
+;;
+;; FIXME: Ought to use c-comment-prefix-regexp with some modifications
+;; instead of this.
+(c-lang-defconst c-comment-start-regexp
+  (c c++ objc idl pike) "/[/*]"
+  ;; We need to match all 3 Java style comments
+  ;; 1) Traditional C block; 2) javadoc /** ...; 3) C++ style
+  java "/\\(/\\|[*][*]?\\)")
+(c-lang-defvar c-comment-start-regexp (c-lang-var c-comment-start-regexp))
+
+;; Strings that starts and ends comments inserted with M-; etc.
+;; comment-start and comment-end are initialized from these.
+(c-lang-defconst comment-start
+  c "/* "
+  (c++ objc java idl pike) "// ")
+(c-lang-defvar comment-start (c-lang-var comment-start))
+(c-lang-defconst comment-end
+  c "*/"
+  (c++ objc java idl pike) "")
+(c-lang-defvar comment-end (c-lang-var comment-end))
+
+;; Regexp that matches when there is no syntactically significant text
+;; before eol.  Macros are regarded as syntactically significant text
+;; here.
+(c-lang-defvar c-syntactic-eol
+  (concat (concat
+          ;; Match horizontal whitespace and block comments that
+          ;; doesn't contain newlines.
+          "\\(\\s \\|"
+          (concat "/\\*"
+                  "\\([^*\n\r]\\|\\*[^/\n\r]\\)*"
+                  "\\*/")
+          "\\)*")
+         (concat
+          ;; Match eol (possibly inside a block comment), or the
+          ;; beginning of a line comment.  Note: This has to be
+          ;; modified for awk where line comments start with '#'.
+          "\\("
+          (concat "\\("
+                  "/\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*"
+                  "\\)?"
+                  "$")
+          "\\|//\\)")))
+
+;; Regexp to append to paragraph-start.
+(c-lang-defconst paragraph-start
+  (c c++ objc idl) "$"
+  java "\\(@[a-zA-Z]+\\>\\|$\\)"       ; For Javadoc.
+  pike "\\(@[a-zA-Z]+\\>\\([^{]\\|$\\)\\|$\\)") ; For Pike refdoc.
+
+;; Regexp to append to paragraph-separate.
+(c-lang-defconst paragraph-separate
+  (c c++ objc java idl) "$"
+  pike (c-lang-var paragraph-start))
+
+;; Prefix added to `c-current-comment-prefix' to set
+;; `c-opt-in-comment-lc', or nil if it should be nil.
+(c-lang-defconst c-in-comment-lc-prefix pike "@[\n\r]\\s *")
+
+;; Regexp to match in-comment line continuations, or nil in languages
+;; where that isn't applicable.  It's assumed that it only might match
+;; from and including the last character on a line.  Built from
+;; *-in-comment-lc-prefix and the current value of
+;; c-current-comment-prefix.
+(c-lang-defvar c-opt-in-comment-lc
+  (if (c-lang-var c-in-comment-lc-prefix)
+      (concat (c-lang-var c-in-comment-lc-prefix)
+             c-current-comment-prefix)))
+
+(defconst c-init-lang-defvars
+  ;; Make a lambda of the collected `c-lang-defvar' initializations.
+  (cc-eval-when-compile
+    (if (cc-bytecomp-is-compiling)
+       (byte-compile-lambda `(lambda () ,c-lang-defvar-init-form))
+      `(lambda () ,c-lang-defvar-init-form))))
+
+(defun c-init-language-vars ()
+  ;; Initialize all `c-lang-defvar' variables according to
+  ;; `c-buffer-is-cc-mode'.
+  (if (not (memq c-buffer-is-cc-mode
+                '(c-mode c++-mode objc-mode java-mode idl-mode pike-mode)))
+      (error "Cannot initialize language variables for unknown mode %s"
+            c-buffer-is-cc-mode))
+  (funcall c-init-lang-defvars))
+
+;; Regexp trying to describe the beginning of a Java top-level
+;; definition.  This is not used by CC Mode, nor is it maintained
+;; since it's practically impossible to write a regexp that reliably
+;; matches such a construct.  Other tools are necessary.
 (defconst c-Java-defun-prompt-regexp
   "^[ \t]*\\(\\(\\(public\\|protected\\|private\\|const\\|abstract\\|synchronized\\|final\\|static\\|threadsafe\\|transient\\|native\\|volatile\\)\\s-+\\)*\\(\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*[][_$.a-zA-Z0-9]+\\|[[a-zA-Z]\\)\\s-*\\)\\s-+\\)\\)?\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*\\s-+\\)\\s-*\\)?\\([_a-zA-Z][^][ \t:;.,{}()\7f=]*\\|\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)\\)\\s-*\\(([^);{}]*)\\)?\\([] \t]*\\)\\(\\s-*\\<throws\\>\\s-*\\(\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)[, \t\n\r\f]*\\)+\\)?\\s-*")
 
-
-\f
-;; internal state variables
-
-;; Internal state of hungry delete key feature
-(defvar c-hungry-delete-key nil)
-(make-variable-buffer-local 'c-hungry-delete-key)
-
-;; Internal state of auto newline feature.
-(defvar c-auto-newline nil)
-(make-variable-buffer-local 'c-auto-newline)
-
-;; Internal auto-newline/hungry-delete designation string for mode line.
-(defvar c-auto-hungry-string nil)
-(make-variable-buffer-local 'c-auto-hungry-string)
-
-;; Buffer local language-specific comment style flag.
-(defvar c-double-slash-is-comments-p nil)
-(make-variable-buffer-local 'c-double-slash-is-comments-p)
-
-;; Non-nil means K&R style argument declarations are valid.
-(defvar c-recognize-knr-p t)
-(make-variable-buffer-local 'c-recognize-knr-p)
-
-
-\f
-(defun c-use-java-style ()
-  "Institutes `java' indentation style.
-For use with the variable `java-mode-hook'."
-  (c-set-style "java"))
-
-(defvar c-styles-are-initialized nil)
-
-(defun c-common-init ()
-  ;; Common initializations for all modes.
-  (if c-styles-are-initialized
-      nil
-    (require 'cc-styles)
-    (c-initialize-builtin-style)
-    (if c-style-variables-are-local-p
-       (c-make-styles-buffer-local))
-    (setq c-styles-are-initialized t))
-  ;; these variables should always be buffer local; they do not affect
-  ;; indentation style.
-  (make-local-variable 'paragraph-start)
-  (make-local-variable 'paragraph-separate)
-  (make-local-variable 'paragraph-ignore-fill-prefix)
-  (make-local-variable 'require-final-newline)
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (make-local-variable 'indent-line-function)
-  (make-local-variable 'indent-region-function)
-  (make-local-variable 'comment-start)
-  (make-local-variable 'comment-end)
-  (make-local-variable 'comment-column)
-  (make-local-variable 'comment-start-skip)
-  (make-local-variable 'comment-multi-line)
-  (make-local-variable 'outline-regexp)
-  (make-local-variable 'outline-level)
-  (make-local-variable 'adaptive-fill-regexp)
-  (make-local-variable 'imenu-generic-expression) ;set in the mode functions
-  ;; Emacs 19.30 and beyond only, AFAIK
-  (if (boundp 'fill-paragraph-function)
-      (progn
-       (make-local-variable 'fill-paragraph-function)
-       (setq fill-paragraph-function 'c-fill-paragraph)))
-  ;; now set their values
-  (setq paragraph-start (concat page-delimiter "\\|$")
-       paragraph-separate paragraph-start
-       paragraph-ignore-fill-prefix t
-       require-final-newline t
-       parse-sexp-ignore-comments t
-       indent-line-function 'c-indent-line
-       indent-region-function 'c-indent-region
-       outline-regexp "[^#\n\^M]"
-       outline-level 'c-outline-level
-       comment-column 32
-       comment-start-skip "/\\*+ *\\|// *"
-       adaptive-fill-regexp nil)
-  ;; we have to do something special for c-offsets-alist so that the
-  ;; buffer local value has its own alist structure.
-  (setq c-offsets-alist (copy-alist c-offsets-alist))
-  ;; setup the comment indent variable in a Emacs version portable way
-  ;; ignore any byte compiler warnings you might get here
-  (make-local-variable 'comment-indent-function)
-  (setq comment-indent-function 'c-comment-indent)
-  ;; add menus to menubar
-  (easy-menu-add (c-mode-menu mode-name))
-  ;; put auto-hungry designators onto minor-mode-alist, but only once
-  (or (assq 'c-auto-hungry-string minor-mode-alist)
-      (setq minor-mode-alist
-           (cons '(c-auto-hungry-string c-auto-hungry-string)
-                 minor-mode-alist))))
-
-(defun c-postprocess-file-styles ()
-  "Function that post processes relevant file local variables.
-Currently, this function simply applies any style and offset settings
-found in the file's Local Variable list.  It first applies any style
-setting found in `c-file-style', then it applies any offset settings
-it finds in `c-file-offsets'."
-  ;; apply file styles and offsets
-  (and c-file-style
-       (c-set-style c-file-style))
-  (and c-file-offsets
-       (mapcar
-       (function
-        (lambda (langentry)
-          (let ((langelem (car langentry))
-                (offset (cdr langentry)))
-            (c-set-offset langelem offset)
-            )))
-       c-file-offsets)))
-
-(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
-
 \f
-;; Common routines
-(defsubst c-make-inherited-keymap ()
-  (let ((map (make-sparse-keymap)))
-    (cond
-     ;; XEmacs 19 & 20
-     ((fboundp 'set-keymap-parents)
-      (set-keymap-parents map c-mode-base-map))
-     ;; Emacs 19
-     ((fboundp 'set-keymap-parent)
-      (set-keymap-parent map c-mode-base-map))
-     ;; incompatible
-     (t (error "CC Mode is incompatible with this version of Emacs")))
-    map))
+;; Syntax tables.
 
 (defun c-populate-syntax-table (table)
   ;; Populate the syntax TABLE
-  ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
   (modify-syntax-entry ?_  "_"     table)
   (modify-syntax-entry ?\\ "\\"    table)
   (modify-syntax-entry ?+  "."     table)
@@ -297,133 +633,25 @@ it finds in `c-file-offsets'."
   (modify-syntax-entry ?>  "."     table)
   (modify-syntax-entry ?&  "."     table)
   (modify-syntax-entry ?|  "."     table)
-  (modify-syntax-entry ?\' "\""    table))
-
-(defun c-setup-dual-comments (table)
-  ;; Set up TABLE to handle block and line style comments
+  (modify-syntax-entry ?\' "\""    table)
+  ;; Set up block and line oriented comments.  The new C standard
+  ;; mandates both comment styles even in C, so since all languages
+  ;; now require dual comments, we make this the default.
   (cond
    ;; XEmacs 19 & 20
    ((memq '8-bit c-emacs-features)
     (modify-syntax-entry ?/  ". 1456" table)
-    (modify-syntax-entry ?*  ". 23"   table)
-    (modify-syntax-entry ?\n "> b"    table)
-    ;; Give CR the same syntax as newline, for selective-display
-    (modify-syntax-entry ?\^m "> b"    table))
-   ;; Emacs 19
+    (modify-syntax-entry ?*  ". 23"   table))
+   ;; Emacs 19 & 20
    ((memq '1-bit c-emacs-features)
     (modify-syntax-entry ?/  ". 124b" table)
-    (modify-syntax-entry ?*  ". 23"   table)
-    (modify-syntax-entry ?\n "> b"    table)
-    ;; Give CR the same syntax as newline, for selective-display
-    (modify-syntax-entry ?\^m "> b"   table))
+    (modify-syntax-entry ?*  ". 23"   table))
    ;; incompatible
    (t (error "CC Mode is incompatible with this version of Emacs"))
-   ))
-
-(defvar c-mode-base-map ()
-  "Keymap shared by all CC Mode related modes.")
-
-(if c-mode-base-map
-    nil
-  ;; TBD: should we even worry about naming this keymap. My vote: no,
-  ;; because Emacs and XEmacs do it differently.
-  (setq c-mode-base-map (make-sparse-keymap))
-  ;; put standard keybindings into MAP
-  ;; the following mappings correspond more or less directly to BOCM
-  (define-key c-mode-base-map "{"         'c-electric-brace)
-  (define-key c-mode-base-map "}"         'c-electric-brace)
-  (define-key c-mode-base-map ";"         'c-electric-semi&comma)
-  (define-key c-mode-base-map "#"         'c-electric-pound)
-  (define-key c-mode-base-map ":"         'c-electric-colon)
-  ;; Lucid Emacs 19.9 defined these two, the second of which was
-  ;; commented out...
-  ;; (define-key c-mode-base-map "\e{" 'c-insert-braces)
-  ;; Commented out electric square brackets because nobody likes them.
-  ;; (define-key c-mode-base-map "[" 'c-insert-brackets)
-  (define-key c-mode-base-map "\C-c\C-m"  'c-mark-function)
-  (define-key c-mode-base-map "\e\C-q"    'c-indent-exp)
-  (define-key c-mode-base-map "\ea"       'c-beginning-of-statement)
-  (define-key c-mode-base-map "\ee"       'c-end-of-statement)
-  (define-key c-mode-base-map "\C-c\C-n"  'c-forward-conditional)
-  (define-key c-mode-base-map "\C-c\C-p"  'c-backward-conditional)
-  (define-key c-mode-base-map "\C-c\C-u"  'c-up-conditional)
-  (define-key c-mode-base-map "\t"        'c-indent-command)
-  ;; Caution!  Enter here at your own risk.  We are trying to support
-  ;; several behaviors and it gets disgusting. :-(
-  ;;
-  ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
-  ;; backwards deletion behavior to DEL, which both Delete and
-  ;; Backspace get translated to.  There's no way to separate this
-  ;; behavior in a clean way, so deal with it!  Besides, it's been
-  ;; this way since the dawn of BOCM.
-  (if (not (boundp 'delete-key-deletes-forward))
-      (define-key c-mode-base-map "\177" 'c-electric-backspace)
-    ;; However, XEmacs 20 actually achieved enlightenment.  It is
-    ;; possible to sanely define both backward and forward deletion
-    ;; behavior under X separately (TTYs are forever beyond hope, but
-    ;; who cares?  XEmacs 20 does the right thing with these too).
-    (define-key c-mode-base-map [delete]    'c-electric-delete)
-    (define-key c-mode-base-map [backspace] 'c-electric-backspace))
-  ;; these are new keybindings, with no counterpart to BOCM
-  (define-key c-mode-base-map ","         'c-electric-semi&comma)
-  (define-key c-mode-base-map "*"         'c-electric-star)
-  (define-key c-mode-base-map "\C-c\C-q"  'c-indent-defun)
-  (define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region)
-  ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
-  (define-key c-mode-base-map "\C-c\C-a"  'c-toggle-auto-state)
-  (define-key c-mode-base-map "\C-c\C-b"  'c-submit-bug-report)
-  (define-key c-mode-base-map "\C-c\C-c"  'comment-region)
-  (define-key c-mode-base-map "\C-c\C-d"  'c-toggle-hungry-state)
-  (define-key c-mode-base-map "\C-c\C-e"  'c-macro-expand)
-  (define-key c-mode-base-map "\C-c\C-o"  'c-set-offset)
-  (define-key c-mode-base-map "\C-c\C-s"  'c-show-syntactic-information)
-  (define-key c-mode-base-map "\C-c\C-t"  'c-toggle-auto-hungry-state)
-  (define-key c-mode-base-map "\C-c."     'c-set-style)
-  ;; conflicts with OOBR
-  ;;(define-key c-mode-base-map "\C-c\C-v"  'c-version)
-  )
-
-;; menu support for both XEmacs and Emacs.  If you don't have easymenu
-;; with your version of Emacs, you are incompatible!
-(require 'easymenu)
-
-(defvar c-c-menu nil)
-(defvar c-c++-menu nil)
-(defvar c-objc-menu nil)
-(defvar c-java-menu nil)
-
-(defun c-mode-menu (modestr)
-  (let ((m
-        '(["Comment Out Region"     comment-region (mark)]
-          ["Macro Expand Region"    c-macro-expand (mark)]
-          ["Backslashify"           c-backslash-region (mark)]
-          ["Indent Expression"      c-indent-exp
-           (memq (char-after) '(?\( ?\[ ?\{))]
-          ["Indent Line"            c-indent-command t]
-          ["Fill Comment Paragraph" c-fill-paragraph t]
-          ["Up Conditional"         c-up-conditional t]
-          ["Backward Conditional"   c-backward-conditional t]
-          ["Forward Conditional"    c-forward-conditional t]
-          ["Backward Statement"     c-beginning-of-statement t]
-          ["Forward Statement"      c-end-of-statement t]
-          )))
-    (cons modestr m)))
-
-
-\f
-;; Support for C
-
-(defvar c-mode-abbrev-table nil
-  "Abbrev table in use in c-mode buffers.")
-(define-abbrev-table 'c-mode-abbrev-table ())
-
-(defvar c-mode-map ()
-  "Keymap used in c-mode buffers.")
-(if c-mode-map
-    nil
-  (setq c-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for C
-  )
+   )
+  (modify-syntax-entry ?\n "> b"  table)
+  ;; Give CR the same syntax as newline, for selective-display
+  (modify-syntax-entry ?\^m "> b" table))
 
 ;;;###autoload
 (defvar c-mode-syntax-table nil
@@ -431,121 +659,78 @@ it finds in `c-file-offsets'."
 (if c-mode-syntax-table
     ()
   (setq c-mode-syntax-table (make-syntax-table))
-  (c-populate-syntax-table c-mode-syntax-table)
-  ;; add extra comment syntax
-  (modify-syntax-entry ?/  ". 14"  c-mode-syntax-table)
-  (modify-syntax-entry ?*  ". 23"  c-mode-syntax-table))
-
-(defun c-enable-//-in-c-mode ()
-  "Enables // as a comment delimiter in `c-mode'.
-ANSI C currently does *not* allow this, although many C compilers
-support optional C++ style comments.  To use, call this function from
-your `.emacs' file before you visit any C files.  The changes are
-global and affect all future `c-mode' buffers."
-  (c-setup-dual-comments c-mode-syntax-table)
-  (setq-default c-C-comment-start-regexp c-C++-comment-start-regexp))
-
-(easy-menu-define c-c-menu c-mode-map "C Mode Commands"
-                 (c-mode-menu "C"))
-
-\f
-;; Support for C++
-
-(defvar c++-mode-abbrev-table nil
-  "Abbrev table in use in c++-mode buffers.")
-(define-abbrev-table 'c++-mode-abbrev-table ())
-
-(defvar c++-mode-map ()
-  "Keymap used in c++-mode buffers.")
-(if c++-mode-map
-    nil
-  (setq c++-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for C++
-  (define-key c++-mode-map "\C-c:"  'c-scope-operator)
-  (define-key c++-mode-map "/"      'c-electric-slash)
-  (define-key c++-mode-map "<"      'c-electric-lt-gt)
-  (define-key c++-mode-map ">"      'c-electric-lt-gt))
+  (c-populate-syntax-table c-mode-syntax-table))
 
+;;;###autoload
 (defvar c++-mode-syntax-table nil
   "Syntax table used in c++-mode buffers.")
 (if c++-mode-syntax-table
     ()
   (setq c++-mode-syntax-table (make-syntax-table))
-  (c-populate-syntax-table c++-mode-syntax-table)
-  ;; add extra comment syntax
-  (c-setup-dual-comments c++-mode-syntax-table)
-  ;; TBD: does it make sense for colon to be symbol class in C++?
-  ;; I'm not so sure, since c-label-key is busted on lines like:
-  ;; Foo::bar( i );
-  ;; maybe c-label-key should be fixed instead of commenting this out,
-  ;; but it also bothers me that this only seems appropriate for C++
-  ;; and not C.
-  ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
-  )
-
-(easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands"
-                 (c-mode-menu "C++"))
-
-\f
-;; Support for Objective-C
-
-(defvar objc-mode-abbrev-table nil
-  "Abbrev table in use in objc-mode buffers.")
-(define-abbrev-table 'objc-mode-abbrev-table ())
+  (c-populate-syntax-table c++-mode-syntax-table))
 
-(defvar objc-mode-map ()
-  "Keymap used in objc-mode buffers.")
-(if objc-mode-map
-    nil
-  (setq objc-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for Objective-C
-  (define-key objc-mode-map "/"      'c-electric-slash))
+(defvar c++-template-syntax-table nil
+  "A variant of `c++-mode-syntax-table' that defines `<' and `>' as
+parenthesis characters.  Used temporarily when template argument lists
+are parsed.")
+(if c++-template-syntax-table
+    ()
+  (setq c++-template-syntax-table
+       (copy-syntax-table c++-mode-syntax-table))
+  (modify-syntax-entry ?< "(>" c++-template-syntax-table)
+  (modify-syntax-entry ?> ")<" c++-template-syntax-table))
 
+;;;###autoload
 (defvar objc-mode-syntax-table nil
   "Syntax table used in objc-mode buffers.")
 (if objc-mode-syntax-table
     ()
   (setq objc-mode-syntax-table (make-syntax-table))
   (c-populate-syntax-table objc-mode-syntax-table)
-  ;; add extra comment syntax
-  (c-setup-dual-comments objc-mode-syntax-table)
-  ;; everyone gets these
-  (modify-syntax-entry ?@ "_" objc-mode-syntax-table)
-  )
-
-(easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands"
-                 (c-mode-menu "ObjC"))
-
-\f
-;; Support for Java
-
-(defvar java-mode-abbrev-table nil
-  "Abbrev table in use in java-mode buffers.")
-(define-abbrev-table 'java-mode-abbrev-table ())
-
-(defvar java-mode-map ()
-  "Keymap used in java-mode buffers.")
-(if java-mode-map
-    nil
-  (setq java-mode-map (c-make-inherited-keymap))
-  ;; add bindings which are only useful for Java
-  (define-key java-mode-map "/"      'c-electric-slash))
+  ;; add extra Objective-C only syntax
+  (modify-syntax-entry ?@ "_" objc-mode-syntax-table))
 
+;;;###autoload
 (defvar java-mode-syntax-table nil
   "Syntax table used in java-mode buffers.")
 (if java-mode-syntax-table
     ()
   (setq java-mode-syntax-table (make-syntax-table))
-  (c-populate-syntax-table java-mode-syntax-table)
-  ;; add extra comment syntax
-  (c-setup-dual-comments java-mode-syntax-table)
-  ;; everyone gets these
-  (modify-syntax-entry ?@ "_" java-mode-syntax-table)
-  )
+  (c-populate-syntax-table java-mode-syntax-table))
+
+;;;###autoload
+(defvar idl-mode-syntax-table nil
+  "Syntax table used in idl-mode buffers.")
+(if idl-mode-syntax-table
+    nil
+  (setq idl-mode-syntax-table (make-syntax-table))
+  (c-populate-syntax-table idl-mode-syntax-table))
+
+;;;###autoload
+(defvar pike-mode-syntax-table nil
+  "Syntax table used in pike-mode buffers.")
+(if pike-mode-syntax-table
+    ()
+  (setq pike-mode-syntax-table (make-syntax-table))
+  (c-populate-syntax-table pike-mode-syntax-table)
+  (modify-syntax-entry ?@ "." pike-mode-syntax-table))
+
+\f
+;; internal state variables
+
+;; Internal state of hungry delete key feature
+(defvar c-hungry-delete-key nil)
+(make-variable-buffer-local 'c-hungry-delete-key)
 
-(easy-menu-define c-java-menu java-mode-map "Java Mode Commands"
-                 (c-mode-menu "Java"))
+;; Internal state of auto newline feature.
+(defvar c-auto-newline nil)
+(make-variable-buffer-local 'c-auto-newline)
+
+;; Internal auto-newline/hungry-delete designation string for mode line.
+(defvar c-auto-hungry-string nil)
+(make-variable-buffer-local 'c-auto-hungry-string)
 
 \f
-(provide 'cc-langs)
+(cc-provide 'cc-langs)
+
 ;;; cc-langs.el ends here