Subject: [PATCH] Avoid defining (temporarily) vars and functions

From: Stefan Monnier <[email-masked]>
Date: Fri, 11 Sep 2015 23:36:45 -0400

Package: Emacs
Version: 25.0.50

CC-mode currently defines various non-CC-mode variables and functions
with dummy values, as a way to avoid byte-compiler warnings when using
those external vars/functions.

Since this is dangerous business, CC-mode has to be extra careful to
undo such settings when they're not needed any more.

It might have made sense back in the days when the byte-compiler did not
offer built-in ways to silence those warnings, but nowadays we can
do better.

Any objections to the patch below (which also removes the unused
cc-bytecomp-put, while we're at it)?

        Stefan

2015-09-12  Stefan Monnier  <[email-masked]>

	* lisp/progmodes/cc-bytecomp.el: Use newer compiler-silencers.
	(cc-bytecomp-defvar): Use just (defvar <foo>) when that is known to
	silence the byte-compiler warnings.
	(cc-bytecomp-defun): Use just (declare-function <foo>) when that is
	known to silence the byte-compiler warnings.
	(cc-bytecomp-boundp, cc-bytecomp-fboundp): Change accordingly.
	(cc-bytecomp-put): Remove, unused.
	(cc-bytecomp-original-properties): Remove var.
	(cc-bytecomp-setup-environment, cc-bytecomp-restore-environment):
	Don't use cc-bytecomp-original-properties any more.

diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el
index 81b7a82..fff2a9e 100644
--- a/lisp/progmodes/cc-bytecomp.el
+++ b/lisp/progmodes/cc-bytecomp.el
@@ -75,12 +75,10 @@
 
 (defvar cc-bytecomp-unbound-variables nil)
 (defvar cc-bytecomp-original-functions nil)
-(defvar cc-bytecomp-original-properties nil)
 (defvar cc-bytecomp-loaded-files nil)
 
 (setq cc-bytecomp-unbound-variables nil)
 (setq cc-bytecomp-original-functions nil)
-(setq cc-bytecomp-original-properties nil)
 (setq cc-bytecomp-loaded-files nil)
 
 (defvar cc-bytecomp-environment-set nil)
@@ -173,16 +171,6 @@ perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere"))
 		  (cc-bytecomp-debug-msg
 		   "cc-bytecomp-setup-environment: Covered function %s" fun))))
 	  (setq p (cdr p)))
-	(setq p cc-bytecomp-original-properties)
-	(while p
-	  (let ((sym (car (car (car p))))
-		(prop (cdr (car (car p))))
-		(tempdef (car (cdr (car p)))))
-	    (put sym prop tempdef)
-	    (cc-bytecomp-debug-msg
-	     "cc-bytecomp-setup-environment: Bound property %s for %s to %s"
-	     prop sym tempdef))
-	  (setq p (cdr p)))
 	(setq cc-bytecomp-environment-set t)
 	(cc-bytecomp-debug-msg
 	 "cc-bytecomp-setup-environment: Done"))))
@@ -232,22 +220,6 @@ perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere"))
 		   "cc-bytecomp-restore-environment: Not restoring function %s"
 		   fun))))
 	  (setq p (cdr p)))
-	(setq p cc-bytecomp-original-properties)
-	(while p
-	  (let ((sym (car (car (car p))))
-		(prop (cdr (car (car p))))
-		(tempdef (car (cdr (car p))))
-		(origdef (cdr (cdr (car p)))))
-	    (if (eq (get sym prop) tempdef)
-		(progn
-		  (put sym prop origdef)
-		  (cc-bytecomp-debug-msg
-		   "cc-bytecomp-restore-environment: Restored property %s for %s to %s"
-		   prop sym origdef))
-	      (cc-bytecomp-debug-msg
-	       "cc-bytecomp-restore-environment: Not restoring property %s for %s"
-	       prop sym)))
-	  (setq p (cdr p)))
 	(setq cc-bytecomp-environment-set nil)
 	(cc-bytecomp-debug-msg
 	 "cc-bytecomp-restore-environment: Done"))))
