# HG changeset patch
# User Gene Harvey <gharveymn@gmail.com>
# Date 1562552474 18000
#      Sun Jul 07 21:21:14 2019 -0500
# Branch jitwork_includefix
# Node ID 6f8d07fd2e7b28b6f479cb628d37ff3e859787d3
# Parent  e2e895f8a6c2069a7f2f1e71fc145b14eb3637a6
fix llvm header conflicts between versions

* configure.ac: replace AC_CHECK_HEADER with
OCTAVE_CHECK_EXACT_HEADER.

* pt-jit.cc: surround includes with #if HAVE_ statements.

* acinclude.m4 (OCTAVE_CHECK_EXACT_HEADER,
OCTAVE_CHECK_EXACT_HEADERS): new macros.

diff -r e2e895f8a6c2 -r 6f8d07fd2e7b configure.ac
--- a/configure.ac	Thu Jun 27 00:49:30 2019 -0500
+++ b/configure.ac	Sun Jul 07 21:21:14 2019 -0500
@@ -1371,8 +1371,6 @@
   if test -z "$LLVM_CONFIG"; then
     warn_llvm="llvm-config utility not found.  JIT compiler is disabled."
   else
-    dnl Preset warning message in case compile fails
-    warn_llvm="LLVM was not found or is to old.  JIT compiler is disabled."
 
     save_CPPFLAGS="$CPPFLAGS"
     save_LDFLAGS="$LDFLAGS"
@@ -1396,48 +1394,39 @@
     dnl library by that name.
     LLVM_SO="LLVM-$($LLVM_CONFIG --version)"
 
+    CPPFLAGS="$LLVM_CPPFLAGS $CPPFLAGS"
+    LDFLAGS="$LLVM_LDFLAGS $LDFLAGS"
+
     dnl Check the guessed library. If it fails fall back to --libs.
     dnl Don't use --system-libs because earlier versions will link libedit
     dnl which conflicts with libreadline and will cause a crash at runtime.
     AC_CHECK_LIB([$LLVM_SO], [LLVMBuildAdd], [LLVM_LIBS="-l$LLVM_SO"],
-                 [LLVM_LIBS="$($LLVM_CONFIG --libs)"])
-
-    CPPFLAGS="$LLVM_CPPFLAGS $CPPFLAGS"
-    LDFLAGS="$LLVM_LDFLAGS $LDFLAGS"
-
-    dnl FIXME: Some of these may show warnings if LLVM is in the system
-    dnl path, but we are building with a different version of LLVM.
-    dnl The warnings don't appear to affect the final build.
-    dnl POTENTIAL FIX: Preappend the headers given to the check macros
-    dnl with $LLVM_INCLUDE_DIR/
+                 [warn_llvm="LLVM was not found or is to old.  JIT compiler is disabled."])
+
     AC_LANG_PUSH(C++)
