diff options
Diffstat (limited to 'lisp/progmodes/cc-langs.el')
-rw-r--r-- | lisp/progmodes/cc-langs.el | 383 |
1 files changed, 308 insertions, 75 deletions
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index e45440b5bfd..f3dd0c6c4c9 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -205,12 +205,13 @@ the evaluated constant value at compile time." ; ' (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. -;; These are defined in cl as aliases to the cl- versions. -;(declare-function delete-duplicates "cl-seq" (cl-seq &rest cl-keys) t) -;(declare-function mapcan "cl-extra" (cl-func cl-seq &rest cl-rest) t) +(declare-function cl-delete-duplicates "cl-seq" (cl-seq &rest cl-keys)) +(declare-function cl-intersection "cl-seq" (cl-list1 cl-list2 &rest cl-keys)) +(declare-function cl-set-difference "cl-seq" (cl-list1 cl-list2 &rest cl-keys)) (eval-and-compile ;; Some helper functions used when building the language constants. @@ -292,7 +293,7 @@ the evaluated constant value at compile time." ["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] + '(["Up Conditional" c-up-conditional t] ["Backward Conditional" c-backward-conditional t] ["Forward Conditional" c-forward-conditional t] "----" @@ -382,9 +383,9 @@ The syntax tables aren't stored directly since they're quite large." ;; 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)) + '(modify-syntax-entry ?@ "_" table)) ((c-major-mode-is 'pike-mode) - `(modify-syntax-entry ?@ "." table))) + '(modify-syntax-entry ?@ "." table))) table))) (c-lang-defconst c-mode-syntax-table @@ -392,27 +393,6 @@ The syntax tables aren't stored directly since they're quite large." ;; 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. WHILE - ;; THIS SYNTAX TABLE IS CURRENT, `c-parse-state' MUST _NOT_ BE - ;; CALLED!!! - t nil - (java 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) - ;; The next eval remove a superfluous ' from '(lambda. This - ;; gets rid of compilation warnings. - (funcall (eval (c-lang-const c++-make-template-syntax-table))))) - (c-lang-defconst c-make-no-parens-syntax-table ;; A variant of the standard syntax table which is used to find matching ;; "<"s and ">"s which have been marked as parens using syntax table @@ -472,21 +452,24 @@ so that all identifiers are recognized as words.") (c-lang-defconst c-get-state-before-change-functions ;; For documentation see the following c-lang-defvar of the same name. ;; The value here may be a list of functions or a single function. - t nil + 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-invalidate-macro-cache c-truncate-bs-cache + c-before-change-check-unbalanced-strings c-parse-quotes-before-change) (c objc) '(c-extend-region-for-CPP c-depropertize-CPP c-invalidate-macro-cache c-truncate-bs-cache + c-before-change-check-unbalanced-strings c-parse-quotes-before-change) - java 'c-parse-quotes-before-change - ;; 'c-before-change-check-<>-operators + java '(c-parse-quotes-before-change + c-before-change-check-unbalanced-strings + c-before-change-check-<>-operators) 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))) @@ -495,7 +478,7 @@ so that all identifiers are recognized as words.") (list fs))) "If non-nil, a list of functions called from c-before-change-hook. Typically these will record enough state to allow -`c-before-font-lock-function' to extend the region to fontify, +`c-before-font-lock-functions' to extend the region to fontify, and may do such things as removing text-properties which must be recalculated. @@ -514,21 +497,29 @@ parameters \(point-min) and \(point-max).") ;; For documentation see the following c-lang-defvar of the same name. ;; The value here may be a list of functions or a single function. t '(c-depropertize-new-text + c-after-change-escape-NL-in-string + c-after-change-mark-abnormal-strings c-change-expand-fl-region) (c objc) '(c-depropertize-new-text + c-after-change-escape-NL-in-string c-parse-quotes-after-change + c-after-change-mark-abnormal-strings c-extend-font-lock-region-for-macros c-neutralize-syntax-in-CPP c-change-expand-fl-region) c++ '(c-depropertize-new-text + c-after-change-escape-NL-in-string + c-after-change-unmark-raw-strings c-parse-quotes-after-change + c-after-change-mark-abnormal-strings c-extend-font-lock-region-for-macros - c-after-change-re-mark-raw-strings c-neutralize-syntax-in-CPP c-restore-<>-properties c-change-expand-fl-region) java '(c-depropertize-new-text + c-after-change-escape-NL-in-string c-parse-quotes-after-change + c-after-change-mark-abnormal-strings c-restore-<>-properties c-change-expand-fl-region) awk '(c-depropertize-new-text @@ -611,12 +602,39 @@ EOL terminated statements." (c c++ objc) t) (c-lang-defvar c-has-bitfields (c-lang-const c-has-bitfields)) +(c-lang-defconst c-single-quotes-quote-strings + "Whether the language uses single quotes for multi-char strings. + +Note that to set up a language to use this, additionally: +\(i) the syntax of \"'\" must be \"string quote\" (7); +\(ii) the language's value of `c-has-quoted-numbers' must be nil; +\(iii) the language's value of `c-get-state-before-change-functions' may not + contain `c-parse-quotes-before-change'; +\(iv) the language's value of `c-before-font-lock-functions' may not contain + `c-parse-quotes-after-change'." + t nil) +(c-lang-defvar c-single-quotes-quote-strings + (c-lang-const c-single-quotes-quote-strings)) + +(c-lang-defconst c-string-delims +;; A list of characters which can delimit arbitrary length strings. + t (if (c-lang-const c-single-quotes-quote-strings) + '(?\" ?\') + '(?\"))) +(c-lang-defvar c-string-delims (c-lang-const c-string-delims)) + (c-lang-defconst c-has-quoted-numbers "Whether the language has numbers quoted like 4'294'967'295." t nil c++ t) (c-lang-defvar c-has-quoted-numbers (c-lang-const c-has-quoted-numbers)) +(c-lang-defconst c-has-compound-literals + "Whether literal initializers {...} are used other than in initializations." + t nil + (c c++) t) +(c-lang-defvar c-has-compound-literals (c-lang-const c-has-compound-literals)) + (c-lang-defconst c-modified-constant "Regexp that matches a “modified” constant literal such as \"L\\='a\\='\", a “long character”. In particular, this recognizes forms of constant @@ -850,6 +868,28 @@ literal are multiline." (c-lang-defvar c-multiline-string-start-char (c-lang-const c-multiline-string-start-char)) +(c-lang-defconst c-string-innards-re-alist + ;; An alist of regexps matching the innards of a string, the key being the + ;; string's delimiter. + ;; + ;; The regexps' matches extend up to, but not including, the closing string + ;; delimiter or an unescaped NL. An EOL is part of the string only if it is + ;; escaped. + t (mapcar (lambda (delim) + (cons + delim + (concat "\\(\\\\\\(.\\|\n\\|\r\\)\\|[^\\\n\r" + (string delim) + "]\\)*"))) + (and + (or (null (c-lang-const c-multiline-string-start-char)) + (c-characterp (c-lang-const c-multiline-string-start-char))) + (if (c-lang-const c-single-quotes-quote-strings) + '(?\" ?\') + '(?\"))))) +(c-lang-defvar c-string-innards-re-alist + (c-lang-const c-string-innards-re-alist)) + (c-lang-defconst c-opt-cpp-symbol "The symbol which starts preprocessor constructs when in the margin." t "#" @@ -899,6 +939,19 @@ file name in angle brackets or quotes." '("include")) objc '("include" "import")) +(c-lang-defconst c-cpp-include-key + ;; Matches an include directive anchored at BOL including any trailing + ;; whitespace, e.g. " # include " + t (if (and (c-lang-const c-anchored-cpp-prefix) + (c-lang-const c-cpp-include-directives)) + (concat + (c-lang-const c-anchored-cpp-prefix) + (c-make-keywords-re 'appendable + (c-lang-const c-cpp-include-directives)) + "[ \t]*") + regexp-unmatchable)) +(c-lang-defvar c-cpp-include-key (c-lang-const c-cpp-include-key)) + (c-lang-defconst c-opt-cpp-macro-define "Cpp directive (without the prefix) that is followed by a macro definition, or nil if the language doesn't have any." @@ -930,6 +983,14 @@ definition, or nil if the language doesn't have any." (c-lang-defvar c-opt-cpp-macro-define-id (c-lang-const c-opt-cpp-macro-define-id)) +(c-lang-defconst c-anchored-hash-define-no-parens + ;; Regexp matching everything up to the end of a cpp define which has no + ;; argument parentheses. Or nil in languages which don't have them. + t (if (c-lang-const c-opt-cpp-macro-define) + (concat (c-lang-const c-anchored-cpp-prefix) + (c-lang-const c-opt-cpp-macro-define) + "[ \t]+\\(\\sw\\|_\\)+\\([^(a-zA-Z0-9_]\\|$\\)"))) + (c-lang-defconst c-cpp-expr-directives "List of cpp directives (without the prefix) that are followed by an expression." @@ -1018,16 +1079,16 @@ since CC Mode treats every identifier as an expression." ;; Primary. ,@(c-lang-const c-identifier-ops) ,@(cond ((or (c-major-mode-is 'c++-mode) (c-major-mode-is 'java-mode)) - `((postfix-if-paren "<" ">"))) ; Templates. + '((postfix-if-paren "<" ">"))) ; Templates. ((c-major-mode-is 'pike-mode) - `((prefix "global" "predef"))) + '((prefix "global" "predef"))) ((c-major-mode-is 'java-mode) - `((prefix "super")))) + '((prefix "super")))) ;; Postfix. ,@(when (c-major-mode-is 'c++-mode) ;; The following need special treatment. - `((prefix "dynamic_cast" "static_cast" + '((prefix "dynamic_cast" "static_cast" "reinterpret_cast" "const_cast" "typeid" "alignof"))) (left-assoc "." @@ -1057,7 +1118,7 @@ since CC Mode treats every identifier as an expression." ;; Member selection. ,@(when (c-major-mode-is 'c++-mode) - `((left-assoc ".*" "->*"))) + '((left-assoc ".*" "->*"))) ;; Multiplicative. (left-assoc "*" "/" "%") @@ -1183,13 +1244,6 @@ This regexp is assumed to not match any non-operator identifier." (c-lang-defvar c-opt-op-identifier-prefix (c-lang-const c-opt-op-identifier-prefix)) -;; Note: the following alias is an old name which was a mis-spelling. It has -;; been corrected above and throughout cc-engine.el. It will be removed at -;; some release very shortly in the future. ACM, 2006-04-14. -(defvaralias 'c-opt-op-identitier-prefix 'c-opt-op-identifier-prefix) -(make-obsolete-variable 'c-opt-op-identitier-prefix 'c-opt-op-identifier-prefix - "CC Mode 5.31.4, 2006-04-14") - (c-lang-defconst c-ambiguous-overloadable-or-identifier-prefixes ;; A list of strings which can be either overloadable operators or ;; identifier prefixes. @@ -1274,7 +1328,7 @@ operators." (c--set-difference (c-lang-const c-assignment-operators) '("=") :test 'string-equal))) - "\\<\\>")) + regexp-unmatchable)) (c-lang-defvar c-assignment-op-regexp (c-lang-const c-assignment-op-regexp)) @@ -1355,15 +1409,17 @@ operators." (c-lang-defvar c->-op-without->-cont-regexp (c-lang-const c->-op-without->-cont-regexp)) -(c-lang-defconst c-multichar->-op-not->>-regexp - ;; Regexp matching multichar tokens containing ">", except ">>" +(c-lang-defconst c-multichar->-op-not->>->>>-regexp + ;; Regexp matching multichar tokens containing ">", except ">>" and ">>>" t (c-make-keywords-re nil - (delete ">>" - (c-filter-ops (c-lang-const c-all-op-syntax-tokens) - t - "\\(.>\\|>.\\)")))) -(c-lang-defvar c-multichar->-op-not->>-regexp - (c-lang-const c-multichar->-op-not->>-regexp)) + (c--set-difference + (c-filter-ops (c-lang-const c-all-op-syntax-tokens) + t + "\\(.>\\|>.\\)") + '(">>" ">>>") + :test 'string-equal))) +(c-lang-defvar c-multichar->-op-not->>->>>-regexp + (c-lang-const c-multichar->-op-not->>->>>-regexp)) (c-lang-defconst c-:-op-cont-tokens ;; A list of second and subsequent characters of all multicharacter tokens @@ -1388,12 +1444,56 @@ operators." t "^;{}?:") (c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars)) +(c-lang-defconst c-stmt-boundary-skip-chars + ;; Like `c-stmt-delim-chars', but augmented by "#" for languages with CPP + ;; constructs, and for C++ Mode, also by "[", to help deal with C++ + ;; attributes. + t (if (c-lang-const c-opt-cpp-symbol) + (concat (substring (c-lang-const c-stmt-delim-chars) 0 1) ; "^" + (c-lang-const c-opt-cpp-symbol) ; usually # + (substring (c-lang-const c-stmt-delim-chars) 1)) ; ";{}?:" + (c-lang-const c-stmt-delim-chars)) + c++ (concat (substring (c-lang-const c-stmt-boundary-skip-chars) 0 1) ; "^" + "[" + (substring (c-lang-const c-stmt-boundary-skip-chars) 1))) ; ";{}?:" +(c-lang-defvar c-stmt-boundary-skip-chars + (c-lang-const c-stmt-boundary-skip-chars)) + +(c-lang-defconst c-stmt-boundary-skip-list + ;; The characters (apart from the initial ^) in `c-stmt-boundary-skip-chars' + ;; as a list of characters. + t (append (substring (c-lang-const c-stmt-boundary-skip-chars) 1) nil)) +(c-lang-defvar c-stmt-boundary-skip-list + (c-lang-const c-stmt-boundary-skip-list)) + (c-lang-defconst c-stmt-delim-chars-with-comma ;; Variant of `c-stmt-delim-chars' that additionally contains ','. t "^;,{}?:") (c-lang-defvar c-stmt-delim-chars-with-comma (c-lang-const c-stmt-delim-chars-with-comma)) +(c-lang-defconst c-stmt-boundary-skip-chars-with-comma + ;; Variant of `c-stmt-boundary-skip-chars' also containing ','. + t (if (c-lang-const c-opt-cpp-symbol) + (concat (substring (c-lang-const c-stmt-delim-chars-with-comma) 0 1) + (c-lang-const c-opt-cpp-symbol) ; usually # + (substring (c-lang-const c-stmt-delim-chars-with-comma) 1)) + (c-lang-const c-stmt-delim-chars-with-comma)) + c++ (concat + (substring (c-lang-const c-stmt-boundary-skip-chars-with-comma) 0 1) ; "^" + "[" + (substring (c-lang-const c-stmt-boundary-skip-chars-with-comma) 1))) ; ";,{}?:" +(c-lang-defvar c-stmt-boundary-skip-chars-with-comma + (c-lang-const c-stmt-boundary-skip-chars-with-comma)) + +(c-lang-defconst c-stmt-boundary-skip-list-with-comma + ;; Variant of `c-stmt-boundary-skip-list' also including a comma. + t (append (substring (c-lang-const c-stmt-boundary-skip-chars-with-comma) + 1) + nil)) +(c-lang-defvar c-stmt-boundary-skip-list-with-comma + (c-lang-const c-stmt-boundary-skip-list-with-comma)) + (c-lang-defconst c-pack-ops "Ops which signal C++11's \"parameter pack\"" t nil @@ -1497,10 +1597,30 @@ properly." ;; language) t (if (c-lang-const c-block-comment-ender) (regexp-quote (c-lang-const c-block-comment-ender)) - "\\<\\>")) + regexp-unmatchable)) (c-lang-defvar c-block-comment-ender-regexp (c-lang-const c-block-comment-ender-regexp)) +(c-lang-defconst c-block-comment-awkward-chars + "List of characters which, inside a block comment, could be the first +character of a double character construct. This doesn't include +backslash." + t (when (> (length (c-lang-const c-block-comment-ender)) 1) + (list (aref (c-lang-const c-block-comment-ender) 0)))) +(c-lang-defvar c-block-comment-awkward-chars + (c-lang-const c-block-comment-awkward-chars)) + +(c-lang-defconst c-font-lock-comment-end-skip + ;; Regexp which matches whitespace followed by the end of a block comment + ;; (if such exists in the language). This is used by font lock to determine + ;; the portion of the end of a comment to fontify with + ;; `font-lock-comment-delimiter-face'. + t (if (c-lang-const c-block-comment-ender) + (concat "[ \t]*" (c-lang-const c-block-comment-ender-regexp)) + regexp-unmatchable)) +(c-lang-setvar font-lock-comment-end-skip + (c-lang-const c-font-lock-comment-end-skip)) + (c-lang-defconst c-comment-start-regexp ;; Regexp to match the start of any type of comment. t (let ((re (c-make-keywords-re nil @@ -1516,7 +1636,7 @@ properly." ;; language) t (if (c-lang-const c-block-comment-starter) (regexp-quote (c-lang-const c-block-comment-starter)) - "\\<\\>")) + regexp-unmatchable)) (c-lang-defvar c-block-comment-start-regexp (c-lang-const c-block-comment-start-regexp)) @@ -1525,22 +1645,42 @@ properly." ;; language; it does in all 7 CC Mode languages). t (if (c-lang-const c-line-comment-starter) (regexp-quote (c-lang-const c-line-comment-starter)) - "\\<\\>")) + regexp-unmatchable)) (c-lang-defvar c-line-comment-start-regexp (c-lang-const c-line-comment-start-regexp)) +(c-lang-defconst c-last-c-comment-end-on-line-re + "Regexp which matches the last block comment ender on the +current line, if any, or nil in those languages without block +comments. When a match is found, submatch 1 contains the comment +ender." + t "\\(\\*/\\)\\([^*]\\|\\*+\\([^*/]\\|$\\)\\)*$" + awk nil) +(c-lang-defvar c-last-c-comment-end-on-line-re + (c-lang-const c-last-c-comment-end-on-line-re)) + +(c-lang-defconst c-last-open-c-comment-start-on-line-re + "Regexp which matches the last block comment start on the +current ine, if any, or nil in those languages without block +comments. When a match is found, submatch 1 contains the comment +starter." + t "\\(/\\*\\)\\([^*]\\|\\*+\\([^*/]\\|$\\)\\)*$" + awk nil) +(c-lang-defvar c-last-open-c-comment-start-on-line-re + (c-lang-const c-last-open-c-comment-start-on-line-re)) + (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) - "\"|" + "\"\\|\\s|" "\""))) (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 "\\<\\>" + t regexp-unmatchable ;; From font-lock.el: `doxygen' uses /*! while others use /**. (c c++ objc) "/\\*[*!]" java "/\\*\\*" @@ -1989,6 +2129,19 @@ effect in the declaration, but are syntactically like whitespace." (c-lang-defvar c-type-decl-suffix-ws-ids-key (c-lang-const c-type-decl-suffix-ws-ids-key)) +(c-lang-defconst c-class-id-suffix-ws-ids-kwds + "\"Identifiers\" that when immediately following the identifier +of a class declaration have semantic effect in the declaration, +but are syntactically like whitespace." + t nil + c++ '("final")) + +(c-lang-defconst c-class-id-suffix-ws-ids-key + ;; An adorned regexp matching `c-class-id-suffix-ws-ids-kwds'. + t (c-make-keywords-re t (c-lang-const c-class-id-suffix-ws-ids-kwds))) +(c-lang-defvar c-class-id-suffix-ws-ids-key + (c-lang-const c-class-id-suffix-ws-ids-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. @@ -2101,6 +2254,18 @@ will be handled." "Alist associating keywords in c-other-decl-block-decl-kwds with their matching \"in\" syntactic symbols.") +(c-lang-defconst c-defun-type-name-decl-kwds + "Keywords introducing a named block, where the name is a \"defun\" + name." + t (append (c-lang-const c-class-decl-kwds) + (c-lang-const c-brace-list-decl-kwds))) + +(c-lang-defconst c-defun-type-name-decl-key + ;; Regexp matching a keyword in `c-defun-name-decl-kwds'. + t (c-make-keywords-re t (c-lang-const c-defun-type-name-decl-kwds))) +(c-lang-defvar c-defun-type-name-decl-key + (c-lang-const c-defun-type-name-decl-key)) + (c-lang-defconst c-typedef-decl-kwds "Keywords introducing declarations where the identifier(s) being declared are types. @@ -2150,6 +2315,18 @@ will be handled." pike (append (c-lang-const c-class-decl-kwds) '("constant"))) +(c-lang-defconst c-equals-type-clause-kwds + "Keywords which are followed by an identifier then an \"=\" + sign, which declares the identifier to be a type." + t nil + c++ '("using")) + +(c-lang-defconst c-equals-type-clause-key + ;; A regular expression which matches any member of + ;; `c-equals-type-clause-kwds'. + t (c-make-keywords-re t (c-lang-const c-equals-type-clause-kwds))) +(c-lang-defvar c-equals-type-clause-key (c-lang-const c-equals-type-clause-key)) + (c-lang-defconst c-modifier-kwds "Keywords that can prefix normal declarations of identifiers \(and typically act as flags). Things like argument declarations @@ -2443,7 +2620,11 @@ regexp if `c-colon-type-list-kwds' isn't nil." ;; before the ":" that starts the inherit list after "class" ;; or "struct" in C++. (Also used as default for other ;; languages.) - "[^][{}();,/#=:]*:")) + (if (c-lang-const c-opt-identifier-concat-key) + (concat "\\([^][{}();,/#=:]\\|" + (c-lang-const c-opt-identifier-concat-key) + "\\)*:") + "[^][{}();,/#=:]*:"))) (c-lang-defvar c-colon-type-list-re (c-lang-const c-colon-type-list-re)) (c-lang-defconst c-paren-nontype-kwds @@ -2569,6 +2750,17 @@ Keywords here should also be in `c-block-stmt-1-kwds'." (c-lang-const c-block-stmt-2-kwds)) :test 'string-equal)) +(c-lang-defconst c-block-stmt-hangon-kwds + "Keywords which may directly follow a member of `c-block-stmt-1/2-kwds'." + t nil + c++ '("constexpr")) + +(c-lang-defconst c-block-stmt-hangon-key + ;; Regexp matching a "hangon" keyword in a `c-block-stmt-1/2-kwds' + ;; construct. + t (c-make-keywords-re t (c-lang-const c-block-stmt-hangon-kwds))) +(c-lang-defvar c-block-stmt-hangon-key (c-lang-const c-block-stmt-hangon-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 @@ -2972,7 +3164,7 @@ Note that Java specific rules are currently applied to tell this from "Regexp matching a keyword that is followed by a colon, where the whole construct can precede a declaration. E.g. \"public:\" in C++." - t "\\<\\>" + t regexp-unmatchable c++ (c-make-keywords-re t (c-lang-const c-protection-kwds))) (c-lang-defvar c-decl-start-colon-kwd-re (c-lang-const c-decl-start-colon-kwd-re)) @@ -3051,24 +3243,40 @@ constructs." ;; token that might precede such a construct, e.g. ';', '}' or '{'. ;; It's built from `c-decl-prefix-re'. ;; - ;; If the first submatch did not match, the match of the whole - ;; regexp is taken to be at the first token in the declaration. - ;; `c-decl-start-re' is not checked in this case. + ;; If the first submatch did not match, we have either a #define construct + ;; without parentheses or the match of the whole regexp is taken to be at + ;; the first token in the declaration. `c-decl-start-re' is not checked in + ;; these cases. ;; ;; Design note: The reason the same regexp is used to match both ;; tokens that precede declarations and start them is to avoid an ;; extra regexp search from the previous declaration spot in ;; `c-find-decl-spots'. Users of `c-find-decl-spots' also count on - ;; that it finds all declaration/cast/label starts in approximately + ;; it finding all declaration/cast/label starts in approximately ;; linear order, so we can't do the searches in two separate passes. - t (if (c-lang-const c-decl-start-kwds) - (concat (c-lang-const c-decl-prefix-re) - "\\|" - (c-make-keywords-re t (c-lang-const c-decl-start-kwds))) - (c-lang-const c-decl-prefix-re))) + t (cond + ((and (c-lang-const c-decl-start-kwds) + (c-lang-const c-anchored-hash-define-no-parens)) + (concat (c-lang-const c-decl-prefix-re) + "\\|" (c-lang-const c-anchored-hash-define-no-parens) + "\\|" (c-make-keywords-re t (c-lang-const c-decl-start-kwds)))) + ((c-lang-const c-decl-start-kwds) + (concat (c-lang-const c-decl-prefix-re) + "\\|" (c-make-keywords-re t (c-lang-const c-decl-start-kwds)))) + ((c-lang-const c-anchored-hash-define-no-parens) + (concat (c-lang-const c-decl-prefix-re) + "\\|" (c-lang-const c-anchored-hash-define-no-parens))) + (t (c-lang-const c-decl-prefix-re)))) (c-lang-defvar c-decl-prefix-or-start-re (c-lang-const c-decl-prefix-or-start-re)) +(c-lang-defconst c-dposr-cpp-macro-depth + ;; The match number of `c-anchored-hash-define-no-parens''s first match + ;; within `c-decl-prefix-or-start-re', or nil if there is no such component. + t (if (c-lang-const c-anchored-hash-define-no-parens) + (1+ (regexp-opt-depth (c-lang-const c-decl-prefix-re))))) +(c-lang-defvar c-dposr-cpp-macro-depth (c-lang-const c-dposr-cpp-macro-depth)) + (c-lang-defconst c-cast-parens ;; List containing the paren characters that can open a cast, or nil in ;; languages without casts. @@ -3153,7 +3361,7 @@ Identifier syntax is in effect when this is matched \(see t (if (c-lang-const c-type-modifier-kwds) (concat (regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>") ;; Default to a regexp that never matches. - "\\<\\>") + regexp-unmatchable) ;; Check that there's no "=" afterwards to avoid matching tokens ;; like "*=". (c objc) (concat "\\(" @@ -3167,7 +3375,7 @@ Identifier syntax is in effect when this is matched \(see "\\|" "\\.\\.\\." "\\|" - "[*(&]" + "[*(&~]" "\\|" (c-lang-const c-type-decl-prefix-key) "\\|" @@ -3191,7 +3399,7 @@ that might precede the identifier in a declaration, e.g. the as the end of the operator. Identifier syntax is in effect when this is matched \(see `c-identifier-syntax-table')." t ;; Default to a regexp that never matches. - "\\<\\>" + regexp-unmatchable ;; Check that there's no "=" afterwards to avoid matching tokens ;; like "*=". (c objc) (concat "\\(\\*\\)" @@ -3350,7 +3558,7 @@ list." (c-lang-defconst c-pre-id-bracelist-key "A regexp matching tokens which, preceding an identifier, signify a bracelist. " - t "\\<\\>" + t regexp-unmatchable c++ "new\\([^[:alnum:]_$]\\|$\\)\\|&&?\\(\\S.\\|$\\)") (c-lang-defvar c-pre-id-bracelist-key (c-lang-const c-pre-id-bracelist-key)) @@ -3406,7 +3614,7 @@ the invalidity of the putative template construct." ;; before the '{' of the enum list, to avoid searching too far. "[^][{};/#=]*" "{") - "\\<\\>")) + regexp-unmatchable)) (c-lang-defvar c-enum-clause-introduction-re (c-lang-const c-enum-clause-introduction-re)) @@ -3518,11 +3726,36 @@ i.e. before \":\". Only used if `c-recognize-colon-labels' is set." c++ (concat "\\s(\\|\"\\|" (c-lang-const c-nonlabel-token-key))) (c-lang-defvar c-nonlabel-token-key (c-lang-const c-nonlabel-token-key)) +(c-lang-defconst c-nonlabel-nonparen-token-key + "Regexp matching things that can't occur in generic colon labels, +neither in a statement nor in a declaration context, with the +exception of an open parenthesis. The regexp is tested at the +beginning of every sexp in a suspected label, i.e. before \":\". +Only used if `c-recognize-colon-labels' is set." + ;; This lang const is the same as `c-nonlabel-token-key', except for a + ;; slight difference in the c++-mode value. + t (concat + ;; All keywords except `c-label-kwds' and `c-protection-kwds'. + (c-make-keywords-re t + (c--set-difference (c-lang-const c-keywords) + (append (c-lang-const c-label-kwds) + (c-lang-const c-protection-kwds)) + :test 'string-equal))) + ;; Don't allow string literals, except in AWK and Java. Character constants are OK. + (c objc pike idl) (concat "\"\\|" + (c-lang-const c-nonlabel-nonparen-token-key)) + ;; Also check for open parens in C++, to catch member init lists in + ;; constructors. We normally allow it so that macros with arguments + ;; work in labels. + c++ (concat "[{[]\\|\"\\|" (c-lang-const c-nonlabel-nonparen-token-key))) +(c-lang-defvar c-nonlabel-nonparen-token-key + (c-lang-const c-nonlabel-nonparen-token-key)) + (c-lang-defconst c-nonlabel-token-2-key "Regexp matching things that can't occur two symbols before a colon in a label construct. This catches C++'s inheritance construct \"class foo : bar\". Only used if `c-recognize-colon-labels' is set." - t "\\<\\>" ; matches nothing + t regexp-unmatchable c++ (c-make-keywords-re t '("class"))) (c-lang-defvar c-nonlabel-token-2-key (c-lang-const c-nonlabel-token-2-key)) |