@@ -348,25 +320,28 @@ afterwards.  Don't use within `eval-when-compile'."
      (eval-when-compile (cc-bytecomp-setup-environment))))
 
 (defmacro cc-bytecomp-defvar (var)
-  "Binds the symbol as a variable during compilation of the file,
+  "Bind the symbol as a variable during compilation of the file,
 to silence the byte compiler.  Don't use within `eval-when-compile'."
-  `(eval-when-compile
-     (if (boundp ',var)
-	 (cc-bytecomp-debug-msg
-	  "cc-bytecomp-defvar: %s bound already as variable" ',var)
-       (if (not (memq ',var cc-bytecomp-unbound-variables))
-	   (progn
-	     (cc-bytecomp-debug-msg
-	      "cc-bytecomp-defvar: Saving %s (as unbound)" ',var)
-	     (setq cc-bytecomp-unbound-variables
-		   (cons ',var cc-bytecomp-unbound-variables))))
-       (if (cc-bytecomp-is-compiling)
-	   (progn
-	     (defvar ,var)
-	     (set ',var (intern (concat "cc-bytecomp-ignore-var:"
-					(symbol-name ',var))))
-	     (cc-bytecomp-debug-msg
-	      "cc-bytecomp-defvar: Covered variable %s" ',var))))))
+  (if (not (featurep 'xemacs))
+      `(defvar ,var)
+    ;; Not sure if XEmacs's ‘defvar’ works in the same way.
+    `(eval-when-compile
+       (if (boundp ',var)
+	   (cc-bytecomp-debug-msg
+	    "cc-bytecomp-defvar: %s bound already as variable" ',var)
+	 (if (not (memq ',var cc-bytecomp-unbound-variables))
+	     (progn
+	       (cc-bytecomp-debug-msg
+		"cc-bytecomp-defvar: Saving %s (as unbound)" ',var)
+	       (setq cc-bytecomp-unbound-variables
+		     (cons ',var cc-bytecomp-unbound-variables))))
+	 (if (cc-bytecomp-is-compiling)
+	     (progn
+	       (defvar ,var)
+	       (set ',var (intern (concat "cc-bytecomp-ignore-var:"
+					  (symbol-name ',var))))
+	       (cc-bytecomp-debug-msg
+		"cc-bytecomp-defvar: Covered variable %s" ',var)))))))
 
 (defmacro cc-bytecomp-defun (fun)
   "Bind the symbol as a function during compilation of the file,
@@ -377,48 +352,33 @@ definition.  That means that this macro will not shut up warnings
 about incorrect number of arguments.  It's dangerous to try to replace
 existing functions since the byte compiler might need the definition
 at compile time, e.g. for macros and inline functions."
-  `(eval-when-compile
-     (if (fboundp ',fun)
-	 (cc-bytecomp-debug-msg
-	  "cc-bytecomp-defun: %s bound already as function" ',fun)
-       (if (not (assq ',fun cc-bytecomp-original-functions))
-	   (progn
-	     (cc-bytecomp-debug-msg
-	      "cc-bytecomp-defun: Saving %s (as unbound)" ',fun)
-	     (setq cc-bytecomp-original-functions
-		   (cons (list ',fun nil 'unbound)
-			 cc-bytecomp-original-functions))))
-       (if (cc-bytecomp-is-compiling)
-	   (progn
-	     (fset ',fun (intern (concat "cc-bytecomp-ignore-fun:"
-					 (symbol-name ',fun))))
-	     (cc-bytecomp-debug-msg
-	      "cc-bytecomp-defun: Covered function %s" ',fun))))))
-
-(defmacro cc-bytecomp-put (symbol propname value)
-  "Set a property on a symbol during compilation (and evaluation) of
-the file.  Don't use outside `eval-when-compile'."
-  `(eval-when-compile
-     (if (not (assoc (cons ,symbol ,propname) cc-bytecomp-original-properties))
-	 (progn
+  (if (fboundp 'declare-function)
+      `(declare-function ,fun nil)
+    `(eval-when-compile
+       (if (fboundp ',fun)
 	   (cc-bytecomp-debug-msg
-	    "cc-bytecomp-put: Saving property %s for %s with value %s"
-	    ,propname ,symbol (get ,symbol ,propname))
-	   (setq cc-bytecomp-original-properties
-		 (cons (cons (cons ,symbol ,propname)
-			     (cons ,value (get ,symbol ,propname)))
-		       cc-bytecomp-original-properties))))
-     (put ,symbol ,propname ,value)
-     (cc-bytecomp-debug-msg
-      "cc-bytecomp-put: Bound property %s for %s to %s"
-      ,propname ,symbol ,value)))
+	    "cc-bytecomp-defun: %s bound already as function" ',fun)
+	 (if (not (assq ',fun cc-bytecomp-original-functions))
+	     (progn
+	       (cc-bytecomp-debug-msg
+		"cc-bytecomp-defun: Saving %s (as unbound)" ',fun)
+	       (setq cc-bytecomp-original-functions
+		     (cons (list ',fun nil 'unbound)
+			   cc-bytecomp-original-functions))))
+	 (if (cc-bytecomp-is-compiling)
+	     (progn
+	       (fset ',fun (intern (concat "cc-bytecomp-ignore-fun:"
+					   (symbol-name ',fun))))
+	       (cc-bytecomp-debug-msg
+		"cc-bytecomp-defun: Covered function %s" ',fun)))))))
 
 (defmacro cc-bytecomp-boundp (symbol)
   "Return non-nil if the given symbol is bound as a variable outside
 the compilation.  This is the same as using `boundp' but additionally
 exclude any variables that have been bound during compilation with
 `cc-bytecomp-defvar'."
-  (if (and (cc-bytecomp-is-compiling)
+  (if (and (featurep 'xemacs)
+	   (cc-bytecomp-is-compiling)
 	   (memq (car (cdr symbol)) cc-bytecomp-unbound-variables))
       nil
     `(boundp ,symbol)))
@@ -429,7 +389,8 @@ the compilation.  This is the same as using `fboundp' but additionally
 exclude any functions that have been bound during compilation with
 `cc-bytecomp-defun'."
   (let (fun-elem)
-    (if (and (cc-bytecomp-is-compiling)
+    (if (and (not (fboundp 'declare-function))
+	     (cc-bytecomp-is-compiling)
 	     (setq fun-elem (assq (car (cdr symbol))
 				  cc-bytecomp-original-functions))
 	     (eq (elt fun-elem 2) 'unbound))