From 735c8b516e09ecd056563569fb132e5ca56810d7 Mon Sep 17 00:00:00 2001
From: Alan Mackenzie <acm@muc.de>
Date: Tue, 21 Nov 2017 18:06:11 +0000
Subject: [PATCH] Make c-defun-name analyze more thoroughly a function type
 which is a struct

This fixes bug #29293.

* lisp/progmodes/cc-cmds.el (c-defun-name): When a struct (etc.) type is
encountered, check whether it is the return type of a function rather than a
declaration of the struct itself.  Similarly adapt the cond arm which deals
with functions properly to recognize struct return types.
---
 lisp/progmodes/cc-cmds.el | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 2b663135932..471560e19d4 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1849,7 +1849,15 @@ with a brace block."
 	  ;; Pick out the defun name, according to the type of defun.
 	  (cond
 	   ;; struct, union, enum, or similar:
-	   ((looking-at c-type-prefix-key)
+	   ((save-excursion
+	      (and
+	       (looking-at c-type-prefix-key)
+	       (consp (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil))
+	       (or (not (or (eq (char-after) ?{)
+			    (and c-recognize-knr-p
+				 (c-in-knr-argdecl))))
+		   (progn (c-backward-syntactic-ws)
+			  (not (eq (char-before) ?\)))))))
 	    (let ((key-pos (point)))
 	      (c-forward-over-token-and-ws) ; over "struct ".
 	      (cond
@@ -1897,8 +1905,16 @@ with a brace block."
 
 	   (t
 	    ;; Normal function or initializer.
-	    (when (c-syntactic-re-search-forward "[{(]" nil t)
-	      (backward-char)
+	    (when
+		(and
+		 (consp (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil))
+		 (or (eq (char-after) ?{)
+		     (and c-recognize-knr-p
+			  (c-in-knr-argdecl)))
+		 (progn
+		   (c-backward-syntactic-ws)
+		   (eq (char-before) ?\)))
+		 (c-go-list-backward))
 	      (c-backward-syntactic-ws)
 	      (when (eq (char-before) ?\=) ; struct foo bar = {0, 0} ;
 		(c-backward-token-2)
-- 
2.39.5