emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] Changes to emacs/lisp/progmodes/cc-langs.el [lexbind]


From: Miles Bader
Subject: [Emacs-diffs] Changes to emacs/lisp/progmodes/cc-langs.el [lexbind]
Date: Tue, 14 Oct 2003 19:30:25 -0400

Index: emacs/lisp/progmodes/cc-langs.el
diff -c emacs/lisp/progmodes/cc-langs.el:1.19.2.1 
emacs/lisp/progmodes/cc-langs.el:1.19.2.2
*** emacs/lisp/progmodes/cc-langs.el:1.19.2.1   Fri Apr  4 01:20:32 2003
--- emacs/lisp/progmodes/cc-langs.el    Tue Oct 14 19:30:15 2003
***************
*** 1,10 ****
  ;;; cc-langs.el --- language specific settings for CC Mode
  
! ;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
  
! ;; 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: address@hidden
--- 1,9 ----
  ;;; cc-langs.el --- language specific settings for CC Mode
  
! ;; Copyright (C) 1985,1987,1992-2003 Free Software Foundation, Inc.
  
! ;; Authors:    1998- Martin Stjernholm
! ;;             1992-1999 Barry A. Warsaw
  ;;             1987 Dave Detlefs and Stewart Clamen
  ;;             1985 Richard M. Stallman
  ;; Maintainer: address@hidden
***************
*** 31,36 ****
--- 30,116 ----
  
  ;;; Commentary:
  
+ ;; HACKERS NOTE: There's heavy macro magic here.  If you need to make
+ ;; changes in this or other files containing `c-lang-defconst' but
+ ;; don't want to read through the longer discussion below then read
+ ;; this:
+ ;;
+ ;; o  A change in a `c-lang-defconst' or `c-lang-defvar' will not take
+ ;;    effect if the file containing the mode init function (typically
+ ;;    cc-mode.el) is byte compiled.
+ ;; o  To make changes show in font locking you need to reevaluate the
+ ;;    `*-font-lock-keywords-*' constants, which normally is easiest to
+ ;;    do with M-x eval-buffer in cc-fonts.el.
+ ;; o  In either case it's necessary to reinitialize the mode to make
+ ;;    the changes show in an existing buffer.
+ 
+ ;;; Introduction to the language dependent variable system:
+ ;;
+ ;; This file contains all the language dependent variables, except
+ ;; those specific for font locking which reside in cc-fonts.el.  As
+ ;; far as possible, all the differences between the languages that CC
+ ;; Mode supports are described with these variables only, so that the
+ ;; code can be shared.
+ ;;
+ ;; The language constant system (see cc-defs.el) is used to specify
+ ;; various language dependent info at a high level, such as lists of
+ ;; keywords, and then from them generate - at compile time - the
+ ;; various regexps and other low-level structures actually employed in
+ ;; the code at runtime.
+ ;;
+ ;; This system is also designed to make it easy for developers of
+ ;; derived modes to customize the source constants for new language
+ ;; variants, without having to keep up with the exact regexps etc that
+ ;; are used in each CC Mode version.  It's possible from an external
+ ;; package to add a new language by inheriting an existing one, and
+ ;; then change specific constants as necessary for the new language.
+ ;; The old values for those constants (and the values of all the other
+ ;; high-level constants) may be used to build the new ones, and those
+ ;; new values will in turn be used by the low-level definitions here
+ ;; to build the runtime constants appropriately for the new language
+ ;; in the current version of CC Mode.
+ ;;
+ ;; Like elsewhere in CC Mode, the existence of a doc string signifies
+ ;; that a language constant is part of the external API, and that it
+ ;; therefore can be used with a high confidence that it will continue
+ ;; to work with future versions of CC Mode.  Even so, it's not
+ ;; unlikely that such constants will change meaning slightly as this
+ ;; system is refined further; a certain degree of dependence on the CC
+ ;; Mode version is unavoidable when hooking in at this level.  Also
+ ;; note that there's still work to be done to actually use these
+ ;; constants everywhere inside CC Mode; there are still hardcoded
+ ;; values in many places in the code.
+ ;;
+ ;; Separate packages will also benefit from the compile time
+ ;; evaluation; the byte compiled file(s) for them will contain the
+ ;; compiled runtime constants ready for use by (the byte compiled) CC
+ ;; Mode, and the source definitions in this file don't have to be
+ ;; loaded then.  However, if a byte compiled package is loaded that
+ ;; has been compiled with a different version of CC Mode than the one
+ ;; currently loaded, then the compiled-in values will be discarded and
+ ;; new ones will be built when the mode is initialized.  That will
+ ;; automatically trig a load of the file(s) containing the source
+ ;; definitions (i.e. this file and/or cc-fonts.el) if necessary.
+ ;;
+ ;; A small example of a derived mode is available at
+ ;; <http://cc-mode.sourceforge.net/derived-mode-ex.el>.  It also
+ ;; contains some useful hints for derived mode developers.
+ 
+ ;;; Using language variables:
+ ;;
+ ;; The `c-lang-defvar' forms in this file comprise the language
+ ;; variables that CC Mode uses.  It does not work to use
+ ;; `c-lang-defvar' anywhere else (which isn't much of a limitation
+ ;; since these variables sole purpose is to interface with the CC Mode
+ ;; core functions).  The values in these `c-lang-defvar's are not
+ ;; evaluated right away but instead collected to a single large `setq'
+ ;; that can be inserted for a particular language with the
+ ;; `c-init-language-vars' macro.
+ 
+ ;; This file is only required at compile time, or when not running
+ ;; from byte compiled files, or when the source definitions for the
+ ;; language constants are requested.
+ 
  ;;; Code:
  
  (eval-when-compile
***************
*** 39,741 ****
                  (stringp byte-compile-dest-file))
             (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
!     (require 'cc-bytecomp)))
  
  (cc-require 'cc-defs)
  (cc-require 'cc-vars)
  
  
! ;; 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-delete-duplicates (list)
!     (let ((tail list))
!       (while tail
!       (setcdr tail (delete (car tail) (cdr tail)))
!       (setq tail (cdr tail)))
!       list))
! 
!   (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."
!     (let ((list (copy-sequence (apply 'append lists))))
!       (setq list (c-delete-duplicates list))
!       (if list
!         (let ((re (c-regexp-opt list)))
!           ;; 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)
!   )
  
  
! ;; 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 (c-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)))
! (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))
! 
! ;; 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:;.,{}()=]*\\|\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)\\)\\s-*\\(([^);{}]*)\\)?\\([] 
\t]*\\)\\(\\s-*\\<throws\\>\\s-*\\(\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)[, 
\t\n\r\f]*\\)+\\)?\\s-*")
  
  
! ;; Syntax tables.
  
! (defun c-populate-syntax-table (table)
!   ;; Populate the syntax TABLE
!   (modify-syntax-entry ?_  "_"     table)
!   (modify-syntax-entry ?\\ "\\"    table)
!   (modify-syntax-entry ?+  "."     table)
!   (modify-syntax-entry ?-  "."     table)
!   (modify-syntax-entry ?=  "."     table)
!   (modify-syntax-entry ?%  "."     table)
!   (modify-syntax-entry ?<  "."     table)
!   (modify-syntax-entry ?>  "."     table)
!   (modify-syntax-entry ?&  "."     table)
!   (modify-syntax-entry ?|  "."     table)
!   (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))
!    ;; Emacs 19 & 20
!    ((memq '1-bit c-emacs-features)
!     (modify-syntax-entry ?/  ". 124b" table)
!     (modify-syntax-entry ?*  ". 23"   table))
!    ;; incompatible
!    (t (error "CC Mode is incompatible with this version of Emacs"))
!    )
!   (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
!   "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))
! 
! ;;;###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))
! 
! (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 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))
! 
! ;;;###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))
! 
! 
! ;; 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)
  
  
  (cc-provide 'cc-langs)
  
  ;;; cc-langs.el ends here
--- 119,2331 ----
                  (stringp byte-compile-dest-file))
             (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
!     (load "cc-bytecomp" nil t)))
  
  (cc-require 'cc-defs)
  (cc-require 'cc-vars)
  
  
! ;;; Setup for the `c-lang-defvar' system.
  
  (eval-and-compile
!   ;; These are used to collect the init forms from the subsequent
!   ;; `c-lang-defvar'.  They are used to build the lambda in
!   ;; `c-make-init-lang-vars-fun' below.
!   (defvar c-lang-variable-inits nil)
!   (defvar c-lang-variable-inits-tail nil)
!   (setq c-lang-variable-inits (list nil)
!       c-lang-variable-inits-tail c-lang-variable-inits))
! 
! (defmacro c-lang-defvar (var val &optional doc)
!   "Declares the buffer local variable VAR to get the value VAL at mode
! initialization, at which point VAL is evaluated.  More accurately, VAL
! is evaluated and bound to VAR when the result from the macro
! `c-init-language-vars' is evaluated.
! 
! `c-lang-const' is typically used in VAL to get the right value for the
! language being initialized, and such calls will be macro expanded to
! the evaluated constant value at compile time.
! 
! This macro does not do any hidden buffer changes."
! 
!   (when (and (not doc)
!            (eq (car-safe val) 'c-lang-const)
!            (eq (nth 1 val) var)
!            (not (nth 2 val)))
!     ;; Special case: If there's no docstring and the value is a
!     ;; simple (c-lang-const foo) where foo is the same name as VAR
!     ;; then take the docstring from the language constant foo.
!     (setq doc (get (intern (symbol-name (nth 1 val)) c-lang-constants)
!                  'variable-documentation)))
!   (or (stringp doc)
!       (setq doc nil))
! 
!   (let ((elem (assq var (cdr c-lang-variable-inits))))
!     (if elem
!       (setcdr elem (list val doc))
!       (setcdr c-lang-variable-inits-tail (list (list var val doc)))
!       (setq c-lang-variable-inits-tail (cdr c-lang-variable-inits-tail))))
! 
!   ;; Return the symbol, like the other def* forms.
!   `',var)
! 
! (put 'c-lang-defvar 'lisp-indent-function 'defun)
! (eval-after-load "edebug"
!   '(def-edebug-spec c-lang-defvar
!      (&define name def-form &optional stringp)))
  
! 
! ;;; Various mode specific values that aren't language related.
! 
! (c-lang-defconst c-mode-menu
!   ;; The definition for the mode menu.  The menu title is prepended to
!   ;; this before it's fed to `easy-menu-define'.
!   t `(["Comment Out Region"     comment-region
!        (c-fn-region-is-active-p)]
!       ["Uncomment Region"       (comment-region (region-beginning)
!                                               (region-end) '(4))
!        (c-fn-region-is-active-p)]
!       ["Indent Expression"      c-indent-exp
!        (memq (char-after) '(?\( ?\[ ?\{))]
!       ["Indent Line or Region"  c-indent-line-or-region t]
!       ["Fill Comment Paragraph" c-fill-paragraph t]
!       "----"
!       ["Backward Statement"     c-beginning-of-statement t]
!       ["Forward Statement"      c-end-of-statement t]
!       ,@(when (c-lang-const c-opt-cpp-prefix)
!         ;; Only applicable if there's a cpp preprocessor.
!         `(["Up Conditional"         c-up-conditional t]
!           ["Backward Conditional"   c-backward-conditional t]
!           ["Forward Conditional"    c-forward-conditional t]
!           "----"
!           ["Macro Expand Region"    c-macro-expand
!            (c-fn-region-is-active-p)]
!           ["Backslashify"           c-backslash-region
!            (c-fn-region-is-active-p)]))
!       "----"
!       ("Toggle..."
!        ["Syntactic indentation" c-toggle-syntactic-indentation t]
!        ["Auto newline"          c-toggle-auto-state t]
!        ["Hungry delete"         c-toggle-hungry-state t])))
  
  
! ;;; Syntax tables.
  
