aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2020-09-12 16:37:56 +0000
committerAlan Mackenzie2020-09-12 16:37:56 +0000
commit62f239eec2be42d857cc91009b4b7d8c8cf31b4e (patch)
tree0a9c9fdafc5672803fa696e4ae9286857a6fb4aa
parentd228cac2e8d7026231daf1c97fb37279d61420a9 (diff)
downloademacs-62f239eec2be42d857cc91009b4b7d8c8cf31b4e.tar.gz
emacs-62f239eec2be42d857cc91009b4b7d8c8cf31b4e.zip
C++ Mode: handle __attribute__,etc. inside constructor argument lists
This corrects both the fontification and indentation of these things, fixing bug #42270. * lisp/progmodes/cc-engine.el (c-do-declarators): Skip over "hangon keys" and noise macros whilst scanning a putative C++ function. (c-forward-decl-or-cast-1): When checking for typeless functions, skip over "hangon keys" and noise macros. * lisp/progmodes/cc-mode.el (c-fl-decl-end): Deal with certain invalid "nested declarators" by scanning over them with a recursive call of c-fl-decl-end. * lisp/progmodes/cc-vars.el (c-noise-macro-names) (c-noise-macro-with-parens-names): State in the doc strings that if either of these is a regexp, it must have a submatch 1 which matches the noise macro exactly.
-rw-r--r--lisp/progmodes/cc-engine.el18
-rw-r--r--lisp/progmodes/cc-mode.el34
-rw-r--r--lisp/progmodes/cc-vars.el6
3 files changed, 48 insertions, 10 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 7ff424c6a7e..7d10027c76f 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -2238,7 +2238,7 @@ comment at the start of cc-engine.el for more info."
2238 2238
2239 ((and c-opt-cpp-prefix 2239 ((and c-opt-cpp-prefix
2240 (looking-at c-noise-macro-name-re)) 2240 (looking-at c-noise-macro-name-re))
2241 ;; Skip over a noise macro. 2241 ;; Skip over a noise macro without parens.
2242 (goto-char (match-end 1)) 2242 (goto-char (match-end 1))
2243 (not (eobp))) 2243 (not (eobp)))
2244 2244
@@ -9130,6 +9130,12 @@ This function might do hidden buffer changes."
9130 (catch 'is-function 9130 (catch 'is-function
9131 (while 9131 (while
9132 (progn 9132 (progn
9133 (while
9134 (cond
9135 ((looking-at c-decl-hangon-key)
9136 (c-forward-keyword-clause 1))
9137 ((looking-at c-noise-macro-with-parens-name-re)
9138 (c-forward-noise-clause))))
9133 (if (eq (char-after) ?\)) 9139 (if (eq (char-after) ?\))
9134 (throw 'is-function t)) 9140 (throw 'is-function t))
9135 (setq cdd-got-type (c-forward-type)) 9141 (setq cdd-got-type (c-forward-type))
@@ -9782,6 +9788,16 @@ This function might do hidden buffer changes."
9782 (save-excursion 9788 (save-excursion
9783 (goto-char after-paren-pos) 9789 (goto-char after-paren-pos)
9784 (c-forward-syntactic-ws) 9790 (c-forward-syntactic-ws)
9791 (progn
9792 (while
9793 (cond
9794 ((and
9795 c-opt-cpp-prefix
9796 (looking-at c-noise-macro-with-parens-name-re))
9797 (c-forward-noise-clause))
9798 ((looking-at c-decl-hangon-key)
9799 (c-forward-keyword-clause 1))))
9800 t)
9785 (or (c-forward-type) 9801 (or (c-forward-type)
9786 ;; Recognize a top-level typeless 9802 ;; Recognize a top-level typeless
9787 ;; function declaration in C. 9803 ;; function declaration in C.
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 73275cfa621..c6dd671051d 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -2266,7 +2266,8 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
2266(defun c-fl-decl-end (pos) 2266(defun c-fl-decl-end (pos)
2267 ;; If POS is inside a declarator, return the end of the token that follows 2267 ;; If POS is inside a declarator, return the end of the token that follows
2268 ;; the declarator, otherwise return nil. POS being in a literal does not 2268 ;; the declarator, otherwise return nil. POS being in a literal does not
2269 ;; count as being in a declarator (on pragmatic grounds). 2269 ;; count as being in a declarator (on pragmatic grounds). POINT is not
2270 ;; preserved.
2270 (goto-char pos) 2271 (goto-char pos)
2271 (let ((lit-start (c-literal-start)) 2272 (let ((lit-start (c-literal-start))
2272 enclosing-attribute pos1) 2273 enclosing-attribute pos1)
@@ -2279,12 +2280,31 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
2279 (let ((lim (save-excursion 2280 (let ((lim (save-excursion
2280 (and (c-beginning-of-macro) 2281 (and (c-beginning-of-macro)
2281 (progn (c-end-of-macro) (point)))))) 2282 (progn (c-end-of-macro) (point))))))
2282 (when (and (c-forward-declarator lim) 2283 (and (c-forward-declarator lim)
2283 (or (not (eq (char-after) ?\()) 2284 (if (eq (char-after) ?\()
2284 (c-go-list-forward nil lim)) 2285 (and
2285 (eq (c-forward-token-2 1 nil lim) 0)) 2286 (c-go-list-forward nil lim)
2286 (c-backward-syntactic-ws) 2287 (progn (c-forward-syntactic-ws lim)
2287 (point))))))) 2288 (not (eobp)))
2289 (progn
2290 (if (looking-at c-symbol-char-key)
2291 ;; Deal with baz (foo((bar)) type var), where
2292 ;; foo((bar)) is not semantically valid. The result
2293 ;; must be after var).
2294 (and
2295 (goto-char pos)
2296 (setq pos1 (c-on-identifier))
2297 (goto-char pos1)
2298 (progn
2299 (c-backward-syntactic-ws)
2300 (eq (char-before) ?\())
2301 (c-fl-decl-end (1- (point))))
2302 (c-backward-syntactic-ws)
2303 (point))))
2304 (and (progn (c-forward-syntactic-ws lim)
2305 (not (eobp)))
2306 (c-backward-syntactic-ws)
2307 (point)))))))))
2288 2308
2289(defun c-change-expand-fl-region (_beg _end _old-len) 2309(defun c-change-expand-fl-region (_beg _end _old-len)
2290 ;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock 2310 ;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index b885f6ae1d8..9e6f9527ca1 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1670,7 +1670,8 @@ indented as a statement."
1670like \"INLINE\" which are syntactic noise. Such a macro/extension is complete 1670like \"INLINE\" which are syntactic noise. Such a macro/extension is complete
1671in itself, never having parentheses. All these names must be syntactically 1671in itself, never having parentheses. All these names must be syntactically
1672valid identifiers. Alternatively, this variable may be a regular expression 1672valid identifiers. Alternatively, this variable may be a regular expression
1673which matches the names of such macros. 1673which matches the names of such macros, in which case it must have a submatch
16741 which matches the actual noise macro name.
1674 1675
1675If you change this variable's value, call the function 1676If you change this variable's value, call the function
1676`c-make-noise-macro-regexps' to set the necessary internal variables (or do 1677`c-make-noise-macro-regexps' to set the necessary internal variables (or do
@@ -1686,7 +1687,8 @@ this implicitly by reinitializing C/C++/Objc Mode on any buffer)."
1686which optionally have arguments in parentheses, and which expand to nothing. 1687which optionally have arguments in parentheses, and which expand to nothing.
1687All these names must be syntactically valid identifiers. These are recognized 1688All these names must be syntactically valid identifiers. These are recognized
1688by CC Mode only in declarations. Alternatively, this variable may be a 1689by CC Mode only in declarations. Alternatively, this variable may be a
1689regular expression which matches the names of such macros. 1690regular expression which matches the names of such macros, in which case it
1691must have a submatch 1 which matches the actual noise macro name.
1690 1692
1691If you change this variable's value, call the function 1693If you change this variable's value, call the function
1692`c-make-noise-macro-regexps' to set the necessary internal variables (or do 1694`c-make-noise-macro-regexps' to set the necessary internal variables (or do