diff options
Diffstat (limited to 'lisp/progmodes/cc-langs.el')
-rw-r--r-- | lisp/progmodes/cc-langs.el | 284 |
1 files changed, 254 insertions, 30 deletions
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 07479389c62..0b125bc43fa 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -1,4 +1,4 @@ -;;; cc-langs.el --- language specific settings for CC Mode -*- coding: utf-8 -*- +;;; cc-langs.el --- language specific settings for CC Mode -*- lexical-binding: t; coding: utf-8 -*- ;; Copyright (C) 1985, 1987, 1992-2021 Free Software Foundation, Inc. @@ -159,7 +159,9 @@ evaluated and bound to VAR when the result from the macro `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." - + (declare (indent defun) + (debug (&define name def-form + &optional &or ("quote" symbolp) stringp))) (when (and (not doc) (eq (car-safe val) 'c-lang-const) (eq (nth 1 val) var) @@ -191,6 +193,7 @@ Emacs variable like `comment-start'. `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." + (declare (debug (&define name def-form))) (let ((elem (assq var (cdr c-emacs-variable-inits)))) (if elem (setcdr elem (list val)) ; Maybe remove "list", sometime. 2006-07-19 @@ -200,13 +203,6 @@ the evaluated constant value at compile time." ;; Return the symbol, like the other def* forms. `',var) -(put 'c-lang-defvar 'lisp-indent-function 'defun) -; (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el. -; ' -(def-edebug-spec c-lang-defvar - (&define name def-form &optional &or ("quote" symbolp) stringp)) -(def-edebug-spec c-lang-setvar (&define name def-form)) - ;; Suppress "might not be defined at runtime" warning. ;; This file is only used when compiling other cc files. (declare-function cl-delete-duplicates "cl-seq" (cl-seq &rest cl-keys)) @@ -337,7 +333,8 @@ the evaluated constant value at compile time." This includes setting \\=' and \" as string delimiters, and setting up the comment syntax to handle both line style \"//\" and block style \"/*\" \"*/\" comments." - + ;; Never native compile to allow cc-mode.el:467 hack. + (declare (speed -1)) (modify-syntax-entry ?_ "_" table) (modify-syntax-entry ?\\ "\\" table) (modify-syntax-entry ?+ "." table) @@ -378,12 +375,14 @@ The syntax tables aren't stored directly since they're quite large." (let ((table (make-syntax-table))) (c-populate-syntax-table table) ;; Mode specific syntaxes. - ,(cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode)) + ,(cond ((c-major-mode-is 'objc-mode) ;; Let '@' be part of symbols in ObjC to cope with ;; its compiler directives as single keyword tokens. ;; This is then necessary since it's assumed that ;; every keyword is a single symbol. '(modify-syntax-entry ?@ "_" table)) + ((c-major-mode-is 'java-mode) + '(modify-syntax-entry ?@ "'" table)) ((c-major-mode-is 'pike-mode) '(modify-syntax-entry ?@ "." table))) table))) @@ -454,9 +453,9 @@ so that all identifiers are recognized as words.") ;; The value here may be a list of functions or a single function. t 'c-before-change-check-unbalanced-strings c++ '(c-extend-region-for-CPP - c-before-change-check-raw-strings - c-before-change-check-<>-operators c-depropertize-CPP + c-before-change-check-ml-strings + c-before-change-check-<>-operators c-truncate-bs-cache c-before-change-check-unbalanced-strings c-parse-quotes-before-change) @@ -468,6 +467,8 @@ so that all identifiers are recognized as words.") java '(c-parse-quotes-before-change c-before-change-check-unbalanced-strings c-before-change-check-<>-operators) + pike '(c-before-change-check-ml-strings + c-before-change-check-unbalanced-strings) awk 'c-awk-record-region-clear-NL) (c-lang-defvar c-get-state-before-change-functions (let ((fs (c-lang-const c-get-state-before-change-functions))) @@ -507,7 +508,7 @@ parameters \(point-min) and \(point-max).") c-change-expand-fl-region) c++ '(c-depropertize-new-text c-after-change-escape-NL-in-string - c-after-change-unmark-raw-strings + c-after-change-unmark-ml-strings c-parse-quotes-after-change c-after-change-mark-abnormal-strings c-extend-font-lock-region-for-macros @@ -520,6 +521,11 @@ parameters \(point-min) and \(point-max).") c-after-change-mark-abnormal-strings c-restore-<>-properties c-change-expand-fl-region) + pike '(c-depropertize-new-text + c-after-change-escape-NL-in-string + c-after-change-unmark-ml-strings + c-after-change-mark-abnormal-strings + c-change-expand-fl-region) awk '(c-depropertize-new-text c-awk-extend-and-syntax-tablify-region)) (c-lang-defvar c-before-font-lock-functions @@ -579,14 +585,12 @@ don't have EOL terminated statements. " (c-lang-defvar c-at-vsemi-p-fn (c-lang-const c-at-vsemi-p-fn)) (c-lang-defconst c-vsemi-status-unknown-p-fn - "Contains a predicate regarding the presence of virtual semicolons. -More precisely, the function answers the question, \"are we unsure whether a -virtual semicolon exists on this line?\". The (admittedly kludgy) purpose of -such a function is to prevent an infinite recursion in -`c-beginning-of-statement-1' when point starts at a `while' token. The function -MUST NOT UNDER ANY CIRCUMSTANCES call `c-beginning-of-statement-1', even -indirectly. This variable contains nil for languages which don't have EOL -terminated statements." + "A function \"are we unsure whether there is a virtual semicolon on this line?\". +The (admittedly kludgy) purpose of such a function is to prevent an infinite +recursion in c-beginning-of-statement-1 when point starts at a `while' token. +The function MUST NOT UNDER ANY CIRCUMSTANCES call `c-beginning-of-statement-1', +even indirectly. This variable contains nil for languages which don't have +EOL terminated statements." t nil (c c++ objc) 'c-macro-vsemi-status-unknown-p awk 'c-awk-vsemi-status-unknown-p) @@ -623,6 +627,176 @@ Note that to set up a language to use this, additionally: '(?\"))) (c-lang-defvar c-string-delims (c-lang-const c-string-delims)) + +;; The next section of the code defines multi-line ("ml") strings for each +;; language. By default, there are no ml strings in a language. To configure +;; them, set each needed lang const in the section. See further details in +;; cc-engine.el (search for "Handling of CC Mode multi-line strings."). +(c-lang-defconst c-ml-string-backslash-escapes + ;; N.B. if `c-ml-string-backslash-escapes' is non-nil, you probably need a + ;; `c-ml-string-any-closer-re' that scans backslashed characters, etc. + "If non-nil, a \\ character escapes the next character in a ml string. +Otherwise such a \\ will be marked to be handled as any other character." + t nil + pike t + ) + +(c-lang-defconst c-ml-string-non-punc-skip-chars + ;; A `skip-chars-forward' argument which skips over all ml string characters + ;; which don't need to be marked with punctuation ('(1)) syntax. + t (if (c-lang-const c-ml-string-backslash-escapes) + "^\"" + "^\"\\")) +(c-lang-defvar c-ml-string-non-punc-skip-chars + (c-lang-const c-ml-string-non-punc-skip-chars)) + +(c-lang-defconst c-ml-string-opener-re + "If non-nil, a regexp that matches a multi-line string opener. +It may also match context. + +Such an opener must be at least 2 characters long, and must +contain a \" character. (match-string 1) matches the actual +delimiter and (match-string 2) matches the actual \". If a +delimiter contains several \"s, it is recommended to configure +the first of them as \"the\" \"." + t nil + pike "\\(#\\(\"\\)\\)" + c++ "\\(R\\(\"\\)[^ ()\\\n\r\t]\\{0,16\\}(\\)") +(c-lang-defvar c-ml-string-opener-re (c-lang-const c-ml-string-opener-re)) + +(c-lang-defconst c-ml-string-max-opener-len + "If non-nil, the maximum length of a multi-line string opener." + t nil + pike 2 + c++ 19) +(c-lang-defvar c-ml-string-max-opener-len + (c-lang-const c-ml-string-max-opener-len)) + +(c-lang-defconst c-ml-string-any-closer-re + "If non-nil, a regexp that matches any multi-line string closer. +It may also match context. + +A search for this regexp starting at the end of the corresponding +opener must find the first closer as the first match. + +Such a closer must include a \" character. (match-string 1) +matches the actual delimiter and and (match-string 2) matches the +actual \". If a delimiter contains several \"s, it is +recommended to regard the last of them as \"the\" \"." + t nil + pike "\\(?:\\=\\|[^\\\"]\\)\\(?:\\\\.\\)*\\(\\(\"\\)\\)" + c++ "\\()[^ ()\\n\r\t]\\{0,16\\}\\(\"\\)\\)") +;; csharp "\\(?:\\=\\|[^\"]\\)\\(?:\"\"\\)*\\(\\(\"\\)\\)\\(?:[^\"]\\|\\'\\)" +(c-lang-defvar c-ml-string-any-closer-re + (c-lang-const c-ml-string-any-closer-re)) + +(c-lang-defconst c-ml-string-max-closer-len + "If non-nil, the maximum length of a multi-line string closer. +This must include the length of any \"context trailer\" following +the actual closer and any \"context leader\" preceding it. This +variable is ignored when `c-ml-string-back-closer-re' is non-nil." + t nil + c++ 18) +(c-lang-defvar c-ml-string-max-closer-len + (c-lang-const c-ml-string-max-closer-len)) + +(c-lang-defconst c-ml-string-max-closer-len-no-leader + "If non-nil, the maximum length of a ml string closer without its leader. +By \"leader\" is meant the context bytes preceding the actual +multi-line string closer, that part of +`c-ml-string-any-closer-re''s match preceding (match-beginning 1)." + t nil + pike 1 + ;; 2 + ;; 3 + c++ 18) +(c-lang-defvar c-ml-string-max-closer-len-no-leader + (c-lang-const c-ml-string-max-closer-len-no-leader)) + +(c-lang-defconst c-ml-string-back-closer-re + "A regexp to move back out of a putative ml closer point is in. + +This variable need only be non-nil for languages with multi-line +string closers that can contain an indefinite length \"leader\" +preceding the actual closer. It was designed for formats where +an unbounded number of \\s or \"s might precede the closer +proper, for example in Pike Mode or csharp-mode. + +If point is in a putative multi-line string closer, a backward +regexp search with `c-ml-string-back-closer-re' will leave point +in a \"safe place\", from where a forward regexp search with +`c-ml-string-any-closer-re' can test whether the original +position was inside an actual closer. + +When non-nil, this variable should end in \"\\\\\\==\". Note that +such a backward search will match a minimal string, so a +\"context character\" is probably needed at the start of the +regexp. The value for csharp-mode would be something like +\"\\\\(:?\\\\`\\\\|[^\\\"]\\\\)\\\"*\\\\\\==\"." + t nil + pike "\\(:?\\`\\|[^\\\"]\\)\\(:?\\\\.\\)*\\=" + ;;pike ;; 2 + ;; "\\(:?\\`\\|[^\"]\\)\"*\\=" + ) +(c-lang-defvar c-ml-string-back-closer-re + (c-lang-const c-ml-string-back-closer-re)) + +(c-lang-defconst c-make-ml-string-closer-re-function + "If non-nil, a function which creates a closer regexp matching an opener. + +Such a function is given one argument, a multi-line opener (a +string), and returns a regexp which will match the corresponding +closer. When this regexp matches, (match-string 1) should be the +actual closing delimiter, and (match-string 2) the \"active\" \" +it contains. + +A forward regexp search for this regexp starting at the end of +the opener must find the closer as its first match." + t (if (c-lang-const c-ml-string-any-closer-re) + 'c-ml-string-make-closer-re) + c++ 'c-c++-make-ml-string-closer-re) +(c-lang-defvar c-make-ml-string-closer-re-function + (c-lang-const c-make-ml-string-closer-re-function)) + +(c-lang-defconst c-make-ml-string-opener-re-function + "If non-nil, a function which creates an opener regexp matching a closer. + +Such a function is given one argument, a multi-line closer (a +string), and returns a regexp which will match the corresponding +opener. When this regexp matches, (match-string 1) should be the +actual opening delimiter, and (match-string 2) the \"active\" \" +it contains. + +A backward regexp search for this regexp starting at the start of +the closer might not find the opener as its first match, should +there be copies of the opener contained in the multi-line string." + t (if (c-lang-const c-ml-string-opener-re) + 'c-ml-string-make-opener-re) + c++ 'c-c++-make-ml-string-opener-re) +(c-lang-defvar c-make-ml-string-opener-re-function + (c-lang-const c-make-ml-string-opener-re-function)) + +(c-lang-defconst c-ml-string-cpp-or-opener-re + ;; A regexp which matches either a macro or a multi-line string opener. + t (concat "\\(" + (or (c-lang-const c-anchored-cpp-prefix) "\\`a\\`") + "\\)\\|\\(" + (or (c-lang-const c-ml-string-opener-re) "\\`a\\`") + "\\)")) +(c-lang-defvar c-ml-string-cpp-or-opener-re + (c-lang-const c-ml-string-cpp-or-opener-re)) + +(c-lang-defconst c-cpp-or-ml-match-offset + ;; The offset to be added onto match numbers for a multi-line string in + ;; matches for `c-cpp-or-ml-string-opener-re'. + t (if (c-lang-const c-anchored-cpp-prefix) + (+ 2 (regexp-opt-depth (c-lang-const c-anchored-cpp-prefix))) + 2)) +(c-lang-defvar c-cpp-or-ml-match-offset + (c-lang-const c-cpp-or-ml-match-offset)) +;; End of ml string section. + + (c-lang-defconst c-has-quoted-numbers "Whether the language has numbers quoted like 4'294'967'295." t nil @@ -863,9 +1037,15 @@ literals." "Set if the language supports multiline string literals without escaped newlines. If t, all string literals are multiline. If a character, only literals where the open quote is immediately preceded by that -literal are multiline." - t nil - pike ?#) +literal are multiline. + +Note that from CC Mode 5.36, this character use is obsolete, +having been superseded by the \"multi-line string\" mechanism. +If both mechanisms are set for a language, the newer one prevails +over the old `c-multiline-string-start-char'. See the variables +in the page containing `c-ml-string-opener-re' in cc-langs.el for +further directions." + t nil) (c-lang-defvar c-multiline-string-start-char (c-lang-const c-multiline-string-start-char)) @@ -2746,7 +2926,8 @@ if this isn't nil." `c-recognize-<>-arglists' for details. That language constant is assumed to be set if this isn't nil." t nil - c++ '("template") + c++ '("template" "const_cast" "dynamic_cast" "reinterpret_cast" + "static_cast") idl '("fixed" "string" "wstring")) (c-lang-defconst c-<>-sexp-kwds @@ -3098,6 +3279,36 @@ Note that Java specific rules are currently applied to tell this from 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-stmt-block-only-keywords + "All keywords which unambiguously signify a statement block (as opposed to + a brace list) when occurring inside braces." + t (c--set-difference + (c-lang-const c-keywords) + (append (c-lang-const c-primary-expr-kwds) + (c-lang-const c-constant-kwds) + `(,@(when (c-major-mode-is 'c++-mode) + '("typeid" "dynamic_cast" "static_cast" "const_cast" + "reinterpret_cast" "alignof"))) + (c-lang-const c-type-modifier-prefix-kwds) + (c-lang-const c-overloadable-operators) + (c-lang-const c-template-typename-kwds) + `(,@(when (c-major-mode-is 'c++-mode) + '("reflexpr"))) + `(,@(when (c-major-mode-is '(c-mode c++-mode)) + '("sizeof"))) + (c-lang-const c-pre-lambda-tokens) + (c-lang-const c-block-decls-with-vars) + (c-lang-const c-primitive-type-kwds)) + :test 'string-equal)) + +(c-lang-defconst c-stmt-block-only-keywords-regexp + ;; A regexp matching a keyword in `c-stmt-block-only-keywords'. Such a + ;; match can start and end only at token boundaries. + t (concat "\\(^\\|\\=\\|[^" (c-lang-const c-symbol-chars) "]\\)" + (c-make-keywords-re t (c-lang-const c-stmt-block-only-keywords)))) +(c-lang-defvar c-stmt-block-only-keywords-regexp + (c-lang-const c-stmt-block-only-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 @@ -3650,13 +3861,25 @@ list." c t) (c-lang-defvar c-recognize-knr-p (c-lang-const c-recognize-knr-p)) +(c-lang-defconst c-pre-id-bracelist-kwds + "Keywords which, preceding an identifier and brace, signify a bracelist. +This is only used in c++-mode." + t nil + c++ '("new" "throw")) + (c-lang-defconst c-pre-id-bracelist-key - "A regexp matching tokens which, preceding an identifier, signify a bracelist. -" - t regexp-unmatchable - c++ "new\\([^[:alnum:]_$]\\|$\\)\\|&&?\\(\\S.\\|$\\)") + ;; A regexp matching keywords which, preceding an identifier and brace, + ;; signify a bracelist. Only used in c++-mode. + t (c-make-keywords-re t (c-lang-const c-pre-id-bracelist-kwds))) (c-lang-defvar c-pre-id-bracelist-key (c-lang-const c-pre-id-bracelist-key)) +(c-lang-defconst c-pre-brace-non-bracelist-key + "A regexp matching tokens which, preceding a brace, make it a non-bracelist." + t regexp-unmatchable + c++ "&&?\\(\\S.\\|$\\)") +(c-lang-defvar c-pre-brace-non-bracelist-key + (c-lang-const c-pre-brace-non-bracelist-key)) + (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 @@ -4051,6 +4274,7 @@ accomplish that conveniently." 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." + (declare (debug nil)) `(funcall ,(c-make-init-lang-vars-fun mode))) |