From 02b037b85ce32fdcf454f5b12d72f09bcb217891 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Mon, 15 Feb 2016 12:45:42 +0000 Subject: [PATCH] Allow arithmetic operators inside C++ template constructs. Fixes debbugs #22486. This corrects the previous patch with this message which was empty. * lisp/progmodes/cc-langs.el (c-multichar->-op-not->>-regexp): New language variable. (c-<>-notable-chars-re): New language variable. * lisp/progmodes/cc-engine.el (c-forward-<>-arglist-recur): User c-<>-notable-chars-re in place of the former fixed string in searching for places to stop and examine. Use c-multichar->-op-not->>-regexp to check that a found ">" is not part of a multichar operator in place of the former c->-op-without->-cont-regexp. Add code to skip forwards over a balanced parenthesized expression. --- lisp/progmodes/cc-engine.el | 14 ++++++++++++-- lisp/progmodes/cc-langs.el | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index a4a1604e6f4..d4dcb1ca0e8 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -6056,7 +6056,10 @@ comment at the start of cc-engine.el for more info." ;; Stop on ',', '|', '&', '+' and '-' to catch ;; common binary operators that could be between ;; two comparison expressions "ad". - "[<;{},|+&-]\\|[>)]" + ;; 2016-02-11: C++11 templates can now contain arithmetic + ;; expressions, so template detection in C++ is now less + ;; robust than it was. + c-<>-notable-chars-re nil t t)) (cond @@ -6064,7 +6067,9 @@ comment at the start of cc-engine.el for more info." ;; Either an operator starting with '>' or the end of ;; the angle bracket arglist. - (if (looking-at c->-op-without->-cont-regexp) + (if (save-excursion + (c-backward-token-2) + (looking-at c-multichar->-op-not->>-regexp)) (progn (goto-char (match-end 0)) t) ; Continue the loop. @@ -6134,6 +6139,11 @@ comment at the start of cc-engine.el for more info." ))) t) ; carry on looping. + ((and + (eq (char-before) ?\() + (c-go-up-list-forward) + (eq (char-before) ?\)))) + ((and (not c-restricted-<>-arglists) (or (and (eq (char-before) ?&) (not (eq (char-after) ?&))) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 8a1d43c627c..dd1bccf3d96 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -228,6 +228,12 @@ the evaluated constant value at compile time." ;; with the group symbol for each group and should return non-nil ;; if that group is to be included. ;; + ;; OP-FILTER selects the operators. It is either t to select all + ;; operators, a string to select all operators for which `string-match' + ;; matches the operator with the string, or a function which will be + ;; called with the operator and should return non-nil when the operator + ;; is to be selected. + ;; ;; If XLATE is given, it's a function which is called for each ;; matching operator and its return value is collected instead. ;; If it returns a list, the elements are spliced directly into @@ -1245,7 +1251,6 @@ operators." t "\\`<." (lambda (op) (substring op 1))))) - (c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp)) (c-lang-defconst c->-op-cont-tokens @@ -1264,7 +1269,6 @@ operators." ;; Regexp matching the second and subsequent characters of all ;; multicharacter tokens that begin with ">". t (c-make-keywords-re nil (c-lang-const c->-op-cont-tokens))) - (c-lang-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp)) (c-lang-defconst c->-op-without->-cont-regexp @@ -1279,10 +1283,19 @@ operators." "\\`>>" (lambda (op) (substring op 1))) :test 'string-equal))) - (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 ">>" + 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-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 @@ -3087,6 +3100,20 @@ expression is considered to be a type." ; generics is not yet coded in CC Mode. (c-lang-defvar c-recognize-<>-arglists (c-lang-const c-recognize-<>-arglists)) +(c-lang-defconst c-<>-notable-chars-re + "A regexp matching any single character notable inside a <...> construct. +This must include \"<\" and \">\", and should include \",\", and +any character which cannot be valid inside such a construct. +This is used in `c-forward-<>-arglist-recur' to try to detect +sequences of tokens which cannot be a template/generic construct. +When \"(\" is present, that defun will attempt to parse a +parenthesized expression inside the template. When \")\" is +present it will treat an unbalanced closing paren as a sign of +the invalidity of the putative template construct." + t "[<;{},|+&->)]" + c++ "[<;{},>()]") +(c-lang-defvar c-<>-notable-chars-re (c-lang-const c-<>-notable-chars-re)) + (c-lang-defconst c-enums-contain-decls "Non-nil means that an enum structure can contain declarations." t nil -- 2.39.2