-    AC_CHECK_HEADER([llvm/Support/TargetSelect.h], [warn_llvm=""])
-
-    have_function_h=no
-    AC_CHECK_HEADERS([llvm/IR/Function.h llvm/Function.h],
-                     [have_function_h=yes; break])
-    if test $have_function_h = no; then
-      warn_llvm="Missing LLVM file Function.h.  JIT compiler is disabled."
-    fi
-
-    have_irbuilder_h=no
-    AC_CHECK_HEADERS([llvm/Support/IRBuilder.h llvm/IR/IRBuilder.h \
-                      llvm/IRBuilder.h], [have_irbuilder_h=yes; break])
-    if test $have_irbuilder_h = no; then
-      warn_llvm="Missing LLVM file IRBuilder.h.  JIT compiler is disabled."
-    fi
-
-    have_llvm_data_h=no
-    AC_CHECK_HEADERS([llvm/Target/TargetData.h llvm/IR/DataLayout.h \
-                      llvm/DataLayout.h], [have_llvm_data_h=yes; break])
-    if test $have_llvm_data_h = no; then
-      warn_llvm="Missing LLVM file TargetData.h.  JIT compiler is disabled."
-    fi
-
-    AC_CHECK_HEADERS([llvm/IR/Verifier.h])
-    AC_CHECK_HEADERS([llvm/Analysis/BasicAliasAnalysis.h])
-    AC_CHECK_HEADERS([llvm/Transforms/Scalar/GVN.h])
-    AC_CHECK_HEADERS([llvm/Bitcode/ReaderWriter.h])
+    OCTAVE_CHECK_EXACT_HEADER([llvm], [llvm/Support/TargetSelect.h])
+
+    OCTAVE_CHECK_EXACT_HEADERS([llvm], [Function.h],
+                               [llvm/IR/Function.h llvm/Function.h])
+
+    OCTAVE_CHECK_EXACT_HEADERS([llvm], [IRBuilder.h],
+               [llvm/Support/IRBuilder.h llvm/IR/IRBuilder.h llvm/IRBuilder.h])
+
+    OCTAVE_CHECK_EXACT_HEADERS([llvm], [TargetData.h],
+             [llvm/Target/TargetData.h llvm/IR/DataLayout.h llvm/DataLayout.h])
+
+    OCTAVE_CHECK_EXACT_HEADER([llvm], [llvm/IR/Verifier.h])
+
+    OCTAVE_CHECK_EXACT_HEADER([llvm], [llvm/Analysis/BasicAliasAnalysis.h])
+
+    OCTAVE_CHECK_EXACT_HEADER([llvm], [llvm/Transforms/Scalar/GVN.h])
+
+    OCTAVE_CHECK_EXACT_HEADER([llvm], [llvm/Bitcode/ReaderWriter.h])
+
+    OCTAVE_CHECK_EXACT_HEADER([llvm],
+                              [llvm/Transforms/InstCombine/InstCombine.h])
+
+    OCTAVE_CHECK_EXACT_HEADER([llvm], [llvm/Transforms/Utils.h])
 
     OCTAVE_LLVM_FUNCTION_ADDATTRIBUTE_API
     OCTAVE_LLVM_FUNCTION_ADDFNATTR_API
diff -r e2e895f8a6c2 -r 6f8d07fd2e7b libinterp/parse-tree/pt-jit.cc
--- a/libinterp/parse-tree/pt-jit.cc	Thu Jun 27 00:49:30 2019 -0500
+++ b/libinterp/parse-tree/pt-jit.cc	Sun Jul 07 21:21:14 2019 -0500
@@ -123,8 +123,13 @@
 #  include <llvm/Transforms/Scalar/GVN.h>
 #endif
 
-#include <llvm/Transforms/InstCombine/InstCombine.h>
-#include <llvm/Transforms/Utils.h>
+#if defined (HAVE_LLVM_TRANSFORMS_INSTCOMBINE_INSTCOMBINE_H)
+#  include <llvm/Transforms/InstCombine/InstCombine.h>
+#endif
+
+#if defined (HAVE_LLVM_TRANSFORMS_UTILS_H)
+#  include <llvm/Transforms/Utils.h>
+#endif
 
 static bool Vdebug_jit = false;
 
diff -r e2e895f8a6c2 -r 6f8d07fd2e7b m4/acinclude.m4
--- a/m4/acinclude.m4	Thu Jun 27 00:49:30 2019 -0500
+++ b/m4/acinclude.m4	Sun Jul 07 21:21:14 2019 -0500
@@ -2638,6 +2638,87 @@
   fi
 ])
 dnl
