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.
This commit is contained in:
parent
44b16f60fd
commit
02b037b85c
2 changed files with 42 additions and 5 deletions
|
@ -6056,7 +6056,10 @@ comment at the start of cc-engine.el for more info."
|
||||||
;; Stop on ',', '|', '&', '+' and '-' to catch
|
;; Stop on ',', '|', '&', '+' and '-' to catch
|
||||||
;; common binary operators that could be between
|
;; common binary operators that could be between
|
||||||
;; two comparison expressions "a<b" and "c>d".
|
;; two comparison expressions "a<b" and "c>d".
|
||||||
"[<;{},|+&-]\\|[>)]"
|
;; 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))
|
nil t t))
|
||||||
|
|
||||||
(cond
|
(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
|
;; Either an operator starting with '>' or the end of
|
||||||
;; the angle bracket arglist.
|
;; 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
|
(progn
|
||||||
(goto-char (match-end 0))
|
(goto-char (match-end 0))
|
||||||
t) ; Continue the loop.
|
t) ; Continue the loop.
|
||||||
|
@ -6134,6 +6139,11 @@ comment at the start of cc-engine.el for more info."
|
||||||
)))
|
)))
|
||||||
t) ; carry on looping.
|
t) ; carry on looping.
|
||||||
|
|
||||||
|
((and
|
||||||
|
(eq (char-before) ?\()
|
||||||
|
(c-go-up-list-forward)
|
||||||
|
(eq (char-before) ?\))))
|
||||||
|
|
||||||
((and (not c-restricted-<>-arglists)
|
((and (not c-restricted-<>-arglists)
|
||||||
(or (and (eq (char-before) ?&)
|
(or (and (eq (char-before) ?&)
|
||||||
(not (eq (char-after) ?&)))
|
(not (eq (char-after) ?&)))
|
||||||
|
|
|
@ -228,6 +228,12 @@ the evaluated constant value at compile time."
|
||||||
;; with the group symbol for each group and should return non-nil
|
;; with the group symbol for each group and should return non-nil
|
||||||
;; if that group is to be included.
|
;; 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
|
;; If XLATE is given, it's a function which is called for each
|
||||||
;; matching operator and its return value is collected instead.
|
;; matching operator and its return value is collected instead.
|
||||||
;; If it returns a list, the elements are spliced directly into
|
;; If it returns a list, the elements are spliced directly into
|
||||||
|
@ -1245,7 +1251,6 @@ operators."
|
||||||
t
|
t
|
||||||
"\\`<."
|
"\\`<."
|
||||||
(lambda (op) (substring op 1)))))
|
(lambda (op) (substring op 1)))))
|
||||||
|
|
||||||
(c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp))
|
(c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp))
|
||||||
|
|
||||||
(c-lang-defconst c->-op-cont-tokens
|
(c-lang-defconst c->-op-cont-tokens
|
||||||
|
@ -1264,7 +1269,6 @@ operators."
|
||||||
;; Regexp matching the second and subsequent characters of all
|
;; Regexp matching the second and subsequent characters of all
|
||||||
;; multicharacter tokens that begin with ">".
|
;; multicharacter tokens that begin with ">".
|
||||||
t (c-make-keywords-re nil (c-lang-const c->-op-cont-tokens)))
|
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-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp))
|
||||||
|
|
||||||
(c-lang-defconst c->-op-without->-cont-regexp
|
(c-lang-defconst c->-op-without->-cont-regexp
|
||||||
|
@ -1279,10 +1283,19 @@ operators."
|
||||||
"\\`>>"
|
"\\`>>"
|
||||||
(lambda (op) (substring op 1)))
|
(lambda (op) (substring op 1)))
|
||||||
:test 'string-equal)))
|
:test 'string-equal)))
|
||||||
|
|
||||||
(c-lang-defvar c->-op-without->-cont-regexp
|
(c-lang-defvar c->-op-without->-cont-regexp
|
||||||
(c-lang-const 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
|
(c-lang-defconst c-stmt-delim-chars
|
||||||
;; The characters that should be considered to bound statements. To
|
;; The characters that should be considered to bound statements. To
|
||||||
;; optimize `c-crosses-statement-barrier-p' somewhat, it's assumed 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.
|
; generics is not yet coded in CC Mode.
|
||||||
(c-lang-defvar c-recognize-<>-arglists (c-lang-const c-recognize-<>-arglists))
|
(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
|
(c-lang-defconst c-enums-contain-decls
|
||||||
"Non-nil means that an enum structure can contain declarations."
|
"Non-nil means that an enum structure can contain declarations."
|
||||||
t nil
|
t nil
|
||||||
|
|
Loading…
Add table
Reference in a new issue