! (defun c-populate-syntax-table (table)
!   "Populate the given syntax table as necessary for a C-like language.
! This includes setting ' and \" as string delimiters, and setting up
! the comment syntax to handle both line style \"//\" and block style
! \"/*\" \"*/\" comments."
! 
!   (modify-syntax-entry ?_  "_"     table)
!   (modify-syntax-entry ?\\ "\\"    table)
!   (modify-syntax-entry ?+  "."     table)
!   (modify-syntax-entry ?-  "."     table)
!   (modify-syntax-entry ?=  "."     table)
!   (modify-syntax-entry ?%  "."     table)
!   (modify-syntax-entry ?<  "."     table)
!   (modify-syntax-entry ?>  "."     table)
!   (modify-syntax-entry ?&  "."     table)
!   (modify-syntax-entry ?|  "."     table)
!   (modify-syntax-entry ?\' "\""    table)
!   (modify-syntax-entry ?\240 "."   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
!    ((memq '8-bit c-emacs-features)
!     (modify-syntax-entry ?/  ". 1456" table)
!     (modify-syntax-entry ?*  ". 23"   table))
!    ;; Emacs
!    ((memq '1-bit c-emacs-features)
!     (modify-syntax-entry ?/  ". 124b" table)
!     (modify-syntax-entry ?*  ". 23"   table))
!    ;; incompatible
!    (t (error "CC Mode is incompatible with this version of Emacs")))
! 
!   (modify-syntax-entry ?\n "> b"  table)
!   ;; Give CR the same syntax as newline, for selective-display
!   (modify-syntax-entry ?\^m "> b" table))
! 
! (c-lang-defconst c-make-mode-syntax-table
!   "Functions that generates the mode specific syntax tables.
! The syntax tables aren't stored directly since they're quite large."
!   t `(lambda ()
!        (let ((table (make-syntax-table)))
!        (c-populate-syntax-table table)
!        ;; Mode specific syntaxes.
!        ,(cond ((c-major-mode-is 'objc-mode)
!                `(modify-syntax-entry ?@ "_" table))
!               ((c-major-mode-is 'pike-mode)
!                `(modify-syntax-entry ?@ "." table)))
!        table)))
! 
! (c-lang-defconst c-mode-syntax-table
!   ;; The syntax tables in evaluated form.  Only used temporarily when
!   ;; the constants in this file are evaluated.
!   t (funcall (c-lang-const c-make-mode-syntax-table)))
! 
! (c-lang-defconst c++-make-template-syntax-table
!   ;; A variant of `c++-mode-syntax-table' that defines `<' and `>' as
!   ;; parenthesis characters.  Used temporarily when template argument
!   ;; lists are parsed.  Note that this encourages incorrect parsing of
!   ;; templates since they might contain normal operators that uses the
!   ;; '<' and '>' characters.  Therefore this syntax table might go
!   ;; away when CC Mode handles templates correctly everywhere.
!   t   nil
!   c++ `(lambda ()
!        (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table))))
!          (modify-syntax-entry ?< "(>" table)
!          (modify-syntax-entry ?> ")<" table)
!          table)))
! (c-lang-defvar c++-template-syntax-table
!   (and (c-lang-const c++-make-template-syntax-table)
!        (funcall (c-lang-const c++-make-template-syntax-table))))
! 
! (c-lang-defconst c-identifier-syntax-modifications
!   "A list that describes the modifications that should be done to the
! mode syntax table to get a syntax table that matches all identifiers
! and keywords as words.
! 
! The list is just like the one used in `font-lock-defaults': Each
! element is a cons where the car is the character to modify and the cdr
! the new syntax, as accepted by `modify-syntax-entry'."
!   ;; The $ character is not allowed in most languages (one exception
!   ;; is Java which allows it for legacy reasons) but we still classify
!   ;; it as an indentifier character since it's often used in various
!   ;; machine generated identifiers.
!   t    '((?_ . "w") (?$ . "w"))
!   objc (append '((?@ . "w"))
!              (c-lang-const c-identifier-syntax-modifications))
!   awk  '((?_ . "w")))
! (c-lang-defvar c-identifier-syntax-modifications
!   (c-lang-const c-identifier-syntax-modifications))
! 
! (c-lang-defvar c-identifier-syntax-table
!   (let ((table (copy-syntax-table (c-mode-var "mode-syntax-table")))
!       (mods c-identifier-syntax-modifications)
!       mod)
!     (while mods
!       (setq mod (car mods)
!           mods (cdr mods))
!       (modify-syntax-entry (car mod) (cdr mod) table))
!     table)
!   "Syntax table built on the mode syntax table but additionally
! classifies symbol constituents like '_' and '$' as word constituents,
! so that all identifiers are recognized as words.")
! 
! 
! ;;; Lexer-level syntax (identifiers, tokens etc).
! 
! (c-lang-defconst c-symbol-start
!   "Regexp that matches the start of a symbol, i.e. any identifier or
! keyword.  It's unspecified how far it matches.  Does not contain a \\|
! operator at the top level."
!   t    (concat "[" c-alpha "_]")
!   pike (concat "[" c-alpha "_`]"))
! (c-lang-defvar c-symbol-start (c-lang-const c-symbol-start))
! 
! (c-lang-defconst c-symbol-chars
!   "Set of characters that can be part of a symbol.
! This is on the form that fits inside [ ] in a regexp."
!   ;; Pike note: With the backquote identifiers this would include most
!   ;; operator chars too, but they are handled with other means instead.
!   t    (concat c-alnum "_$")
!   objc (concat c-alnum "_$@"))
  
  (c-lang-defconst c-symbol-key
!   "Regexp matching identifiers and keywords.  Assumed to match if
! `c-symbol-start' matches on the same position."
!   t    (concat (c-lang-const c-symbol-start)
!              "[" (c-lang-const c-symbol-chars) "]*")
!   pike (concat
!       ;; Use the value from C here since the operator backquote is
!       ;; covered by the other alternative.
!       (c-lang-const c-symbol-key c)
!       "\\|"
!       (c-make-keywords-re nil
!         (c-lang-const c-overloadable-operators))))
! (c-lang-defvar c-symbol-key (c-lang-const c-symbol-key))
! 
! (c-lang-defconst c-symbol-key-depth
!   ;; Number of regexp grouping parens in `c-symbol-key'.
!   t (c-regexp-opt-depth (c-lang-const c-symbol-key)))
! 
! (c-lang-defconst c-nonsymbol-chars
!   "This is the set of chars that can't be part of a symbol, i.e. the
! negation of `c-symbol-chars'."
!   t (concat "^" (c-lang-const c-symbol-chars)))
! (c-lang-defvar c-nonsymbol-chars (c-lang-const c-nonsymbol-chars))
! 
! (c-lang-defconst c-nonsymbol-key
!   "Regexp that matches any character that can't be part of a symbol.
! It's usually appended to other regexps to avoid matching a prefix.
! It's assumed to not contain any submatchers."
!   ;; The same thing regarding Unicode identifiers applies here as to
!   ;; `c-symbol-key'.
!   t (concat "[" (c-lang-const c-nonsymbol-chars) "]"))
! 
! (c-lang-defconst c-opt-identifier-concat-key
!   "Regexp matching the operators that join symbols to fully qualified
! identifiers, or nil in languages that don't have such things.  Does
! not contain a \\| operator at the top level."
!   t    nil
!   c++  "::"
!   java "\\."
!   idl  "::"
!   pike "\\(::\\|\\.\\)")
! (c-lang-defvar c-opt-identifier-concat-key
!   (c-lang-const c-opt-identifier-concat-key)
!   'dont-doc)
! 
! (c-lang-defconst c-opt-after-id-concat-key
!   "Regexp that must match the token after `c-opt-identifier-concat-key'
! for it to be considered an identifier concatenation operator (which
! e.g. causes the preceding identifier to be fontified as a reference).
! Assumed to be a string if `c-opt-identifier-concat-key' is."
!   t    (if (c-lang-const c-opt-identifier-concat-key)
!          (c-lang-const c-symbol-start))
!   c++  (concat (c-lang-const c-symbol-start)
!              "\\|[~*]")
!   java (concat (c-lang-const c-symbol-start)
!              "\\|\\*"))
! 
! (c-lang-defconst c-identifier-start
!   "Regexp that matches the start of an \(optionally qualified)
! identifier.  It should also match all keywords.  It's unspecified how
! far it matches."
!   t    (concat (c-lang-const c-symbol-start)
!              (if (c-lang-const c-opt-identifier-concat-key)
!                  (concat "\\|" (c-lang-const c-opt-identifier-concat-key))
!                ""))
!   c++  (concat (c-lang-const c-identifier-start)
!              "\\|"
!              "[~*][ \t\n\r\f\v]*" (c-lang-const c-symbol-start))
!   ;; Java does not allow a leading qualifier operator.
!   java (c-lang-const c-symbol-start))
! (c-lang-defvar c-identifier-start (c-lang-const c-identifier-start))
! 
! (c-lang-defconst c-identifier-key
!   "Regexp matching a fully qualified identifier, like \"A::B::c\" in
! C++.  It does not recognize the full range of syntactic whitespace
! between the tokens; `c-forward-name' has to be used for that."
!   t    (c-lang-const c-symbol-key)    ; Default to `c-symbol-key'.
!   ;; C++ allows a leading qualifier operator and a `~' before the last
!   ;; symbol.  This regexp is more complex than strictly necessary to
!   ;; ensure that it can be matched with a minimum of backtracking.
!   c++  (concat
!       "\\(" (c-lang-const c-opt-identifier-concat-key) "[ \t\n\r\f\v]*\\)?"
!       (concat
!        "\\("
!        ;; The submatch below is depth of `c-opt-identifier-concat-key' + 3.
!        "\\(" (c-lang-const c-symbol-key) "\\)"
!        (concat "\\("
!                "[ \t\n\r\f\v]*"
!                (c-lang-const c-opt-identifier-concat-key)
!                "[ \t\n\r\f\v]*"
!                ;; The submatch below is: `c-symbol-key-depth' +
!                ;; 2 * depth of `c-opt-identifier-concat-key' + 5.
!                "\\(" (c-lang-const c-symbol-key) "\\)"
!                "\\)*")
!        (concat "\\("
!                "[ \t\n\r\f\v]*"
!                (c-lang-const c-opt-identifier-concat-key)
!                "[ \t\n\r\f\v]*"
!                "[~*]"
!                "[ \t\n\r\f\v]*"
!                ;; The submatch below is: 2 * `c-symbol-key-depth' +
!                ;; 3 * depth of `c-opt-identifier-concat-key' + 7.
!                "\\(" (c-lang-const c-symbol-key) "\\)"
!                "\\)?")
!        "\\|"
!        "~[ \t\n\r\f\v]*"
!        ;; The submatch below is: 3 * `c-symbol-key-depth' +
!        ;; 3 * depth of `c-opt-identifier-concat-key' + 8.
!        "\\(" (c-lang-const c-symbol-key) "\\)"
!        "\\)"))
!   ;; IDL and Pike allows a leading qualifier operator.
!   (idl pike) (concat
!             "\\("
!             (c-lang-const c-opt-identifier-concat-key)
!             "[ \t\n\r\f\v]*"
!             "\\)?"
!             ;; The submatch below is depth of
!             ;; `c-opt-identifier-concat-key' + 2.
!             "\\(" (c-lang-const c-symbol-key) "\\)"
!             (concat "\\("
!                     "[ \t\n\r\f\v]*"
!                     (c-lang-const c-opt-identifier-concat-key)
!                     "[ \t\n\r\f\v]*"
!                     ;; The submatch below is: `c-symbol-key-depth' +
!                     ;; 2 * depth of `c-opt-identifier-concat-key' + 4.
!                     "\\(" (c-lang-const c-symbol-key) "\\)"
!                     "\\)*"))
!   ;; Java does not allow a leading qualifier operator.  If it ends
!   ;; with ".*" (used in import declarations) we also consider that as
!   ;; part of the name.  ("*" is actually recognized in any position
!   ;; except the first by this regexp, but we don't bother.)
!   java (concat "\\(" (c-lang-const c-symbol-key) "\\)" ; 1
!              (concat "\\("
!                      "[ \t\n\r\f\v]*"
!                      (c-lang-const c-opt-identifier-concat-key)
!                      "[ \t\n\r\f\v]*"
!                      (concat "\\("
!                              ;; The submatch below is `c-symbol-key-depth' +
!                              ;; depth of `c-opt-identifier-concat-key' + 4.
!                              "\\(" (c-lang-const c-symbol-key) "\\)"
!                              "\\|\\*\\)")
!                      "\\)*")))
! (c-lang-defvar c-identifier-key (c-lang-const c-identifier-key))
! 
! (c-lang-defconst c-identifier-last-sym-match
!   "Used to identify the submatch in `c-identifier-key' that surrounds
! the last symbol in the qualified identifier.  It's a list of submatch
! numbers, of which the first that has a match is taken.  It's assumed
! that at least one does when the regexp has matched."
!   t    '(0)
!   c++  (list (+ (* 3 (c-lang-const c-symbol-key-depth))
!               (* 3 (c-regexp-opt-depth
!                     (c-lang-const c-opt-identifier-concat-key)))
!               8)
!            (+ (* 2 (c-lang-const c-symbol-key-depth))
!               (* 3 (c-regexp-opt-depth
!                     (c-lang-const c-opt-identifier-concat-key)))
!               7)
!            (+ (c-lang-const c-symbol-key-depth)
!               (* 2 (c-regexp-opt-depth
!                     (c-lang-const c-opt-identifier-concat-key)))
!               5)
!            (+ (c-regexp-opt-depth
!                (c-lang-const c-opt-identifier-concat-key))
!               3))
!   (idl pike) (list (+ (c-lang-const c-symbol-key-depth)
!                     (* 2 (c-regexp-opt-depth
!                           (c-lang-const c-opt-identifier-concat-key)))
!                     4)
!                  (+ (c-regexp-opt-depth
!                      (c-lang-const c-opt-identifier-concat-key))
!                     2))
!   java (list (+ (c-lang-const c-symbol-key-depth)
!               (c-regexp-opt-depth
!                (c-lang-const c-opt-identifier-concat-key))
!               4)
!            1))
! (c-lang-defvar c-identifier-last-sym-match
!   (c-lang-const c-identifier-last-sym-match)
!   'dont-doc)
! 
! (c-lang-defconst c-opt-cpp-prefix
!   "Regexp matching the prefix of a cpp directive in the languages that
! normally use that macro preprocessor.  Tested at bol or at boi.
! Assumed to not contain any submatches or \\| operators."
!   t "\\s *#\\s *"
!   (java awk) nil)
! (c-lang-defvar c-opt-cpp-prefix (c-lang-const c-opt-cpp-prefix))
! 
! (c-lang-defconst c-opt-cpp-start
!   "Regexp matching the prefix of a cpp directive including the directive
! name, or nil in languages without preprocessor support.  The first
! submatch surrounds the directive name."
!   t    (if (c-lang-const c-opt-cpp-prefix)
!          (concat (c-lang-const c-opt-cpp-prefix)
!                  "\\([" c-alnum "]+\\)"))
!   ;; Pike, being a scripting language, recognizes hash-bangs too.
!   pike (concat (c-lang-const c-opt-cpp-prefix)
!              "\\([" c-alnum "]+\\|!\\)"))
! (c-lang-defvar c-opt-cpp-start (c-lang-const c-opt-cpp-start))
! 
! (c-lang-defconst c-cpp-defined-fns
!   ;; Name of functions in cpp expressions that take an identifier as
!   ;; the argument.
!   t    (if (c-lang-const c-opt-cpp-prefix)
!          '("defined"))
!   pike '("defined" "efun" "constant"))
! 
! (c-lang-defconst c-assignment-operators
!   "List of all assignment operators."
!   t    '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" "&=" "^=" "|=")
!   java (append (c-lang-const c-assignment-operators)
!              '(">>>="))
!   c++  (append (c-lang-const c-assignment-operators)
!              '("and_eq" "or_eq" "xor_eq"))
!   idl  nil)
! 
! (c-lang-defconst c-operators
!   "List describing all operators, along with their precedence and
! associativity.  The order in the list corresponds to the precedence of
! the operators: The operators in each element is a group with the same
! precedence, and the group has higher precedence than the groups in all
! following elements.  The car of each element describes the type of of
! the operator group, and the cdr is a list of the operator tokens in
! it.  The operator group types are:
! 
! 'prefix         Unary prefix operators.
! 'postfix        Unary postfix operators.
! 'left-assoc     Binary left associative operators (i.e. a+b+c means (a+b)+c).
! 'right-assoc    Binary right associative operators (i.e. a=b=c means a=(b=c)).
! 'right-assoc-sequence
!                 Right associative operator that constitutes of a
!                 sequence of tokens that separate expressions.  All the
!                 tokens in the group are in this case taken as
!                 describing the sequence in one such operator, and the
!                 order between them is therefore significant.
! 
! Operators containing a character with paren syntax are taken to match
! with a corresponding open/close paren somewhere else.  A postfix
! operator with close paren syntax is taken to end a postfix expression
! started somewhere earlier, rather than start a new one at point.  Vice
! versa for prefix operators with open paren syntax.
! 
! 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
!   ;; in this variable; precedence, associativity etc are present as a
!   ;; preparation for future work.
! 
!   t `(;; Preprocessor.
!       ,@(when (c-lang-const c-opt-cpp-prefix)
!         `((prefix "#"
!                   ,@(when (c-major-mode-is '(c-mode c++-mode))
!                       '("%:" "??=")))
!           (left-assoc "##"
!                       ,@(when (c-major-mode-is '(c-mode c++-mode))
!                           '("%:%:" "??=??=")))))
! 
!       ;; Primary.  Info duplicated in `c-opt-identifier-concat-key'
!       ;; and `c-identifier-key'.
!       ,@(cond ((c-major-mode-is 'c++-mode)
!              `((postfix-if-paren "<" ">") ; Templates.
!                (prefix "~" "??-" "compl")
!                (right-assoc "::")
!                (prefix "::")))
!             ((c-major-mode-is 'pike-mode)
!              `((left-assoc "::")
!                (prefix "::" "global" "predef")))
!             ((c-major-mode-is 'java-mode)
!              `(;; Not necessary since it's also in the postfix group below.
!                ;;(left-assoc ".")
!                (prefix "super"))))
! 
!       ;; Postfix.
!       ,@(when (c-major-mode-is 'c++-mode)
!         ;; The following need special treatment.
!         `((prefix "dynamic_cast" "static_cast"
!                   "reinterpret_cast" "const_cast" "typeid")))
!       (left-assoc "."
!                 ,@(unless (c-major-mode-is 'java-mode)
!                     '("->")))
!       (postfix "++" "--" "[" "]" "(" ")"
!              ,@(when (c-major-mode-is '(c-mode c++-mode))
!                  '("<:" ":>" "??(" "??)")))
! 
!       ;; Unary.
!       (prefix "++" "--" "+" "-" "!" "~"
!             ,@(when (c-major-mode-is 'c++-mode) '("not" "compl"))
!             ,@(when (c-major-mode-is '(c-mode c++-mode))
!                 '("*" "&" "sizeof" "??-"))
!             ,@(when (c-major-mode-is 'objc-mode)
!                 '("@selector" "@protocol" "@encode"))
!             ;; The following need special treatment.
!             ,@(cond ((c-major-mode-is 'c++-mode)
!                      '("new" "delete"))
!                     ((c-major-mode-is 'java-mode)
!                      '("new"))
!                     ((c-major-mode-is 'pike-mode)
!                      '("class" "lambda" "catch" "throw" "gauge")))
!             "(" ")"                   ; Cast.
!             ,@(when (c-major-mode-is 'pike-mode)
!                 '("[" "]")))          ; Type cast.
! 
!       ;; Member selection.
!       ,@(when (c-major-mode-is 'c++-mode)
!         `((left-assoc ".*" "->*")))
! 
!       ;; Multiplicative.
!       (left-assoc "*" "/" "%")
! 
!       ;; Additive.
!       (left-assoc "+" "-")
! 
!       ;; Shift.
!       (left-assoc "<<" ">>"
!                 ,@(when (c-major-mode-is 'java-mode)
!                     '(">>>")))
! 
!       ;; Relational.
!       (left-assoc "<" ">" "<=" ">="
!                 ,@(when (c-major-mode-is 'java-mode)
!                     '("instanceof")))
! 
!       ;; Equality.
!       (left-assoc "==" "!="
!                 ,@(when (c-major-mode-is 'c++-mode) '("not_eq")))
! 
!       ;; Bitwise and.
!       (left-assoc "&"
!                 ,@(when (c-major-mode-is 'c++-mode) '("bitand")))
! 
!       ;; Bitwise exclusive or.
!       (left-assoc "^"
!                 ,@(when (c-major-mode-is '(c-mode c++-mode))
!                     '("??'"))
!                 ,@(when (c-major-mode-is 'c++-mode) '("xor")))
! 
!       ;; Bitwise or.
!       (left-assoc "|"
!                 ,@(when (c-major-mode-is '(c-mode c++-mode))
!                     '("??!"))
!                 ,@(when (c-major-mode-is 'c++-mode) '("bitor")))
! 
!       ;; Logical and.
!       (left-assoc "&&"
!                 ,@(when (c-major-mode-is 'c++-mode) '("and")))
! 
!       ;; Logical or.
!       (left-assoc "||"
!                 ,@(when (c-major-mode-is '(c-mode c++-mode))
!                     '("??!??!"))
!                 ,@(when (c-major-mode-is 'c++-mode) '("or")))
! 
!       ;; Conditional.
!       (right-assoc-sequence "?" ":")
! 
!       ;; Assignment.
!       (right-assoc ,@(c-lang-const c-assignment-operators))
! 
!       ;; Exception.
!       ,@(when (c-major-mode-is 'c++-mode)
!         '((prefix "throw")))
! 
!       ;; Sequence.
!       (left-assoc ","))
! 
!   ;; IDL got its own definition since it has a much smaller operator
!   ;; set than the other languages.
!   idl `(;; Preprocessor.
!       (prefix "#")
!       (left-assoc "##")
!       ;; Primary.  Info duplicated in `c-opt-identifier-concat-key'
!       ;; and `c-identifier-key'.
!       (left-assoc "::")
!       (prefix "::")
!       ;; Unary.
!       (prefix  "+" "-" "~")
!       ;; Multiplicative.
!       (left-assoc "*" "/" "%")
!       ;; Additive.
!       (left-assoc "+" "-")
!       ;; Shift.
!       (left-assoc "<<" ">>")
!       ;; And.
!       (left-assoc "&")
!       ;; Xor.
!       (left-assoc "^")
!       ;; Or.
!       (left-assoc "|")))
! 
! (c-lang-defconst c-operator-list
!   ;; The operators as a flat list (without duplicates).
!   t (delete-duplicates (mapcan (lambda (elem) (append (cdr elem) nil))
!                              (c-lang-const c-operators))
!                      :test 'string-equal))
! 
! (c-lang-defconst c-overloadable-operators
!   "List of the operators that are overloadable, in their \"identifier form\"."
!   t    nil
!   ;; The preceding "operator" keyword is treated separately in C++.
!   c++  '("new" "delete" ;; Can be followed by "[]" but we ignore that.
!        "+" "-" "*" "/" "%"
!        "^" "??'" "xor" "&" "bitand" "|" "??!" "bitor" "~" "??-" "compl"
!        "!" "=" "<" ">" "+=" "-=" "*=" "/=" "%=" "^="
!        "??'=" "xor_eq" "&=" "and_eq" "|=" "??!=" "or_eq"
!        "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=" ">="
!        "&&" "and" "||" "??!??!" "or" "++" "--" "," "->*" "->"
!        "()" "[]" "<::>" "??(??)")
!   ;; These work like identifiers in Pike.
!   pike '("`+" "`-" "`&" "`|" "`^" "`<<" "`>>" "`*" "`/" "`%" "`~"
!        "`==" "`<" "`>" "`!" "`[]" "`[]=" "`->" "`->=" "`()" "``+"
!        "``-" "``&" "``|" "``^" "``<<" "``>>" "``*" "``/" "``%"
!        "`+="))
! 
! (c-lang-defconst c-overloadable-operators-regexp
!   ;; Regexp tested after an "operator" token in C++.
!   t   nil
!   c++ (c-make-keywords-re nil (c-lang-const c-overloadable-operators)))
! (c-lang-defvar c-overloadable-operators-regexp
!   (c-lang-const c-overloadable-operators-regexp))
! 
! (c-lang-defconst c-other-op-syntax-tokens
!   "List of the tokens made up of characters in the punctuation or
! parenthesis syntax classes that have uses other than as expression
! operators."
!   t '("{" "}" "(" ")" "[" "]" ";" ":" "," "=" "/*" "*/" "//")
!   (c c++ pike) (append '("#" "##"     ; Used by cpp.
!                        "::" "...")
!                      (c-lang-const c-other-op-syntax-tokens))
!   (c c++) (append '("<%" "%>" "<:" ":>" "%:" "%:%:" "*")
!                 (c-lang-const c-other-op-syntax-tokens))
!   c++  (append '("&") (c-lang-const c-other-op-syntax-tokens))
!   objc (append '("#" "##"             ; Used by cpp.
!                "+" "-") (c-lang-const c-other-op-syntax-tokens))
!   idl  (append '("#" "##")            ; Used by cpp.
!              (c-lang-const c-other-op-syntax-tokens))
!   pike (append '("..")
!              (c-lang-const c-other-op-syntax-tokens)
!              (c-lang-const c-overloadable-operators))
!   awk '("{" "}" "(" ")" "[" "]" ";" "," "=" "/"))
! 
! (c-lang-defconst c-nonsymbol-token-regexp
!   ;; Regexp matching all tokens in the punctuation and parenthesis
!   ;; syntax classes.  Note that this also matches ".", which can start
!   ;; a float.
!   t (c-make-keywords-re nil
!       (c-with-syntax-table (c-lang-const c-mode-syntax-table)
!       (mapcan (lambda (op)
!                 (if (string-match "\\`\\(\\s.\\|\\s\(\\|\\s\)\\)+\\'" op)
!                     (list op)))
!               (append (c-lang-const c-other-op-syntax-tokens)
!                       (c-lang-const c-operator-list))))))
! (c-lang-defvar c-nonsymbol-token-regexp
!   (c-lang-const c-nonsymbol-token-regexp))
! 
! (c-lang-defconst c-assignment-op-regexp
!   ;; Regexp matching all assignment operators and only them.  The
!   ;; beginning of the first submatch is used to detect the end of the
!   ;; token, along with the end of the whole match.
!   t (if (c-lang-const c-assignment-operators)
!       (concat
!        ;; Need special case for "=" since it's a prefix of "==".
!        "=\\([^=]\\|$\\)"
!        "\\|"
!        (c-make-keywords-re nil
!          (set-difference (c-lang-const c-assignment-operators)
!                          '("=")
!                          :test 'string-equal)))
!       "\\<\\>"))
! (c-lang-defvar c-assignment-op-regexp
!   (c-lang-const c-assignment-op-regexp))
! 
! (c-lang-defconst c-<-op-cont-regexp
!   ;; Regexp matching the second and subsequent characters of all
!   ;; multicharacter tokens that begin with "<".
!   t (c-make-keywords-re nil
!       (mapcan (lambda (op)
!               (if (string-match "\\`<." op)
!                   (list (substring op 1))))
!             (append (c-lang-const c-other-op-syntax-tokens)
!                     (c-lang-const c-operator-list)))))
! (c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp))
! 
! (c-lang-defconst c->-op-cont-regexp
!   ;; Regexp matching the second and subsequent characters of all
!   ;; multicharacter tokens that begin with ">".
!   t (c-make-keywords-re nil
!       (mapcan (lambda (op)
!               (if (string-match "\\`>." op)
!                   (list (substring op 1))))
!             (append (c-lang-const c-other-op-syntax-tokens)
!                     (c-lang-const c-operator-list)))))
! (c-lang-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp))
! 
! (c-lang-defconst 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 "?:".
!   t    "^;{}?:"
!   awk  "^;{}\n\r?:") ; The newline chars gets special treatment.
! (c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars))
! 
! (c-lang-defconst c-stmt-delim-chars-with-comma
!   ;; Variant of `c-stmt-delim-chars' that additionally contains ','.
!   t    "^;,{}?:"
!   awk  "^;,{}\n\r?:") ; The newline chars gets special treatment.
! (c-lang-defvar c-stmt-delim-chars-with-comma
!   (c-lang-const c-stmt-delim-chars-with-comma))
! 
! 
! ;;; Syntactic whitespace.
! 
! (c-lang-defconst c-comment-start-regexp
!   ;; Regexp to match the start of any type of comment.
!   ;;
!   ;; TODO: Ought to use `c-comment-prefix-regexp' with some
!   ;; modifications instead of this.
!   t    "/[/*]"
!   awk  "#")
! (c-lang-defvar c-comment-start-regexp (c-lang-const c-comment-start-regexp))
! 
! (c-lang-defconst c-literal-start-regexp
!   ;; Regexp to match the start of comments and string literals.
!   t (concat (c-lang-const c-comment-start-regexp)
!           "\\|"
!           (if (memq 'gen-string-delim c-emacs-features)
!               "\"|"
!             "\"")))
! (c-lang-defvar c-literal-start-regexp (c-lang-const c-literal-start-regexp))
! 
! (c-lang-defconst c-doc-comment-start-regexp
!   "Regexp to match the start of documentation comments."
!   t    "\\<\\>"
!   ;; From font-lock.el: `doxygen' uses /*! while others use /**.
!   (c c++ objc) "/\\*[*!]"
!   java "/\\*\\*"
!   pike "/[/*]!")
! (c-lang-defvar c-doc-comment-start-regexp
!   (c-lang-const c-doc-comment-start-regexp))
! 
! (c-lang-defconst comment-start
!   "String that starts comments inserted with M-; etc.
! `comment-start' is initialized from this."
!   t    "// "
!   c    "/* "
!   awk  "# ")
! (c-lang-defvar comment-start (c-lang-const comment-start)
!   'dont-doc)
! 
! (c-lang-defconst comment-end
!   "String that ends comments inserted with M-; etc.
! `comment-end' is initialized from this."
!   t    ""
!   c    " */")
! (c-lang-defvar comment-end (c-lang-const comment-end)
!   'dont-doc)
! 
! (c-lang-defconst comment-start-skip
!   "Regexp to match the start of a comment plus everything up to its body.
! `comment-start-skip' is initialized from this."
!   t    "/\\*+ *\\|//+ *"
!   awk  "#+ *")
! (c-lang-defvar comment-start-skip (c-lang-const comment-start-skip)
!   'dont-doc)
! 
! (c-lang-defconst c-syntactic-ws-start
!   "Regexp matching any sequence that can start syntactic whitespace.
! The only uncertain case is '#' when there are cpp directives."
!   t     "[ \n\t\r\v\f#]\\|/[/*]\\|\\\\[\n\r]"
!   awk   "[ \n\t\r\v\f#]\\|\\\\[\n\r]")
! (c-lang-defvar c-syntactic-ws-start (c-lang-const c-syntactic-ws-start)
!   'dont-doc)
! 
! (c-lang-defconst c-syntactic-ws-end
!   "Regexp matching any single character that might end syntactic whitespace."
!   t     "[ \n\t\r\v\f/]"
!   awk   "[ \n\t\r\v\f]")
! (c-lang-defvar c-syntactic-ws-end (c-lang-const c-syntactic-ws-end)
!   'dont-doc)
! 
! (c-lang-defconst c-nonwhite-syntactic-ws
!   ;; Regexp matching a piece of syntactic whitespace that isn't a
!   ;; sequence of simple whitespace characters.  As opposed to
!   ;; `c-(forward|backward)-syntactic-ws', this doesn't regard cpp
!   ;; directives as syntactic whitespace.
!   t (concat "/" (concat
!                "\\("
!                "/[^\n\r]*[\n\r]"      ; Line comment.
!                "\\|"
!                ;; Block comment. We intentionally don't allow line
!                ;; breaks in them to avoid going very far and risk
!                ;; running out of regexp stack; this regexp is
!                ;; intended to handle only short comments that
!                ;; might be put in the middle of limited constructs
!                ;; like declarations.
!                "\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*\\*/"
!                "\\)")
!           "\\|"
!           "\\\\[\n\r]")               ; Line continuations.
!   awk ("#.*[\n\r]\\|\\\\[\n\r]"))
! 
! (c-lang-defconst c-syntactic-ws
!   ;; Regexp matching syntactic whitespace, including possibly the
!   ;; empty string.  As opposed to `c-(forward|backward)-syntactic-ws',
!   ;; this doesn't regard cpp directives as syntactic whitespace.  Does
!   ;; not contain a \| operator at the top level.
!   t (concat "[ \t\n\r\f\v]*\\("
!           "\\(" (c-lang-const c-nonwhite-syntactic-ws) "\\)"
!           "[ \t\n\r\f\v]*\\)*"))
! 
! (c-lang-defconst c-syntactic-ws-depth
!   ;; Number of regexp grouping parens in `c-syntactic-ws'.
!   t (c-regexp-opt-depth (c-lang-const c-syntactic-ws)))
! 
! (c-lang-defconst c-nonempty-syntactic-ws
!   ;; Regexp matching syntactic whitespace, which is at least one
!   ;; character long.  As opposed to `c-(forward|backward)-syntactic-ws',
!   ;; this doesn't regard cpp directives as syntactic whitespace.  Does
!   ;; not contain a \| operator at the top level.
!   t (concat "\\([ \t\n\r\f\v]\\|"
!           (c-lang-const c-nonwhite-syntactic-ws)
!           "\\)+"))
! 
! (c-lang-defconst c-nonempty-syntactic-ws-depth
!   ;; Number of regexp grouping parens in `c-nonempty-syntactic-ws'.
!   t (c-regexp-opt-depth (c-lang-const c-nonempty-syntactic-ws)))
! 
! (c-lang-defconst c-single-line-syntactic-ws
!   ;; Regexp matching syntactic whitespace without any line breaks.  As
!   ;; opposed to `c-(forward|backward)-syntactic-ws', this doesn't
!   ;; regard cpp directives as syntactic whitespace.  Does not contain
!   ;; a \| operator at the top level.
!   t (concat "[ \t]*\\("
!           "/\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*\\*/" ; Block comment
!           "[ \t]*\\)*")
!   awk ("[ \t]*\\(#.*$\\)?"))
! 
! (c-lang-defconst c-single-line-syntactic-ws-depth
!   ;; Number of regexp grouping parens in `c-single-line-syntactic-ws'.
!   t (c-regexp-opt-depth (c-lang-const c-single-line-syntactic-ws)))
! 
! (c-lang-defvar c-syntactic-eol
!   ;; Regexp that matches when there is no syntactically significant
!   ;; text before eol.  Macros are regarded as syntactically
!   ;; significant text here.
!   (concat (concat
!          ;; Match horizontal whitespace and block comments that
!          ;; don't contain newlines.
!          "\\(\\s \\|"
!          (concat "/\\*"
!                  "\\([^*\n\r]\\|\\*[^/\n\r]\\)*"
!                  "\\*/")
!          "\\)*")
!         (concat
!          ;; Match eol (possibly inside a block comment or preceded
!          ;; by a line continuation backslash), 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]\\)*"
!                  "\\|"
!                  "\\\\"
!                  "\\)?"
!                  "$")
!          "\\|//\\)")))
! 
! 
! ;;; In-comment text handling.
! 
! (c-lang-defconst c-paragraph-start
!   "Regexp to append to `paragraph-start'."
!   t    "$"
!   java "\\(@[a-zA-Z]+\\>\\|$\\)"      ; For Javadoc.
!   pike "\\(@[a-zA-Z_-]+\\>\\([^{]\\|$\\)\\|$\\)") ; For Pike refdoc.
! (c-lang-defvar c-paragraph-start (c-lang-const c-paragraph-start))
! 
! (c-lang-defconst c-paragraph-separate
!   "Regexp to append to `paragraph-separate'."
!   t    "$"
!   pike (c-lang-const c-paragraph-start))
! (c-lang-defvar c-paragraph-separate (c-lang-const c-paragraph-separate))
! 
! 
! ;;; Keyword lists.
! 
! ;; Note: All and only all language constants containing keyword lists
! ;; should end with "-kwds"; they're automatically collected into the
! ;; `c-kwds-lang-consts' list below and used to build `c-keywords' etc.
  
  (c-lang-defconst c-primitive-type-kwds
!   "Primitive type keywords.  As opposed to the other keyword lists, the
! keywords listed here are fontified with the type face instead of the
! keyword face.
! 
! If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
! `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
! `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
! will be handled.
! 
! Do not try to modify this list for end user customizations; the
! `*-font-lock-extra-types' variable, where `*' is the mode prefix, is
! the appropriate place for that."
!   t    '("char" "double" "float" "int" "long" "short" "signed"
!        "unsigned" "void")
!   c    (append
!       '("_Bool" "_Complex" "_Imaginary") ; Conditionally defined in C99.
!       (c-lang-const c-primitive-type-kwds))
!   c++  (append
!       '("bool" "wchar_t")
!       (c-lang-const c-primitive-type-kwds))
!   ;; Objective-C extends C, but probably not the new stuff in C99.
!   objc (append
!       '("id" "Class" "SEL" "IMP" "BOOL")
!       (c-lang-const c-primitive-type-kwds))
    java '("boolean" "byte" "char" "double" "float" "int" "long" "short" "void")
!   idl  '("Object" "ValueBase" "any" "boolean" "char" "double" "fixed" "float"
!        "long" "octet" "sequence" "short" "string" "void" "wchar" "wstring"
!        ;; In CORBA PSDL:
!        "ref"
!        ;; The following can't really end a type, but we have to specify them
!        ;; here due to the assumption in `c-primitive-type-prefix-kwds'.  It
!        ;; doesn't matter that much.
!        "unsigned" "strong")
!   pike '(;; this_program isn't really a keyword, but it's practically
!        ;; used as a builtin type.
!        "array" "float" "function" "int" "mapping" "mixed" "multiset"
!        "object" "program" "string" "this_program" "void"))
! 
! (c-lang-defconst c-primitive-type-key
!   ;; An adorned regexp that matches `c-primitive-type-kwds'.
!   t (c-make-keywords-re t (c-lang-const c-primitive-type-kwds)))
! (c-lang-defvar c-primitive-type-key (c-lang-const c-primitive-type-key))
! 
! (c-lang-defconst c-primitive-type-prefix-kwds
!   "Keywords that might act as prefixes for primitive types.  Assumed to
! be a subset of `c-primitive-type-kwds'."
!   t       nil
!   (c c++) '("long" "short" "signed" "unsigned")
!   idl     '("long" "unsigned"
!           ;; In CORBA PSDL:
!           "strong"))
! 
! (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
! declarations.
! 
! Note that an alternative if the second part doesn't hold is
! `c-type-list-kwds'.  Keywords on this list are typically also present
! on one of the `*-decl-kwds' lists."
!   t    nil
!   c    '("struct" "union" "enum")
!   c++  (append '("class" "typename")
!              (c-lang-const c-type-prefix-kwds c)))
! 
! (c-lang-defconst c-type-prefix-key
!   ;; Adorned regexp matching `c-type-prefix-kwds'.
!   t (c-make-keywords-re t (c-lang-const c-type-prefix-kwds)))
! (c-lang-defvar c-type-prefix-key (c-lang-const c-type-prefix-key))
! 
! (c-lang-defconst c-type-modifier-kwds
!   "Type modifier keywords.  These can occur almost anywhere in types
! but they don't build a type of themselves.  Unlike the keywords on
! `c-primitive-type-kwds', they are fontified with the keyword face and
! not the type face."
!   t    nil
!   c    '("const" "restrict" "volatile")
!   c++  '("const" "volatile" "throw")
!   objc '("const" "volatile"))
! 
! (c-lang-defconst c-opt-type-modifier-key
!   ;; Adorned regexp matching `c-type-modifier-kwds', or nil in
!   ;; languages without such keywords.
!   t (and (c-lang-const c-type-modifier-kwds)
!        (c-make-keywords-re t (c-lang-const c-type-modifier-kwds))))
! (c-lang-defvar c-opt-type-modifier-key (c-lang-const c-opt-type-modifier-key))
! 
! (c-lang-defconst c-opt-type-component-key
!   ;; An adorned regexp that matches `c-primitive-type-prefix-kwds' and
!   ;; `c-type-modifier-kwds', or nil in languages without any of them.
!   t (and (or (c-lang-const c-primitive-type-prefix-kwds)
!            (c-lang-const c-type-modifier-kwds))
!        (c-make-keywords-re t
!          (append (c-lang-const c-primitive-type-prefix-kwds)
!                  (c-lang-const c-type-modifier-kwds)))))
! (c-lang-defvar c-opt-type-component-key
!   (c-lang-const c-opt-type-component-key))
! 
! (c-lang-defconst c-class-decl-kwds
!   "Keywords introducing declarations where the following block (if any)
! contains another declaration level that should be considered a class.
! 
! If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
! `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
! `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
! will be handled.
! 
! Note that presence on this list does not automatically treat the
! following identifier as a type; the keyword must also be present on
! `c-type-prefix-kwds' or `c-type-list-kwds' to accomplish that."
!   t    nil
!   c    '("struct" "union")
!   c++  '("class" "struct" "union")
!   objc '("struct" "union"
!        "@interface" "@implementation" "@protocol")
    java '("class" "interface")
!   idl  '("component" "eventtype" "exception" "home" "interface" "struct"
!        "union" "valuetype"
!        ;; In CORBA PSDL:
!        "storagehome" "storagetype"
!        ;; In CORBA CIDL:
!        "catalog" "executor" "manages" "segment")
    pike '("class"))
  
  (c-lang-defconst c-class-key
!   ;; Regexp matching the start of a class.
!   t (c-make-keywords-re t (c-lang-const c-class-decl-kwds)))
! (c-lang-defvar c-class-key (c-lang-const c-class-key))
! 
! (c-lang-defconst c-brace-list-decl-kwds
!   "Keywords introducing declarations where the following block (if
! any) is a brace list.
! 
! If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
! `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
! `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
! will be handled."
!   t    '("enum")
!   (java awk) nil)
! 
! (c-lang-defconst c-brace-list-key
!   ;; Regexp matching the start of declarations where the following
!   ;; block is a brace list.
!   t (c-make-keywords-re t (c-lang-const c-brace-list-decl-kwds)))
! (c-lang-defvar c-brace-list-key (c-lang-const c-brace-list-key))
! 
! (c-lang-defconst c-other-block-decl-kwds
!   "Keywords where the following block (if any) contain another
! declaration level that should not be considered a class.
! 
! If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
! `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
! `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
! will be handled."
!   t   nil
!   c   '("extern")
    c++ '("namespace" "extern")
!   idl '("module"
!       ;; In CORBA CIDL:
!       "composition"))
  
  (c-lang-defconst c-other-decl-block-key
!   ;; Regexp matching the start of blocks besides classes that contain
!   ;; another declaration level.
!   t (c-make-keywords-re t (c-lang-const c-other-block-decl-kwds)))
! (c-lang-defvar c-other-decl-block-key (c-lang-const c-other-decl-block-key))
! 
! (c-lang-defconst c-typedef-decl-kwds
!   "Keywords introducing declarations where the identifiers are defined
! to be types.
! 
! If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
! `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
! `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
! will be handled."
!   t    '("typedef")
!   (java awk) nil)
! 
! (c-lang-defconst c-typeless-decl-kwds
!   "Keywords introducing declarations where the identifier (declarator)
! list follows directly after the keyword, without any type.
! 
! If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
! `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
! `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
! will be handled."
!   t    nil
!   ;; Unlike most other languages, exception names are not handled as
!   ;; types in IDL since they only can occur in "raises" specs.
!   idl  '("exception" "factory" "finder" "native"
!        ;; In CORBA PSDL:
!        "key" "stores"
!        ;; In CORBA CIDL:
!        ;; Note that "manages" here clashes with its presence on
!        ;; `c-type-list-kwds' for IDL.
!        "executor" "facet" "manages" "segment")
!   pike '("constant"))
! 
! (c-lang-defconst c-modifier-kwds
!   "Keywords that can prefix normal declarations of identifiers
! \(and typically acts as flags).  Things like argument declarations
! inside function headers are also considered declarations in this
! sense.
! 
! If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
! `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
! `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))
!   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"
!        "in" "inout" "local" "multiple" "oneway" "out" "private" "provides"
!        "public" "publishes" "readonly" "typeid" "typeprefix" "uses"
!        ;; In CORBA PSDL:
!        "primary" "state"
!        ;; In CORBA CIDL:
!        "bindsTo" "delegatesTo" "implements" "proxy" "storedOn")
!   ;; Note: "const" is not used in Java, but it's still a reserved keyword.
!   java '("abstract" "const" "final" "native" "private" "protected" "public"
!        "static" "strictfp" "synchronized" "transient" "volatile")
!   pike '("final" "inline" "local" "nomask" "optional" "private" "protected"
!        "public" "static" "variant"))
! 
! (c-lang-defconst c-other-decl-kwds
!   "Keywords that can start or prefix any declaration level construct,
! besides those on `c-class-decl-kwds', `c-brace-list-decl-kwds',
! `c-other-block-decl-kwds', `c-typedef-decl-kwds',
! `c-typeless-decl-kwds' and `c-modifier-kwds'.  In a declaration, these
! keywords are also recognized inside or after the identifiers that
! makes up the type.
! 
! If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
! `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
! `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
! will be handled."
!   t       nil
!   (c c++) '("__declspec")             ; MSVC extension.
!   objc    '("@class" "@end" "@defs")
!   java    '("import" "package")
!   pike    '("import" "inherit"))
! 
! (c-lang-defconst c-specifier-key
!   ;; Adorned regexp matching keywords that can start a declaration but
!   ;; not a type.
!   t (c-make-keywords-re t
!       (set-difference (append (c-lang-const c-class-decl-kwds)
!                             (c-lang-const c-brace-list-decl-kwds)
!                             (c-lang-const c-other-block-decl-kwds)
!                             (c-lang-const c-typedef-decl-kwds)
!                             (c-lang-const c-typeless-decl-kwds)
!                             (c-lang-const c-modifier-kwds)
!                             (c-lang-const c-other-decl-kwds))
!                     (append (c-lang-const c-primitive-type-kwds)
!                             (c-lang-const c-type-prefix-kwds)
!                             (c-lang-const c-type-modifier-kwds))
!                     :test 'string-equal)))
! (c-lang-defvar c-specifier-key (c-lang-const c-specifier-key))
! 
! (c-lang-defconst c-protection-kwds
!   "Protection label keywords in classes."
!   t    nil
!   c++  '("private" "protected" "public")
!   objc '("@private" "@protected" "@public"))
! 
! (c-lang-defconst c-opt-access-key
!   ;; Regexp matching an access protection label in a class, or nil in
!   ;; languages that don't have such things.
!   t    (if (c-lang-const c-protection-kwds)
!          (c-make-keywords-re t (c-lang-const c-protection-kwds)))
!   c++  (concat "\\("
!              (c-make-keywords-re nil (c-lang-const c-protection-kwds))
!              "\\)[ \t\n\r\f\v]*:"))
! (c-lang-defvar c-opt-access-key (c-lang-const c-opt-access-key))
  
  (c-lang-defconst c-block-decls-with-vars
!   "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.
! 
! The keywords on list are assumed to also be present on one of the
! `*-decl-kwds' lists."
!   t        nil
!   (c objc) '("struct" "union" "enum" "typedef")
!   c++      '("class" "struct" "union" "enum" "typedef"))
  
  (c-lang-defconst c-opt-block-decls-with-vars-key
!   ;; Regexp matching the `c-block-decls-with-vars' keywords, or nil in
!   ;; languages without such constructs.
!   t (and (c-lang-const c-block-decls-with-vars)
!        (c-make-keywords-re t (c-lang-const c-block-decls-with-vars))))
  (c-lang-defvar c-opt-block-decls-with-vars-key
!   (c-lang-const c-opt-block-decls-with-vars-key))
  
! (c-lang-defconst c-postfix-decl-spec-kwds
!   "Keywords introducing extra declaration specifiers in the region
! between the header and the body \(i.e. the \"K&R-region\") in
! declarations."
!   t    nil
!   (c c++) '("__attribute__")          ; GCC extension.
!   java '("extends" "implements" "throws")
!   idl  '("context" "getraises" "manages" "primarykey" "raises" "setraises"
!        "supports"
!        ;; In CORBA PSDL:
!        "as" "const" "implements" "of" "ref"))
! 
! (c-lang-defconst c-nonsymbol-sexp-kwds
!   "Keywords that may be followed by a nonsymbol sexp before whatever
! construct it's part of continues."
!   t    nil
!   (c c++ objc) '("extern"))
! 
! (c-lang-defconst c-type-list-kwds
!   "Keywords that may be followed by a comma separated list of type
! identifiers, where each optionally can be prefixed by keywords.  (Can
! also be used for the special case when the list can contain only one
! element.)
! 
! Assumed to be mutually exclusive with `c-ref-list-kwds'.  There's no
! reason to put keywords on this list if they are on `c-type-prefix-kwds'.
! There's also no reason to add keywords that prefixes a normal
! declaration consisting of a type followed by a declarator (list), so
! the keywords on `c-modifier-kwds' should normally not be listed here
! too.
! 
! Note: Use `c-typeless-decl-kwds' for keywords followed by a function
! or variable identifier (that's being defined)."
!   t    '("struct" "union" "enum")
!   (c awk) nil
!   c++  '("operator")
!   objc (append '("@class" "@interface" "@implementation" "@protocol")
!              (c-lang-const c-type-list-kwds))
!   java '("class" "import" "interface" "new" "extends" "implements" "throws")
!   idl  (append '("component" "eventtype" "home" "interface" "manages" "native"
!                "primarykey" "supports" "valuetype"
!                ;; In CORBA PSDL:
!                "as" "implements" "of" "scope" "storagehome" "storagetype")
!              (c-lang-const c-type-list-kwds))
!   pike '("class" "enum" "inherit"))
! 
! (c-lang-defconst c-ref-list-kwds
!   "Keywords that may be followed by a comma separated list of
! reference (i.e. namespace/scope/module) identifiers, where each
! optionally can be prefixed by keywords.  (Can also be used for the
! special case when the list can contain only one element.)  Assumed to
! be mutually exclusive with `c-type-list-kwds'.
! 
! Note: Use `c-typeless-decl-kwds' for keywords followed by a function
! or variable identifier (that's being defined)."
!   t    nil
!   c++  '("namespace")
!   java '("package")
!   idl  '("import" "module"
!        ;; In CORBA CIDL:
!        "composition")
!   pike '("import"))
! 
! (c-lang-defconst c-colon-type-list-kwds
!   "Keywords that may be followed (not necessarily directly) by a colon
! and then a comma separated list of type identifiers, where each
! optionally can be prefixed by keywords.  (Can also be used for the
! special case when the list can contain only one element.)"
!   t    nil
!   c++  '("class" "struct")
!   idl  '("component" "eventtype" "home" "interface" "valuetype"
!        ;; In CORBA PSDL:
!        "storagehome" "storagetype"))
! 
! (c-lang-defconst c-colon-type-list-re
!   "Regexp matched after the keywords in `c-colon-type-list-kwds' to skip
! forward to the colon.  The end of the match is assumed to be directly
! after the colon, so the regexp should end with \":\" although that
! isn't necessary.  Must be a regexp if `c-colon-type-list-kwds' isn't
! nil."
!   t (if (c-lang-const c-colon-type-list-kwds)
!       ;; Disallow various common punctuation chars that can't come
!       ;; before the ":" that starts the inherit list after "class"
!       ;; or "struct" in C++.  (Also used as default for other
!       ;; languages.)
!       "[^\]\[{}();,/#=:]*:"))
! (c-lang-defvar c-colon-type-list-re (c-lang-const c-colon-type-list-re))
! 
! (c-lang-defconst c-paren-nontype-kwds
!   "Keywords that may be followed by a parenthesis expression that doesn't
! contain type identifiers."
!   t       nil
!   (c c++) '("__declspec"))            ; MSVC extension.
! 
! (c-lang-defconst c-paren-type-kwds
!   "Keywords that may be followed by a parenthesis expression containing
! type identifiers separated by arbitrary tokens."
!   t    nil
!   c++  '("throw")
!   objc '("@defs")
!   idl  '("switch")
!   pike '("array" "function" "int" "mapping" "multiset" "object" "program"))
! 
! (c-lang-defconst c-paren-any-kwds
!   t (delete-duplicates (append (c-lang-const c-paren-nontype-kwds)
!                              (c-lang-const c-paren-type-kwds))
!                      :test 'string-equal))
! 
! (c-lang-defconst c-<>-type-kwds
!   "Keywords that may be followed by an angle bracket expression
! containing type identifiers separated by \",\".  The difference from
! `c-<>-arglist-kwds' is that unknown names are taken to be types and
! not other identifiers.  `c-recognize-<>-arglists' is assumed to be set
! if this isn't nil."
!   t    nil
!   objc '("id")
!   idl  '("sequence"
!        ;; In CORBA PSDL:
!        "ref"))
! 
! (c-lang-defconst c-<>-arglist-kwds
!   "Keywords that can be followed by a C++ style template arglist; see
! `c-recognize-<>-arglists' for details.  That language constant is
! assumed to be set if this isn't nil."
!   t    nil
!   c++  '("template")
!   idl  '("fixed" "string" "wstring"))
! 
! (c-lang-defconst c-<>-sexp-kwds
!   ;; All keywords that can be followed by an angle bracket sexp.
!   t (delete-duplicates (append (c-lang-const c-<>-type-kwds)
!                              (c-lang-const c-<>-arglist-kwds))
!                      :test 'string-equal))
! 
! (c-lang-defconst c-opt-<>-sexp-key
!   ;; Adorned regexp matching keywords that can be followed by an angle
!   ;; bracket sexp.  Always set when `c-recognize-<>-arglists' is.
!   t (if (c-lang-const c-recognize-<>-arglists)
!       (c-make-keywords-re t (c-lang-const c-<>-sexp-kwds))))
! (c-lang-defvar c-opt-<>-sexp-key (c-lang-const c-opt-<>-sexp-key))
! 
! (c-lang-defconst c-brace-id-list-kwds
!   "Keywords that may be followed by a brace block containing a comma
! separated list of identifier definitions, i.e. like the list of
! identifiers that follows the type in a normal declaration."
!   t (c-lang-const c-brace-list-decl-kwds))
  
  (c-lang-defconst c-block-stmt-1-kwds
!   "Statement keywords followed directly by a substatement."
!   t    '("do" "else")
!   c++  '("do" "else" "try")
!   java '("do" "else" "finally" "try")
!   idl  nil)
  
  (c-lang-defconst c-block-stmt-1-key
!   ;; Regexp matching the start of any statement followed directly by a
!   ;; substatement (doesn't match a bare block, however).
!   t (c-make-keywords-re t (c-lang-const c-block-stmt-1-kwds)))
! (c-lang-defvar c-block-stmt-1-key (c-lang-const c-block-stmt-1-key))
  
  (c-lang-defconst c-block-stmt-2-kwds
!   "Statement keywords followed by a paren sexp and then by a substatement."
!   t    '("for" "if" "switch" "while")
!   c++  '("for" "if" "switch" "while" "catch")
    java '("for" "if" "switch" "while" "catch" "synchronized")
!   idl  nil
!   pike '("for" "if" "switch" "while" "foreach")
!   awk  '("for" "if" "while"))
  
  (c-lang-defconst c-block-stmt-2-key
!   ;; Regexp matching the start of any statement followed by a paren sexp
!   ;; and then by a substatement.
!   t (c-make-keywords-re t (c-lang-const c-block-stmt-2-kwds)))
! (c-lang-defvar c-block-stmt-2-key (c-lang-const c-block-stmt-2-key))
  
  (c-lang-defconst c-opt-block-stmt-key
!   ;; Regexp matching the start of any statement that has a
!   ;; substatement (except a bare block).  Nil in languages that
!   ;; don't have such constructs.
!   t (if (or (c-lang-const c-block-stmt-1-kwds)
!           (c-lang-const c-block-stmt-2-kwds))
!       (c-make-keywords-re t
!         (append (c-lang-const c-block-stmt-1-kwds)
!                 (c-lang-const c-block-stmt-2-kwds)))))
! (c-lang-defvar c-opt-block-stmt-key (c-lang-const c-opt-block-stmt-key))
  
  (c-lang-defconst c-simple-stmt-kwds
!   "Statement keywords followed by an expression or nothing."
!   t    '("break" "continue" "goto" "return")
    ;; Note: `goto' is not valid in Java, but the keyword is still reserved.
    java '("break" "continue" "goto" "return" "throw")
!   idl  nil
!   pike '("break" "continue" "return")
!   awk  '(;; Not sure about "delete", "exit", "getline", etc. ; ACM 2002/5/30
!        "break" "continue" "return" "delete" "exit" "getline" "next"
!        "nextfile" "print" "printf"))
! 
! (c-lang-defconst c-simple-stmt-key
!   ;; Adorned regexp matching `c-simple-stmt-kwds'.
!   t (c-make-keywords-re t (c-lang-const c-simple-stmt-kwds)))
! (c-lang-defvar c-simple-stmt-key (c-lang-const c-simple-stmt-key))
! 
! (c-lang-defconst c-paren-stmt-kwds
!   "Statement keywords followed by a parenthesis expression that
! nevertheless contains a list separated with ';' and not ','."
!   t    '("for")
!   idl  nil)
! 
! (c-lang-defconst c-paren-stmt-key
!   ;; Adorned regexp matching `c-paren-stmt-kwds'.
!   t (c-make-keywords-re t (c-lang-const c-paren-stmt-kwds)))
! (c-lang-defvar c-paren-stmt-key (c-lang-const c-paren-stmt-key))
  
  (c-lang-defconst c-asm-stmt-kwds
!   "Statement keywords followed by an assembler expression."
!   t nil
!   (c c++) '("asm" "__asm__")) ;; Not standard, but common.
  
  (c-lang-defconst c-opt-asm-stmt-key
!   ;; Regexp matching the start of an assembler statement.  Nil in
!   ;; languages that don't support that.
!   t (if (c-lang-const c-asm-stmt-kwds)
!       (c-make-keywords-re t (c-lang-const c-asm-stmt-kwds))))
! (c-lang-defvar c-opt-asm-stmt-key (c-lang-const c-opt-asm-stmt-key))
! 
! (c-lang-defconst c-label-kwds
!   "Keywords introducing labels in blocks."
!   t '("case" "default")
!   awk nil)
! 
! (c-lang-defconst c-before-label-kwds
!   "Keywords that might be followed by a label identifier."
!   t    '("goto")
!   (java pike) (append '("break" "continue")
!                     (c-lang-const c-before-label-kwds))
!   idl  nil
!   awk  nil)
  
  (c-lang-defconst c-label-kwds-regexp
!   ;; Regexp matching any keyword that introduces a label.
!   t (c-make-keywords-re t (c-lang-const c-label-kwds)))
! (c-lang-defvar c-label-kwds-regexp (c-lang-const c-label-kwds-regexp))
! 
! (c-lang-defconst c-constant-kwds
!   "Keywords for constants."
!   t       nil
!   (c c++) '("NULL" ;; Not a keyword, but practically works as one.
!           "false" "true")             ; Defined in C99.
!   objc    '("nil" "Nil")
!   idl     '("TRUE" "FALSE")
!   pike    '("UNDEFINED")) ;; Not a keyword, but practically works as one.
! 
! (c-lang-defconst c-primary-expr-kwds
!   "Keywords besides constants and operators that start primary expressions."
!   t    nil
!   c++  '("operator" "this")
!   objc '("super" "self")
!   java '("this")
!   pike '("this")) ;; Not really a keyword, but practically works as one.
  
  (c-lang-defconst c-expr-kwds
!   ;; Keywords that can occur anywhere in expressions.  Built from
!   ;; `c-primary-expr-kwds' and all keyword operators in `c-operators'.
!   t (delete-duplicates
!      (append (c-lang-const c-primary-expr-kwds)
!            (c-with-syntax-table (c-lang-const c-mode-syntax-table)
!              (mapcan (lambda (op)
!                        (and (string-match "\\`\\(\\w\\|\\s_\\)+\\'" op)
!                             (list op)))
!                      (c-lang-const c-operator-list))))
!      :test 'string-equal))
! 
! (c-lang-defconst c-lambda-kwds
!   "Keywords that start lambda constructs, i.e. function definitions in
! expressions."
!   t    nil
!   pike '("lambda"))
  
  (c-lang-defconst c-opt-lambda-key
!   ;; Adorned regexp matching the start of lambda constructs, or nil in
!   ;; languages that don't have such things.
!   t (and (c-lang-const c-lambda-kwds)
!        (c-make-keywords-re t (c-lang-const c-lambda-kwds))))
! (c-lang-defvar c-opt-lambda-key (c-lang-const c-opt-lambda-key))
! 
! (c-lang-defconst c-inexpr-block-kwds
!   "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)."
!   t    nil
!   pike '("catch" "gauge"))
  
  (c-lang-defconst c-opt-inexpr-block-key
!   ;; Regexp matching the start of in-expression statements, or nil in
!   ;; languages that don't have such things.
!   t    nil
!   pike (c-make-keywords-re t (c-lang-const c-inexpr-block-kwds)))
! (c-lang-defvar c-opt-inexpr-block-key (c-lang-const c-opt-inexpr-block-key))
  
  (c-lang-defconst c-inexpr-class-kwds
+   "Keywords that can start classes inside expressions."
+   t    nil
    java '("new")
    pike '("class"))
  
  (c-lang-defconst c-opt-inexpr-class-key
!   ;; Regexp matching the start of a class in an expression, or nil in
!   ;; languages that don't have such things.
!   t (and (c-lang-const c-inexpr-class-kwds)
!        (c-make-keywords-re t (c-lang-const c-inexpr-class-kwds))))
! (c-lang-defvar c-opt-inexpr-class-key (c-lang-const c-opt-inexpr-class-key))
! 
! (c-lang-defconst c-inexpr-brace-list-kwds
!   "Keywords that can start brace list blocks inside expressions.
! Note that Java specific rules are currently applied to tell this from
! `c-inexpr-class-kwds'."
!   t    nil
!   java '("new"))
! 
! (c-lang-defconst c-opt-inexpr-brace-list-key
!   ;; Regexp matching the start of a brace list in an expression, or
!   ;; nil in languages that don't have such things.  This should not
!   ;; match brace lists recognized through `c-special-brace-lists'.
!   t (and (c-lang-const c-inexpr-brace-list-kwds)
!        (c-make-keywords-re t (c-lang-const c-inexpr-brace-list-kwds))))
! (c-lang-defvar c-opt-inexpr-brace-list-key
!   (c-lang-const c-opt-inexpr-brace-list-key))
  
  (c-lang-defconst c-any-class-key
!   ;; Regexp matching the start of any class, both at top level and in
!   ;; expressions.
!   t (c-make-keywords-re t
!       (append (c-lang-const c-class-decl-kwds)
!             (c-lang-const c-inexpr-class-kwds))))
! (c-lang-defvar c-any-class-key (c-lang-const c-any-class-key))
! 
  (c-lang-defconst c-decl-block-key
!   ;; Regexp matching the start of any declaration-level block that
!   ;; contain another declaration level, i.e. that isn't a function
!   ;; block or brace list.
!   t (c-make-keywords-re t
!       (append (c-lang-const c-class-decl-kwds)
!             (c-lang-const c-other-block-decl-kwds)
!             (c-lang-const c-inexpr-class-kwds)))
!   ;; In Pike modifiers might be followed by a block
!   ;; to apply to several declarations.
!   pike (concat (c-lang-const c-decl-block-key)
!              "\\|"
!              "\\(" (c-make-keywords-re nil
!                      (c-lang-const c-modifier-kwds)) "\\)"
!              (c-lang-const c-syntactic-ws)
!              "{"))
! (c-lang-defvar c-decl-block-key (c-lang-const c-decl-block-key))
  
  (c-lang-defconst c-bitfield-kwds
!   "Keywords that can introduce bitfields."
!   t nil
!   (c c++ objc) '("char" "int" "long" "signed" "unsigned"))
  
  (c-lang-defconst c-opt-bitfield-key
!   ;; Regexp matching the start of a bitfield (not uniquely), or nil in
!   ;; languages without bitfield support.
!   t       nil
!   (c c++) (c-make-keywords-re t (c-lang-const c-bitfield-kwds)))
! (c-lang-defvar c-opt-bitfield-key (c-lang-const c-opt-bitfield-key))
! 
! (c-lang-defconst c-other-kwds
!   "Keywords not accounted for by any other `*-kwds' language constant."
!   t    nil
!   idl  '("truncatable"
!        ;; In CORBA CIDL: (These are declaration keywords that never
!        ;; can start a declaration.)
!        "entity" "process" "service" "session" "storage"))
! 
! 
! ;;; Constants built from keywords.
! 
! ;; Note: No `*-kwds' language constants may be defined below this point.
! 
! (eval-and-compile
!   (defconst c-kwds-lang-consts
!     ;; List of all the language constants that contain keyword lists.
!     (let (list)
!       (mapatoms (lambda (sym)
!                 (when (and (boundp sym)
!                            (string-match "-kwds\\'" (symbol-name sym)))
!                   ;; Make the list of globally interned symbols
!                   ;; instead of ones interned in `c-lang-constants'.
!                   (setq list (cons (intern (symbol-name sym)) list))))
!               c-lang-constants)
!       list)))
  
  (c-lang-defconst c-keywords
!   ;; All keywords as a list.
!   t (delete-duplicates
!      (c-lang-defconst-eval-immediately
!       `(append ,@(mapcar (lambda (kwds-lang-const)
!                          `(c-lang-const ,kwds-lang-const))
!                        c-kwds-lang-consts)
!              nil))
!      :test 'string-equal))
  
  (c-lang-defconst c-keywords-regexp
!   ;; All keywords as an adorned regexp.
!   t (c-make-keywords-re t (c-lang-const c-keywords)))
! (c-lang-defvar c-keywords-regexp (c-lang-const c-keywords-regexp))
! 
! (c-lang-defconst c-keyword-member-alist
!   ;; An alist with all the keywords in the cars.  The cdr for each
!   ;; keyword is a list of the symbols for the `*-kwds' lists that
!   ;; contains it.
!   t (let ((kwd-list-alist
!          (c-lang-defconst-eval-immediately
!           `(list ,@(mapcar (lambda (kwds-lang-const)
!                              `(cons ',kwds-lang-const
!                                     (c-lang-const ,kwds-lang-const)))
!                            c-kwds-lang-consts))))
!         lang-const kwd-list kwd
!         result-alist elem)
!       (while kwd-list-alist
!       (setq lang-const (caar kwd-list-alist)
!             kwd-list (cdar kwd-list-alist)
!             kwd-list-alist (cdr kwd-list-alist))
!       (while kwd-list
!         (setq kwd (car kwd-list)
!               kwd-list (cdr kwd-list))
!         (unless (setq elem (assoc kwd result-alist))
!           (setq result-alist (cons (setq elem (list kwd)) result-alist)))
!         (unless (memq lang-const (cdr elem))
!           (setcdr elem (cons lang-const (cdr elem))))))
!       result-alist))
! 
! (c-lang-defvar c-keywords-obarray
!   ;; An obarray containing all keywords as symbols.  The property list
!   ;; of each symbol has a non-nil entry for the specific `*-kwds'
!   ;; lists it's a member of.
!   ;;
!   ;; E.g. to see whether the string str contains a keyword on
!   ;; `c-class-decl-kwds', one can do like this:
!   ;;     (get (intern-soft str c-keyword-obarray) 'c-class-decl-kwds)
!   ;; Which preferably is written using the associated functions in
!   ;; cc-engine:
!   ;;     (c-keyword-member (c-keyword-sym str) 'c-class-decl-kwds)
! 
!   ;; The obarray is not stored directly as a language constant since
!   ;; the printed representation for obarrays used in .elc files isn't
!   ;; complete.
! 
!   (let* ((alist (c-lang-const c-keyword-member-alist))
!        kwd lang-const-list
!        (obarray (make-vector (* (length alist) 2) 0)))
!     (while alist
!       (setq kwd (caar alist)
!           lang-const-list (cdar alist)
!           alist (cdr alist))
!       (setplist (intern kwd obarray)
!               ;; Emacs has an odd bug that causes `mapcan' to fail
!               ;; with unintelligible errors.  (XEmacs >= 20 works.)
!               ;;(mapcan (lambda (lang-const)
!               ;;            (list lang-const t))
!               ;;          lang-const-list)
!               (apply 'nconc (mapcar (lambda (lang-const)
!                                       (list lang-const t))
!                                     lang-const-list))))
!     obarray))
! 
! (c-lang-defconst c-regular-keywords-regexp
!   ;; Adorned regexp matching all keywords that aren't types or
!   ;; constants.
!   t (c-make-keywords-re t
!       (set-difference (c-lang-const c-keywords)
!                     (append (c-lang-const c-primitive-type-kwds)
!                             (c-lang-const c-constant-kwds))
!                     :test 'string-equal)))
! (c-lang-defvar c-regular-keywords-regexp
!   (c-lang-const c-regular-keywords-regexp))
! 
! (c-lang-defconst c-not-decl-init-keywords
!   ;; Adorned regexp matching all keywords that can't appear at the
!   ;; start of a declaration.
!   t (c-make-keywords-re t
!       (set-difference (c-lang-const c-keywords)
!                     (append (c-lang-const c-primitive-type-kwds)
!                             (c-lang-const c-type-prefix-kwds)
!                             (c-lang-const c-type-modifier-kwds)
!                             (c-lang-const c-class-decl-kwds)
!                             (c-lang-const c-brace-list-decl-kwds)
!                             (c-lang-const c-other-block-decl-kwds)
!                             (c-lang-const c-typedef-decl-kwds)
!                             (c-lang-const c-typeless-decl-kwds)
!                             (c-lang-const c-modifier-kwds)
!                             (c-lang-const c-other-decl-kwds))
!                     :test 'string-equal)))
! (c-lang-defvar c-not-decl-init-keywords
!   (c-lang-const c-not-decl-init-keywords))
! 
! (c-lang-defconst c-primary-expr-regexp
!   ;; Regexp matching the start of any primary expression, i.e. any
!   ;; literal, symbol, prefix operator, and '('.  It doesn't need to
!   ;; exclude keywords; they are excluded afterwards unless the second
!   ;; submatch matches. If the first but not the second submatch
!   ;; matches then it is an ambiguous primary expression; it could also
!   ;; be a match of e.g. an infix operator. (The case with ambiguous
!   ;; keyword operators isn't handled.)
! 
!   t (c-with-syntax-table (c-lang-const c-mode-syntax-table)
!       (let* ((prefix-ops
!             (mapcan (lambda (op)
!                       ;; Filter out the special case prefix
!                       ;; operators that are close parens.
!                       (unless (string-match "\\s\)" op)
!                         (list op)))
!                     (mapcan
!                      (lambda (opclass)
!                        (when (eq (car opclass) 'prefix)
!                          (append (cdr opclass) nil)))
!                      (c-lang-const c-operators))))
! 
!            (nonkeyword-prefix-ops
!             (mapcan (lambda (op)
!                       (unless (string-match "\\`\\(\\w\\|\\s_\\)+\\'" op)
!                         (list op)))
!                     prefix-ops))
! 
!            (in-or-postfix-ops
!             (mapcan (lambda (opclass)
!                       (when (memq (car opclass)
!                                   '(postfix
!                                     left-assoc
!                                     right-assoc
!                                     right-assoc-sequence))
!                         (append (cdr opclass) nil)))
!                     (c-lang-const c-operators)))
! 
!            (unambiguous-prefix-ops (set-difference nonkeyword-prefix-ops
!                                                    in-or-postfix-ops
!                                                    :test 'string-equal))
!            (ambiguous-prefix-ops (intersection nonkeyword-prefix-ops
!                                                in-or-postfix-ops
!                                                :test 'string-equal)))
! 
!       (concat
!        "\\("
!        ;; Take out all symbol class operators from `prefix-ops' and make the
!        ;; first submatch from them together with `c-primary-expr-kwds'.
!        (c-make-keywords-re t
!          (append (c-lang-const c-primary-expr-kwds)
!                  (set-difference prefix-ops nonkeyword-prefix-ops
!                                  :test 'string-equal)))
! 
!        "\\|"
!        ;; Match all ambiguous operators.
!        (c-make-keywords-re nil
!          (intersection nonkeyword-prefix-ops in-or-postfix-ops
!                        :test 'string-equal))
!        "\\)"
! 
!        "\\|"
!        ;; Now match all other symbols.
!        (c-lang-const c-symbol-start)
! 
!        "\\|"
!        ;; The chars that can start integer and floating point
!        ;; constants.
!        "\\.?[0-9]"
! 
!        "\\|"
!        ;; The nonambiguous operators from `prefix-ops'.
!        (c-make-keywords-re nil
!          (set-difference nonkeyword-prefix-ops in-or-postfix-ops
!                          :test 'string-equal))
! 
!        "\\|"
!        ;; Match string and character literals.
!        "\\s\""
!        (if (memq 'gen-string-delim c-emacs-features)
!            "\\|\\s|"
!          "")))))
! (c-lang-defvar c-primary-expr-regexp (c-lang-const c-primary-expr-regexp))
  
! 
! ;;; Additional constants for parser-level constructs.
  
! (c-lang-defconst c-decl-prefix-re
!   "Regexp matching something that might precede a declaration or a cast,
! such as the last token of a preceding statement or declaration.  It
! should not match bob, though.  It can't require a match longer than
! one token.  The end of the token is taken to be at the end of the
! first submatch.  It must not include any following whitespace.  It's
! undefined whether identifier syntax (see `c-identifier-syntax-table')
! is in effect or not."
!   ;; We match a sequence of characters to skip over things like \"};\"
!   ;; more quickly.  We match ")" in C for K&R region declarations, and
!   ;; in all languages except Java for when a cpp macro definition
!   ;; begins with a declaration.
!   t "\\([\{\}\(\);,]+\\)"
!   java "\\([\{\}\(;,]+\\)"
!   ;; Match "<" in C++ to get the first argument in a template arglist.
!   ;; In that case there's an additional check in `c-find-decl-spots'
!   ;; that it got open paren syntax.
!   ;;
!   ;; Also match a single ":" for protection labels.  We cheat a little
!   ;; and require a symbol immediately before to avoid false matches
!   ;; when starting directly on a single ":", which can be the start of
!   ;; the base class initializer list in a constructor.
!   c++ "\\([\{\}\(\);,<]+\\|\\(\\w\\|\\s_\\):\\)\\([^:]\\|\\'\\)"
!   ;; Additionally match the protection directives in Objective-C.
!   ;; Note that this doesn't cope with the longer directives, which we
!   ;; would have to match from start to end since they don't end with
!   ;; any easily recognized characters.
!   objc (concat "\\([\{\}\(\);,]+\\|"
!              (c-make-keywords-re nil (c-lang-const c-protection-kwds))
!              "\\)")
!   ;; Match ":" for switch labels inside union declarations in IDL.
!   idl "\\([\{\}\(\);:,]+\\)\\([^:]\\|\\'\\)"
!   ;; Pike is like C but we also match "[" for multiple value
!   ;; assignments and type casts.
!   pike "\\([\{\}\(\)\[;,]+\\)")
! (c-lang-defvar c-decl-prefix-re (c-lang-const c-decl-prefix-re)
!   'dont-doc)
! 
! (c-lang-defconst c-cast-parens
!   ;; List containing the paren characters that can open a cast, or nil in
!   ;; languages without casts.
!   t (c-with-syntax-table (c-lang-const c-mode-syntax-table)
!       (mapcan (lambda (opclass)
!               (when (eq (car opclass) 'prefix)
!                 (mapcan (lambda (op)
!                           (when (string-match "\\`\\s\(\\'" op)
!                             (list (elt op 0))))
!                         (cdr opclass))))
!             (c-lang-const c-operators))))
! (c-lang-defvar c-cast-parens (c-lang-const c-cast-parens))
! 
! (c-lang-defconst c-type-decl-prefix-key
!   "Regexp matching the operators that might precede the identifier in a
! declaration, e.g. the \"*\" in \"char *argv\".  This regexp should
! match \"(\" if parentheses are valid in type declarations.  The end of
! the first submatch is taken as the end of the operator.  Identifier
! syntax is in effect when this is matched (see `c-identifier-syntax-table')."
!   t (if (c-lang-const c-type-modifier-kwds)
!       (concat (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>")
!       ;; Default to a regexp that never matches.
!       "\\<\\>")
!   (c objc) (concat "\\("
!                  "[*\(]"
!                  "\\|"
!                  (c-lang-const c-type-decl-prefix-key)
!                  "\\)"
!                  "\\([^=]\\|$\\)")
!   c++  (concat "\\("
!              "[*\(&]"
!              "\\|"
!              (concat "\\("    ; 2
!                      ;; If this matches there's special treatment in
!                      ;; `c-font-lock-declarators' and
!                      ;; `c-font-lock-declarations' that check for a
!                      ;; complete name followed by ":: *".
!                      (c-lang-const c-identifier-start)
!                      "\\)")
!              "\\|"
!              (c-lang-const c-type-decl-prefix-key)
!              "\\)"
!              "\\([^=]\\|$\\)")
!   pike "\\([*\(!~]\\)\\([^=]\\|$\\)")
! (c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key)
!   'dont-doc)
! 
! (c-lang-defconst c-type-decl-suffix-key
!   "Regexp matching the operators that might follow after the identifier
! in a declaration, e.g. the \"[\" in \"char argv[]\".  This regexp
! should match \")\" if parentheses are valid in type declarations.  If
! it matches an open paren of some kind, the type declaration check
! continues at the corresponding close paren, otherwise the end of the
! first submatch is taken as the end of the operator.  Identifier syntax
! is in effect when this is matched (see `c-identifier-syntax-table')."
!   ;; Default to a regexp that matches `c-type-modifier-kwds' and a
!   ;; function argument list parenthesis.
!   t    (if (c-lang-const c-type-modifier-kwds)
!          (concat "\\(\(\\|"
!                  (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>"
!                  "\\)")
!        "\\(\(\\)")
!   (c c++ objc) (concat
!               "\\("
!               "[\)\[\(]"
!               "\\|"
!               ;; "throw" in `c-type-modifier-kwds' is followed by a
!               ;; parenthesis list, but no extra measures are
!               ;; necessary to handle that.
!               (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>"
!               "\\)")
!   (java idl) "\\([\[\(]\\)")
! (c-lang-defvar c-type-decl-suffix-key (c-lang-const c-type-decl-suffix-key)
!   'dont-doc)
! 
! (c-lang-defconst c-after-suffixed-type-decl-key
!   "This regexp is matched after a type declaration expression where
! `c-type-decl-suffix-key' has matched.  If it matches then the
! construct is taken as a declaration.  It's typically used to match the
! beginning of a function body or whatever might occur after the
! function header in a function declaration or definition.  It's
! undefined whether identifier syntax (see `c-identifier-syntax-table')
! is in effect or not.
! 
! Note that it's used in cases like after \"foo (bar)\" so it should
! only match when it's certain that it's a declaration, e.g \"{\" but
! not \",\" or \";\"."
!   t "{"
!   ;; If K&R style declarations should be recognized then one could
!   ;; consider to match the start of any symbol since we want to match
!   ;; the start of the first declaration in the "K&R region".  That
!   ;; could however produce false matches on code like "FOO(bar) x"
!   ;; where FOO is a cpp macro, so it's better to leave it out and rely
!   ;; on the other heuristics in that case.
!   t (if (c-lang-const c-postfix-decl-spec-kwds)
!       ;; Add on the keywords in `c-postfix-decl-spec-kwds'.
!       (concat (c-lang-const c-after-suffixed-type-decl-key)
!               "\\|"
!               (c-make-keywords-re t (c-lang-const c-postfix-decl-spec-kwds)))
!       (c-lang-const c-after-suffixed-type-decl-key))
!   ;; Also match the colon that starts a base class initializer list in
!   ;; C++.  That can be confused with a function call before the colon
!   ;; in a ? : operator, but we count on that `c-decl-prefix-re' won't
!   ;; match before such a thing (as a declaration-level construct;
!   ;; matches inside arglist contexts are already excluded).
!   c++ "[{:]")
! (c-lang-defvar c-after-suffixed-type-decl-key
!   (c-lang-const c-after-suffixed-type-decl-key)
!   'dont-doc)
! 
! (c-lang-defconst c-after-suffixed-type-maybe-decl-key
!   ;; Regexp that in addition to `c-after-suffixed-type-decl-key'
!   ;; matches ";" and ",".
!   t (concat "\\(" (c-lang-const c-after-suffixed-type-decl-key) "\\)"
!           "\\|[;,]"))
! (c-lang-defvar c-after-suffixed-type-maybe-decl-key
!   (c-lang-const c-after-suffixed-type-maybe-decl-key))
! 
! (c-lang-defconst c-opt-type-concat-key
!   "Regexp matching operators that concatenate types, e.g. the \"|\" in
! \"int|string\" in Pike.  The end of the first submatch is taken as the
! end of the operator.  nil in languages without such operators.  It's
! undefined whether identifier syntax (see `c-identifier-syntax-table')
! is in effect or not."
!   t nil
!   pike "\\([|.&]\\)\\($\\|[^|.&]\\)")
! (c-lang-defvar c-opt-type-concat-key (c-lang-const c-opt-type-concat-key)
!   'dont-doc)
! 
! (c-lang-defconst c-opt-type-suffix-key
!   "Regexp matching operators that might follow after a type, or nil in
! languages that don't have such operators.  The end of the first
! submatch is taken as the end of the operator.  This should not match
! things like C++ template arglists if `c-recognize-<>-arglists' is set.
! It's undefined whether identifier syntax (see `c-identifier-syntax-table')
! is in effect or not."
!   t nil
!   (c c++ objc pike) "\\(\\.\\.\\.\\)"
!   java "\\(\\[[ \t\n\r\f\v]*\\]\\)")
! (c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key))
! 
! (c-lang-defvar c-known-type-key
!   ;; Regexp matching the known type identifiers.  This is initialized
!   ;; from the type keywords and `*-font-lock-extra-types'.  The first
!   ;; submatch is the one that matches the type.  Note that this regexp
!   ;; assumes that symbol constituents like '_' and '$' have word
!   ;; syntax.
!   (let ((extra-types (when (boundp (c-mode-symbol "font-lock-extra-types"))
!                        (c-mode-var "font-lock-extra-types"))))
!     (concat "\\<\\("
!           (c-make-keywords-re nil (c-lang-const c-primitive-type-kwds))
!           (if (consp extra-types)
!               (concat "\\|" (mapconcat 'identity extra-types "\\|"))
!             "")
!           "\\)\\>")))
! 
! (c-lang-defconst c-special-brace-lists
! "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."
!   t    nil
!   pike '((?{ . ?}) (?\[ . ?\]) (?< . ?>)))
! (c-lang-defvar c-special-brace-lists (c-lang-const c-special-brace-lists))
! 
! (c-lang-defconst c-recognize-knr-p
!   "Non-nil means K&R style argument declarations are valid."
!   t nil
!   c t)
! (c-lang-defvar c-recognize-knr-p (c-lang-const c-recognize-knr-p))
! 
! (c-lang-defconst c-recognize-typeless-decls
!   "Non-nil means function declarations without return type should be
! recognized.  That can introduce an ambiguity with parenthesized macro
! calls before a brace block.  This setting does not affect declarations
! that are preceded by a declaration starting keyword, so
! e.g. `c-typeless-decl-kwds' may still be used when it's set to nil."
!   t nil
!   (c c++ objc) t)
! (c-lang-defvar c-recognize-typeless-decls
!   (c-lang-const c-recognize-typeless-decls))
! 
! (c-lang-defconst c-recognize-<>-arglists
!   "Non-nil means C++ style template arglists should be handled.  More
! specifically, this means a comma separated list of types or
! expressions surrounded by \"<\" and \">\".  It's always preceded by an
! identifier or one of the keywords on `c-<>-type-kwds' or
! `c-<>-arglist-kwds'.  If there's an identifier before then the whole
! expression is considered to be a type."
!   t (or (consp (c-lang-const c-<>-type-kwds))
!       (consp (c-lang-const c-<>-arglist-kwds))))
! (c-lang-defvar c-recognize-<>-arglists (c-lang-const c-recognize-<>-arglists))
! 
! (c-lang-defconst c-recognize-paren-inits
!   "Non-nil means that parenthesis style initializers exist,
! i.e. constructs like
! 
! Foo bar (gnu);
! 
! in addition to the more classic
! 
! Foo bar = gnu;"
!   t nil
!   c++ t)
! (c-lang-defvar c-recognize-paren-inits (c-lang-const c-recognize-paren-inits))
! 
! (c-lang-defconst c-opt-<>-arglist-start
!   ;; Regexp matching the start of angle bracket arglists in languages
!   ;; where `c-recognize-<>-arglists' is set.  Does not exclude
!   ;; keywords outside `c-<>-arglist-kwds'.  The first submatch is
!   ;; assumed to surround the preceding symbol.  The whole match is
!   ;; assumed to end directly after the opening "<".
!   t (if (c-lang-const c-recognize-<>-arglists)
!       (concat "\\("
!               (c-lang-const c-symbol-key)
!               "\\)"
!               (c-lang-const c-syntactic-ws)
!               "<")))
! (c-lang-defvar c-opt-<>-arglist-start (c-lang-const c-opt-<>-arglist-start))
! 
! (c-lang-defconst c-opt-<>-arglist-start-in-paren
!   ;; Regexp that in addition to `c-opt-<>-arglist-start' matches close
!   ;; parens.  The first submatch is assumed to surround
!   ;; `c-opt-<>-arglist-start'.
!   t (if (c-lang-const c-opt-<>-arglist-start)
!       (concat "\\("
!               (c-lang-const c-opt-<>-arglist-start)
!               "\\)\\|\\s\)")))
! (c-lang-defvar c-opt-<>-arglist-start-in-paren
!   (c-lang-const c-opt-<>-arglist-start-in-paren))
  
! (c-lang-defconst c-label-key
!   "Regexp matching a normal label, i.e. a label that doesn't begin with
! a keyword like switch labels.  It's only used at the beginning of a
! statement."
!   t "\\<\\>"
!   (c c++ objc java pike) (concat "\\(" (c-lang-const c-symbol-key) "\\)"
!                                "[ \t\n\r\f\v]*:\\([^:]\\|$\\)"))
! (c-lang-defvar c-label-key (c-lang-const c-label-key)
!   'dont-doc)
! 
! (c-lang-defconst c-opt-postfix-decl-spec-key
!   ;; Regexp matching the beginning of a declaration specifier in the
!   ;; region between the header and the body of a declaration.
!   ;;
!   ;; TODO: This is currently not used uniformly; c++-mode and
!   ;; java-mode each have their own ways of using it.
!   t nil
!   c++ (concat ":?[ \t\n\r\f\v]*\\(virtual[ \t\n\r\f\v]+\\)?\\("
!             (c-make-keywords-re nil (c-lang-const c-protection-kwds))
!             "\\)[ \t\n\r\f\v]+"
!             "\\(" (c-lang-const c-symbol-key) "\\)")
!   java (c-make-keywords-re t (c-lang-const c-postfix-decl-spec-kwds)))
! (c-lang-defvar c-opt-postfix-decl-spec-key
!   (c-lang-const c-opt-postfix-decl-spec-key))
  
  (c-lang-defconst c-opt-friend-key
!   ;; Regexp describing friend declarations classes, or nil in
!   ;; languages that don't have such things.
!   ;;
!   ;; TODO: Ought to use `c-specifier-key' or similar, and the template
!   ;; skipping isn't done properly.  This will disappear soon.
!   t nil
    c++ "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+")
! (c-lang-defvar c-opt-friend-key (c-lang-const c-opt-friend-key))
  
  (c-lang-defconst c-opt-method-key
+   ;; Special regexp to match the start of Objective-C methods.  The
+   ;; first submatch is assumed to end after the + or - key.
+   t nil
    objc (concat
!       ;; TODO: Ought to use a better method than anchoring on bol.
!       "^[ \t]*\\([+-]\\)[ \t\n\r\f\v]*"
!       "\\(([^)]*)[ \t\n\r\f\v]*\\)?"  ; return type
!       "\\(" (c-lang-const c-symbol-key) "\\)"))
! (c-lang-defvar c-opt-method-key (c-lang-const c-opt-method-key))
  
  
! ;;; Wrap up the `c-lang-defvar' system.
  
! ;; Compile in the list of language variables that has been collected
! ;; with the `c-lang-defvar' macro.  Note that the first element is
! ;; nil.
! (defconst c-lang-variable-inits (cc-eval-when-compile c-lang-variable-inits))
! 
! (defun c-make-init-lang-vars-fun (mode)
!   "Create a function that initializes all the language dependent variables
! for the given mode.
! 
! This function should be evaluated at compile time, so that the
! function it returns is byte compiled with all the evaluated results
! from the language constants.  Use the `c-init-language-vars' macro to
! accomplish that conveniently.
! 
! This function does not do any hidden buffer changes."
! 
!   (if (and (not load-in-progress)
!          (boundp 'byte-compile-dest-file)
!          (stringp byte-compile-dest-file))
! 
!       ;; No need to byte compile this lambda since the byte compiler is
!       ;; smart enough to detect the `funcall' construct in the
!       ;; `c-init-language-vars' macro below and compile it all straight
!       ;; into the function that contains `c-init-language-vars'.
!       `(lambda ()
! 
!        ;; This let sets up the context for `c-mode-var' and similar
!        ;; that could be in the result from `cl-macroexpand-all'.
!        (let ((c-buffer-is-cc-mode ',mode)
!              current-var)
!          (condition-case err
! 
!              (if (eq c-version-sym ',c-version-sym)
!                  (setq ,@(let ((c-buffer-is-cc-mode mode)
!                                (c-lang-const-expansion 'immediate))
!                            ;; `c-lang-const' will expand to the evaluated
!                            ;; constant immediately in `cl-macroexpand-all'
!                            ;; below.
!                            (mapcan
!                             (lambda (init)
!                               `(current-var ',(car init)
!                                 ,(car init) ,(cl-macroexpand-all
!                                               (elt init 1))))
!                             (cdr c-lang-variable-inits))))
! 
!                (unless (get ',mode 'c-has-warned-lang-consts)
!                  (message ,(concat "%s compiled with CC Mode %s "
!                                    "but loaded with %s - evaluating "
!                                    "language constants from source")
!                           ',mode ,c-version c-version)
!                  (put ',mode 'c-has-warned-lang-consts t))
! 
!                (require 'cc-langs)
!                (let ((init (cdr c-lang-variable-inits)))
!                  (while init
!                    (setq current-var (caar init))
!                    (set (caar init) (eval (cadar init)))
!                    (setq init (cdr init)))))
! 
!            (error
!             (if current-var
!                 (message "Eval error in the `c-lang-defvar' for `%s': %S"
!                          current-var err)
!               (signal (car err) (cdr err)))))))
! 
!     ;; Being evaluated from source.  Always use the dynamic method to
!     ;; work well when `c-lang-defvar's in this file are reevaluated
!     ;; interactively.
!     `(lambda ()
!        (require 'cc-langs)
!        (let ((c-buffer-is-cc-mode ',mode)
!            (init (cdr c-lang-variable-inits))
!            current-var)
!        (condition-case err
! 
!            (while init
!              (setq current-var (caar init))
!              (set (caar init) (eval (cadar init)))
!              (setq init (cdr init)))
! 
!          (error
!           (if current-var
!               (message "Eval error in the `c-lang-defvar' for `%s': %S"
!                        current-var err)
!             (signal (car err) (cdr err)))))))
!     ))
! 
! (defmacro c-init-language-vars (mode)
!   "Initialize all the language dependent variables for the given mode.
! This macro is expanded at compile time to a form tailored for the mode
! in question, so MODE must be a constant.  Therefore MODE is not
! evaluated and should not be quoted.
  
! This macro does not do any hidden buffer changes."
!   `(funcall ,(c-make-init-lang-vars-fun mode)))
  
  
  (cc-provide 'cc-langs)
  
+ ;;; arch-tag: 1ab57482-cfc2-4c5b-b628-3539c3098822
  ;;; cc-langs.el ends here




reply via email to

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