Subject: bug#18845: 24.4; cc-mode derived modes broken because cl is used but not required

From: Stefan Monnier <[email-masked]>
Date: Wed, 29 Oct 2014 23:54:28 -0400

>   ; Symbol's function definition is void: set-difference
>   (c-lang-const c-matchers-2 c)

Indeed.  One way to solve these problems is to replace those calls with
calls to cl-set-difference.  Alan, what do you think?

>   ; Symbol's function definition is void: cl-macroexpand-all
>   (c-lang-defconst c-other-kwds t nil)

I fixed this one with the patch below,

>   (eval-when-compile
>     (if (and (= emacs-major-version 24) (= emacs-minor-version 4))
>       (require 'cl)))

It's pretty ugly, but yes that should work.

> would that be fine and won't there be a future 24.4 release that fixes
> this issue?

The 24.4 release is over, so no there won't be another 24.4.
And hopefully this will be fixed in 24.5.

        Stefan

=== modified file 'lisp/progmodes/cc-defs.el'
--- lisp/progmodes/cc-defs.el	2014-02-09 12:34:25 +0000
+++ lisp/progmodes/cc-defs.el	2014-10-30 03:46:48 +0000
@@ -169,6 +169,10 @@
 
   (put 'cc-eval-when-compile 'lisp-indent-hook 0))
 
+(eval-and-compile
+  (defalias 'c--macroexpand-all
+    (if (fboundp 'macroexpand-all)
+        'macroexpand-all 'cl-macroexpand-all)))
 
 ;;; Macros.
 
@@ -1834,12 +1838,9 @@
 immediately, i.e. at the same time as the `c-lang-defconst' form
 itself is evaluated."
   ;; Evaluate at macro expansion time, i.e. in the
-  ;; `cl-macroexpand-all' inside `c-lang-defconst'.
+  ;; `c--macroexpand-all' inside `c-lang-defconst'.
   (eval form))
 
-;; Only used at compile time - suppress "might not be defined at runtime".
-(declare-function cl-macroexpand-all "cl" (form &optional env))
-
 (defmacro c-lang-defconst (name &rest args)
   "Set the language specific values of the language constant NAME.
 The second argument can optionally be a docstring.  The rest of the
@@ -1881,7 +1882,7 @@
 
   (let* ((sym (intern (symbol-name name) c-lang-constants))
 	 ;; Make `c-lang-const' expand to a straightforward call to
-	 ;; `c-get-lang-constant' in `cl-macroexpand-all' below.
+	 ;; `c-get-lang-constant' in `c--macroexpand-all' below.
 	 ;;
 	 ;; (The default behavior, i.e. to expand to a call inside
 	 ;; `eval-when-compile' should be equivalent, since that macro
@@ -1944,7 +1945,7 @@
 	;; reason, but we also use this expansion handle
 	;; `c-lang-defconst-eval-immediately' and to register
 	;; dependencies on the `c-lang-const's in VAL.)
-	(setq val (cl-macroexpand-all val))
+	(setq val (c--macroexpand-all val))
 
 	(setq bindings (cons (cons assigned-mode val) bindings)
 	      args (cdr args))))

=== modified file 'lisp/progmodes/cc-langs.el'
--- lisp/progmodes/cc-langs.el	2014-06-14 23:54:39 +0000
+++ lisp/progmodes/cc-langs.el	2014-10-30 03:47:12 +0000
@@ -213,7 +213,6 @@
 ;; These are defined in cl as aliases to the cl- versions.
 ;(declare-function delete-duplicates "cl-seq" (cl-seq &rest cl-keys) t)
 ;(declare-function mapcan "cl-extra" (cl-func cl-seq &rest cl-rest) t)
-;(declare-function cl-macroexpand-all "cl" (form &optional env))
 
 (eval-and-compile
   ;; Some helper functions used when building the language constants.
@@ -3183,7 +3182,7 @@
       `(lambda ()
 
 	 ;; This let sets up the context for `c-mode-var' and similar
-	 ;; that could be in the result from `cl-macroexpand-all'.
+	 ;; that could be in the result from `c--macroexpand-all'.
 	 (let ((c-buffer-is-cc-mode ',mode)
 	       current-var source-eval)
 	   (c-make-emacs-variables-local)
@@ -3193,12 +3192,12 @@
 		   (setq ,@(let ((c-buffer-is-cc-mode mode)
 				 (c-lang-const-expansion 'immediate))
 			     ;; `c-lang-const' will expand to the evaluated
-			     ;; constant immediately in `cl-macroexpand-all'
+			     ;; constant immediately in `c--macroexpand-all'
 			     ;; below.
 			      (cl-mapcan
 			       (lambda (init)
 				 `(current-var ',(car init)
-				   ,(car init) ,(macroexpand-all
+				   ,(car init) ,(c--macroexpand-all
 						 (elt init 1))))
 			       ;; Note: The following `append' copies the
 			       ;; first argument.  That list is small, so