+dnl OCTAVE_CHECK_EXACT_HEADER(LIBRARY ($1), RELATIVE_PATH ($2),
+dnl                           INCLUDE_DIR ($3), IFTRUE ($4), IFFALSE ($5))
+dnl
+dnl Check for a header with an exact path. The relative path is concatenated
+dnl with the include directory to prevent shadowing from the system include
+dnl path.
+dnl
+dnl Usage:
+dnl   # if LLVM_INCLUDE_DIR is defined
+dnl   OCTAVE_CHECK_EXACT_HEADER(llvm, [llvm/IR/Function.h], [],
+dnl                             [AC_MSG_NOTICE([Function.h found])],
+dnl                             [AC_MSG_NOTICE([Function.h not found])])
+dnl
+dnl   # otherwise specify the include directory in INCLUDE_DIR
+dnl   OCTAVE_CHECK_EXACT_HEADER([], [llvm/IR/Function.h], [/opt/llvm4/include],
+dnl                             [AC_MSG_NOTICE([Function.h found])],
+dnl                             [AC_MSG_NOTICE([Function.h not found])])
+dnl
+dnl LIBRARY       - The library of the header. This should be the same as the
+dnl                 first argument to OCTAVE_CHECK_LIB.
+dnl RELATIVE_PATH - Path relative to the include directory
+dnl                 Example: [llvm/IR/Function.h]
+dnl INCLUDE_DIR   - Parent of the relative path. So if INCLUDE_DIR=[/foo]
+dnl                 and RELATIVE_PATH=[bar/baz.h], then the macro will
+dnl                 search at /foo/bar/baz.h for the header. If LIBRARY is
+dnl                 given and this is not, then the expansion of
+dnl                 <LIBRARY>_INCLUDE_DIR is used instead.
+dnl IFTRUE        - Commands to run if the header is found.
+dnl IFFALSE       - Commands to run if the header is not found.
+dnl
+dnl Note: Defines HAVE_<RELATIVE_PATH> if the header is found.
+dnl   Example: if llvm/IR/Function.h is found then HAVE_LLVM_IR_FUNCTION_H
+dnl            will be defined.
+dnl
+AC_DEFUN([OCTAVE_CHECK_EXACT_HEADER], [
+  ifelse([$3], , [octave_cv_include_dir="$m4_toupper($1)_INCLUDE_DIR"],
+         [octave_cv_include_dir=$3])
+  AC_CHECK_HEADER([$octave_cv_include_dir/$2],
+                  [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$2]), [1], [\
+Define to 1 if you have the <$2> header file]) $4], [$5])dnl
+])dnl
+dnl
+dnl OCTAVE_CHECK_EXACT_HEADERS(LIBRARY ($1), FILENAME ($2),
+dnl                            RELATIVE_PATHS ($3), INCLUDE_DIR ($4),
+dnl                            IFTRUE ($5), IFFALSE ($6))
+dnl
+dnl Search for header in multiple possible paths.
+dnl
+dnl LIBRARY        - The library of the headers. This should be the same as the
+dnl                  first argument to OCTAVE_CHECK_LIB.
+dnl FILENAME       - The filename. Used for the warn message.
+dnl RELATIVE_PATHS - Paths at which the header might be found.
+dnl                    Example: [llvm/IR/Function.h llvm/Function.h]
+dnl INCLUDE_DIR    - Parent of the relative paths. So if INCLUDE_DIR=[/foo]
+dnl                  and RELATIVE_PATHS=[bar/baz1.h bar/baz2.h], then the
+dnl                  macro will search at /foo/bar/baz1.h and /foo/bar/baz2.h
+dnl                  for the header. If LIBRARY is given and this is not, then
+dnl                  the expansion of <LIBRARY>_INCLUDE_DIR is used.
+dnl IFTRUE         - Commands to run if the header is found (runs once).
+dnl IFFALSE        - Commands to run if the header is not found (runs once).
+dnl
+dnl Note: Sets warn_$1 if the header is not found.
+dnl
+AC_DEFUN([OCTAVE_CHECK_EXACT_HEADERS], [
+  AS_VAR_PUSHDEF([octave_exact_header], [octave_cv_header_$2])dnl
+  AS_VAR_SET([octave_exact_header], [no])
+
+AH_CHECK_HEADERS([$3])dnl
+for ac_header in $3
+do
+OCTAVE_CHECK_EXACT_HEADER([$1], $ac_header, [$4],
+                          [AS_VAR_SET([octave_exact_header], [yes]); break],
+                          [])dnl
+done
+  AS_VAR_IF([octave_exact_header], [yes],
+            ifelse([$5], , , [$5]),
+            [warn_$1="Missing LLVM file $2."
+             ifelse([$6], , , [$6])])dnl
+  AS_VAR_POPDEF([octave_exact_header])dnl
+])dnl
+dnl
 dnl Check for CallInst::addAttribute API
 dnl
 AC_DEFUN([OCTAVE_LLVM_CALLINST_ADDATTRIBUTE_API], [
