From 7f0de07b3ac67370bfe78faac9c6bffdd90d55ce Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Tue, 6 Aug 2019 16:49:29 +0000 Subject: [PATCH] C++ Mode: Prevent End of statement being found after {} in "count << vec{} <<" * lisp/progmodes/cc-engine.el (c-beginning-of-statement-1): Check for operators which cannot start a statement, which may follow a closing brace. Don't recognise an end of statement in such a case. * lisp/progmodes/cc-langs.el (c-operator-re, c-bin-tern-operators) (c-unary-operators, c-non-after-{}-operators, c-non-after-{}-ops-re): New lang consts and vars. --- lisp/progmodes/cc-engine.el | 18 +++++++++++++++++- lisp/progmodes/cc-langs.el | 30 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index a095277989a..29ebe2eea1f 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -1227,7 +1227,23 @@ comment at the start of cc-engine.el for more info." (not (looking-at c-opt-block-decls-with-vars-key)) (or comma-delim - (not (eq (char-after) ?\,))))))) + (not (eq (char-after) ?\,)))))) + ;; Is the {..} followed by an operator which + ;; prevents it being a statement in its own right? + (save-excursion + (and + (c-go-list-forward) + (progn + (c-forward-syntactic-ws) + (or + (not (looking-at c-non-after-{}-ops-re)) + (let + ((bad-op-len + (- (match-end 0) (match-beginning 0)))) + (and + (looking-at c-operator-re) + (> (- (match-end 0) (match-beginning 0)) + bad-op-len)))))))) (save-excursion (c-forward-sexp) (point))) ;; Just gone back over some paren block? diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 9d36f8f9e49..6ba14a8229b 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -1205,6 +1205,36 @@ since CC Mode treats every identifier as an expression." ;; The operators as a flat list (without duplicates). t (c-filter-ops (c-lang-const c-operators) t t)) +(c-lang-defconst c-operator-re + ;; A regexp which matches any operator. + t (regexp-opt (c-lang-const c-operator-list))) +(c-lang-defvar c-operator-re (c-lang-const c-operator-re)) + +(c-lang-defconst c-bin-tern-operators + ;; All binary and ternary operators + t (c-filter-ops (c-lang-const c-operators) + '(left-assoc right-assoc right-assoc-sequence) + t)) + +(c-lang-defconst c-unary-operators + ;; All unary operators. + t (c-filter-ops (c-lang-const c-operators) + '(prefix postfix postfix-if-paren) + t)) + +(c-lang-defconst c-non-after-{}-operators + "Operators which can't appear after a block {..} construct." + t (c--set-difference (c-lang-const c-bin-tern-operators) + (c-lang-const c-unary-operators) + :test #'string-equal) + awk (remove "/" (c-lang-const c-non-after-{}-operators))) + +(c-lang-defconst c-non-after-{}-ops-re + ;; A regexp matching operators which can't appear after a block {..} + ;; construct. + t (regexp-opt (c-lang-const c-non-after-{}-operators))) +(c-lang-defvar c-non-after-{}-ops-re (c-lang-const c-non-after-{}-ops-re)) + (c-lang-defconst c-overloadable-operators "List of the operators that are overloadable, in their \"identifier form\". See also `c-op-identifier-prefix'." -- 2.39.2