llvm-data-interop (empty) → 0.3.0
raw patch · 11 files changed
+10735/−0 lines, 11 filesdep +arraydep +basedep +bytestringbuild-type:Customsetup-changed
Dependencies added: array, base, bytestring, containers, data-default, deepseq, dwarf, hashable, hashtables, llvm-base-types, loch-th, mtl, text, transformers, unification-fd, unordered-containers, vector
Files
- LICENSE +30/−0
- README.md +37/−0
- Setup.hs +20/−0
- configure +4555/−0
- llvm-data-interop.buildinfo.in +7/−0
- llvm-data-interop.cabal +50/−0
- src/LLVM/Internal/Interop.chs +644/−0
- src/LLVM/Internal/TypeUnification.hs +416/−0
- src/LLVM/Parse.hs +1862/−0
- src/c++/marshal.cpp +2673/−0
- src/c++/marshal.h +441/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Tristan Ravitch++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Tristan Ravitch nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,37 @@+This package converts the LLVM IR (either bitcode files or LLVM+assembly) into a Haskell data type (defined in llvm-base-types). The+conversion uses the LLVM libraries to read bitcode. It then traverses+the IR and produces a Haskell structure that can be pattern matched+against in pure code.++After the conversion, no C++ data is referenced and no C++ code is+called. This library does link against LLVM directly, and therefore+also uses libstdc++. This can make linking tricky sometimes. For+example, mixing template-haskell with C++-linked code does not seem to+work.++Note that this library only works with LLVM 3.0-3.3, and will try to+retain as much compatibility with future and past versions as is+reasonable.++# Installation Notes++ * Currently, this library is set up to link against the LLVM shared+ library (libLLVM-3.X.so). Most distro packages build the LLVM+ shared library. If you make a custom build, be sure to configure+ with `--enable-shared`.++## Debian and Ubuntu++You need the development libraries and headers, so be sure to install+the llvm-3.X-dev package, where X is the version you would like to+use. You will also need clang.++# Changes++## v0.3.0++ * Support LLVM-3.3 (contributed by Patrick Hulin)+ * Minor breaking change in MetaDW*Type. These no longer have a+ MetaDWFile; instead, they directly contain their file and directory+ information.
+ Setup.hs view
@@ -0,0 +1,20 @@+import Distribution.Simple+import Distribution.Simple.LocalBuildInfo+import Distribution.Simple.PackageIndex+import Distribution.Simple.Setup+import Distribution.Simple.UserHooks+import Distribution.PackageDescription++import Data.LLVM.Internal.Paths++main = defaultMainWithHooks autoconfUserHooks { preBuild = extBuild }++extBuild args flags = do+ -- Use the Paths module exposed by one of the dependencies to find+ -- the directory containing the enumeration header. Add that+ -- directory to the search path for this package.+ enumHeaderDir <- getDataFileName "src/c++"+ (Just bi, rest) <- (preBuild autoconfUserHooks) args flags+ let incdirs = includeDirs bi+ return (Just bi { includeDirs = enumHeaderDir : incdirs }, rest)+
+ configure view
@@ -0,0 +1,4555 @@+#! /bin/sh+# Guess values for system-dependent variables and create Makefiles.+# Generated by GNU Autoconf 2.63 for Haskell LLVM data interoperability 0.3.0.+#+# Report bugs to <tristan@nochair.net>.+#+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,+# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.+# This configure script is free software; the Free Software Foundation+# gives unlimited permission to copy, distribute and modify it.+## --------------------- ##+## M4sh Initialization. ##+## --------------------- ##++# Be more Bourne compatible+DUALCASE=1; export DUALCASE # for MKS sh+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then+ emulate sh+ NULLCMD=:+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+ # is contrary to our usage. Disable this feature.+ alias -g '${1+"$@"}'='"$@"'+ setopt NO_GLOB_SUBST+else+ case `(set -o) 2>/dev/null` in+ *posix*) set -o posix ;;+esac++fi+++++# PATH needs CR+# Avoid depending upon Character Ranges.+as_cr_letters='abcdefghijklmnopqrstuvwxyz'+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+as_cr_Letters=$as_cr_letters$as_cr_LETTERS+as_cr_digits='0123456789'+as_cr_alnum=$as_cr_Letters$as_cr_digits++as_nl='+'+export as_nl+# Printing a long string crashes Solaris 7 /usr/bin/printf.+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then+ as_echo='printf %s\n'+ as_echo_n='printf %s'+else+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'+ as_echo_n='/usr/ucb/echo -n'+ else+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'+ as_echo_n_body='eval+ arg=$1;+ case $arg in+ *"$as_nl"*)+ expr "X$arg" : "X\\(.*\\)$as_nl";+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;+ esac;+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"+ '+ export as_echo_n_body+ as_echo_n='sh -c $as_echo_n_body as_echo'+ fi+ export as_echo_body+ as_echo='sh -c $as_echo_body as_echo'+fi++# The user is always right.+if test "${PATH_SEPARATOR+set}" != set; then+ PATH_SEPARATOR=:+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+ PATH_SEPARATOR=';'+ }+fi++# Support unset when possible.+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then+ as_unset=unset+else+ as_unset=false+fi+++# IFS+# We need space, tab and new line, in precisely that order. Quoting is+# there to prevent editors from complaining about space-tab.+# (If _AS_PATH_WALK were called with IFS unset, it would disable word+# splitting by setting IFS to empty value.)+IFS=" "" $as_nl"++# Find who we are. Look in the path if we contain no directory separator.+case $0 in+ *[\\/]* ) as_myself=$0 ;;+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break+done+IFS=$as_save_IFS++ ;;+esac+# We did not find ourselves, most probably we were run as `sh COMMAND'+# in which case we are not to be found in the path.+if test "x$as_myself" = x; then+ as_myself=$0+fi+if test ! -f "$as_myself"; then+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2+ { (exit 1); exit 1; }+fi++# Work around bugs in pre-3.0 UWIN ksh.+for as_var in ENV MAIL MAILPATH+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var+done+PS1='$ '+PS2='> '+PS4='+ '++# NLS nuisances.+LC_ALL=C+export LC_ALL+LANGUAGE=C+export LANGUAGE++# Required to use basename.+if expr a : '\(a\)' >/dev/null 2>&1 &&+ test "X`expr 00001 : '.*\(...\)'`" = X001; then+ as_expr=expr+else+ as_expr=false+fi++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then+ as_basename=basename+else+ as_basename=false+fi+++# Name of the executable.+as_me=`$as_basename -- "$0" ||+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \+ X"$0" : 'X\(//\)$' \| \+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X/"$0" |+ sed '/^.*\/\([^/][^/]*\)\/*$/{+ s//\1/+ q+ }+ /^X\/\(\/\/\)$/{+ s//\1/+ q+ }+ /^X\/\(\/\).*/{+ s//\1/+ q+ }+ s/.*/./; q'`++# CDPATH.+$as_unset CDPATH+++if test "x$CONFIG_SHELL" = x; then+ if (eval ":") 2>/dev/null; then+ as_have_required=yes+else+ as_have_required=no+fi++ if test $as_have_required = yes && (eval ":+(as_func_return () {+ (exit \$1)+}+as_func_success () {+ as_func_return 0+}+as_func_failure () {+ as_func_return 1+}+as_func_ret_success () {+ return 0+}+as_func_ret_failure () {+ return 1+}++exitcode=0+if as_func_success; then+ :+else+ exitcode=1+ echo as_func_success failed.+fi++if as_func_failure; then+ exitcode=1+ echo as_func_failure succeeded.+fi++if as_func_ret_success; then+ :+else+ exitcode=1+ echo as_func_ret_success failed.+fi++if as_func_ret_failure; then+ exitcode=1+ echo as_func_ret_failure succeeded.+fi++if ( set x; as_func_ret_success y && test x = \"\$1\" ); then+ :+else+ exitcode=1+ echo positional parameters were not saved.+fi++test \$exitcode = 0) || { (exit 1); exit 1; }++(+ as_lineno_1=\$LINENO+ as_lineno_2=\$LINENO+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }+") 2> /dev/null; then+ :+else+ as_candidate_shells=+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ case $as_dir in+ /*)+ for as_base in sh bash ksh sh5; do+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"+ done;;+ esac+done+IFS=$as_save_IFS+++ for as_shell in $as_candidate_shells $SHELL; do+ # Try only shells that exist, to save several forks.+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&+ { ("$as_shell") 2> /dev/null <<\_ASEOF+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then+ emulate sh+ NULLCMD=:+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+ # is contrary to our usage. Disable this feature.+ alias -g '${1+"$@"}'='"$@"'+ setopt NO_GLOB_SUBST+else+ case `(set -o) 2>/dev/null` in+ *posix*) set -o posix ;;+esac++fi+++:+_ASEOF+}; then+ CONFIG_SHELL=$as_shell+ as_have_required=yes+ if { "$as_shell" 2> /dev/null <<\_ASEOF+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then+ emulate sh+ NULLCMD=:+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+ # is contrary to our usage. Disable this feature.+ alias -g '${1+"$@"}'='"$@"'+ setopt NO_GLOB_SUBST+else+ case `(set -o) 2>/dev/null` in+ *posix*) set -o posix ;;+esac++fi+++:+(as_func_return () {+ (exit $1)+}+as_func_success () {+ as_func_return 0+}+as_func_failure () {+ as_func_return 1+}+as_func_ret_success () {+ return 0+}+as_func_ret_failure () {+ return 1+}++exitcode=0+if as_func_success; then+ :+else+ exitcode=1+ echo as_func_success failed.+fi++if as_func_failure; then+ exitcode=1+ echo as_func_failure succeeded.+fi++if as_func_ret_success; then+ :+else+ exitcode=1+ echo as_func_ret_success failed.+fi++if as_func_ret_failure; then+ exitcode=1+ echo as_func_ret_failure succeeded.+fi++if ( set x; as_func_ret_success y && test x = "$1" ); then+ :+else+ exitcode=1+ echo positional parameters were not saved.+fi++test $exitcode = 0) || { (exit 1); exit 1; }++(+ as_lineno_1=$LINENO+ as_lineno_2=$LINENO+ test "x$as_lineno_1" != "x$as_lineno_2" &&+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }++_ASEOF+}; then+ break+fi++fi++ done++ if test "x$CONFIG_SHELL" != x; then+ for as_var in BASH_ENV ENV+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var+ done+ export CONFIG_SHELL+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}+fi+++ if test $as_have_required = no; then+ echo This script requires a shell more modern than all the+ echo shells that I found on your system. Please install a+ echo modern shell, or manually run the script under such a+ echo shell if you do have one.+ { (exit 1); exit 1; }+fi+++fi++fi++++(eval "as_func_return () {+ (exit \$1)+}+as_func_success () {+ as_func_return 0+}+as_func_failure () {+ as_func_return 1+}+as_func_ret_success () {+ return 0+}+as_func_ret_failure () {+ return 1+}++exitcode=0+if as_func_success; then+ :+else+ exitcode=1+ echo as_func_success failed.+fi++if as_func_failure; then+ exitcode=1+ echo as_func_failure succeeded.+fi++if as_func_ret_success; then+ :+else+ exitcode=1+ echo as_func_ret_success failed.+fi++if as_func_ret_failure; then+ exitcode=1+ echo as_func_ret_failure succeeded.+fi++if ( set x; as_func_ret_success y && test x = \"\$1\" ); then+ :+else+ exitcode=1+ echo positional parameters were not saved.+fi++test \$exitcode = 0") || {+ echo No shell found that supports shell functions.+ echo Please tell bug-autoconf@gnu.org about your system,+ echo including any error possibly output before this message.+ echo This can help us improve future autoconf versions.+ echo Configuration will now proceed without shell functions.+}++++ as_lineno_1=$LINENO+ as_lineno_2=$LINENO+ test "x$as_lineno_1" != "x$as_lineno_2" &&+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO+ # uniformly replaced by the line number. The first 'sed' inserts a+ # line-number line after each line using $LINENO; the second 'sed'+ # does the real work. The second script uses 'N' to pair each+ # line-number line with the line containing $LINENO, and appends+ # trailing '-' during substitution so that $LINENO is not a special+ # case at line end.+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the+ # scripts with optimization help from Paolo Bonzini. Blame Lee+ # E. McMahon (1931-1989) for sed's syntax. :-)+ sed -n '+ p+ /[$]LINENO/=+ ' <$as_myself |+ sed '+ s/[$]LINENO.*/&-/+ t lineno+ b+ :lineno+ N+ :loop+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/+ t loop+ s/-\n.*//+ ' >$as_me.lineno &&+ chmod +x "$as_me.lineno" ||+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2+ { (exit 1); exit 1; }; }++ # Don't try to exec as it changes $[0], causing all sort of problems+ # (the dirname of $[0] is not the place where we might find the+ # original and so on. Autoconf is especially sensitive to this).+ . "./$as_me.lineno"+ # Exit status is that of the last command.+ exit+}+++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then+ as_dirname=dirname+else+ as_dirname=false+fi++ECHO_C= ECHO_N= ECHO_T=+case `echo -n x` in+-n*)+ case `echo 'x\c'` in+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.+ *) ECHO_C='\c';;+ esac;;+*)+ ECHO_N='-n';;+esac+if expr a : '\(a\)' >/dev/null 2>&1 &&+ test "X`expr 00001 : '.*\(...\)'`" = X001; then+ as_expr=expr+else+ as_expr=false+fi++rm -f conf$$ conf$$.exe conf$$.file+if test -d conf$$.dir; then+ rm -f conf$$.dir/conf$$.file+else+ rm -f conf$$.dir+ mkdir conf$$.dir 2>/dev/null+fi+if (echo >conf$$.file) 2>/dev/null; then+ if ln -s conf$$.file conf$$ 2>/dev/null; then+ as_ln_s='ln -s'+ # ... but there are two gotchas:+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.+ # In both cases, we have to default to `cp -p'.+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||+ as_ln_s='cp -p'+ elif ln conf$$.file conf$$ 2>/dev/null; then+ as_ln_s=ln+ else+ as_ln_s='cp -p'+ fi+else+ as_ln_s='cp -p'+fi+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file+rmdir conf$$.dir 2>/dev/null++if mkdir -p . 2>/dev/null; then+ as_mkdir_p=:+else+ test -d ./-p && rmdir ./-p+ as_mkdir_p=false+fi++if test -x / >/dev/null 2>&1; then+ as_test_x='test -x'+else+ if ls -dL / >/dev/null 2>&1; then+ as_ls_L_option=L+ else+ as_ls_L_option=+ fi+ as_test_x='+ eval sh -c '\''+ if test -d "$1"; then+ test -d "$1/.";+ else+ case $1 in+ -*)set "./$1";;+ esac;+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in+ ???[sx]*):;;*)false;;esac;fi+ '\'' sh+ '+fi+as_executable_p=$as_test_x++# Sed expression to map a string onto a valid CPP name.+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"++# Sed expression to map a string onto a valid variable name.+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"++++exec 7<&0 </dev/null 6>&1++# Name of the host.+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,+# so uname gets run too.+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`++#+# Initializations.+#+ac_default_prefix=/usr/local+ac_clean_files=+ac_config_libobj_dir=.+LIBOBJS=+cross_compiling=no+subdirs=+MFLAGS=+MAKEFLAGS=+SHELL=${CONFIG_SHELL-/bin/sh}++# Identity of this package.+PACKAGE_NAME='Haskell LLVM data interoperability'+PACKAGE_TARNAME='llvm-data-interop'+PACKAGE_VERSION='0.3.0'+PACKAGE_STRING='Haskell LLVM data interoperability 0.3.0'+PACKAGE_BUGREPORT='tristan@nochair.net'++ac_unique_file="src/LLVM/Internal/Interop.chs"+# Factoring default headers for most tests.+ac_includes_default="\+#include <stdio.h>+#ifdef HAVE_SYS_TYPES_H+# include <sys/types.h>+#endif+#ifdef HAVE_SYS_STAT_H+# include <sys/stat.h>+#endif+#ifdef STDC_HEADERS+# include <stdlib.h>+# include <stddef.h>+#else+# ifdef HAVE_STDLIB_H+# include <stdlib.h>+# endif+#endif+#ifdef HAVE_STRING_H+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H+# include <memory.h>+# endif+# include <string.h>+#endif+#ifdef HAVE_STRINGS_H+# include <strings.h>+#endif+#ifdef HAVE_INTTYPES_H+# include <inttypes.h>+#endif+#ifdef HAVE_STDINT_H+# include <stdint.h>+#endif+#ifdef HAVE_UNISTD_H+# include <unistd.h>+#endif"++ac_subst_vars='LTLIBOBJS+LIBOBJS+llvm_libdir+llvm_ldoptions+llvm_includedir+llvm_target+llvm_extra_libdirs+llvm_extra_libs+llvm_cppflags+llvm_version+EGREP+GREP+CXXCPP+llvm_config+OBJEXT+EXEEXT+ac_ct_CXX+CPPFLAGS+LDFLAGS+CXXFLAGS+CXX+target_alias+host_alias+build_alias+LIBS+ECHO_T+ECHO_N+ECHO_C+DEFS+mandir+localedir+libdir+psdir+pdfdir+dvidir+htmldir+infodir+docdir+oldincludedir+includedir+localstatedir+sharedstatedir+sysconfdir+datadir+datarootdir+libexecdir+sbindir+bindir+program_transform_name+prefix+exec_prefix+PACKAGE_BUGREPORT+PACKAGE_STRING+PACKAGE_VERSION+PACKAGE_TARNAME+PACKAGE_NAME+PATH_SEPARATOR+SHELL'+ac_subst_files=''+ac_user_opts='+enable_option_checking+with_compiler+with_llvm_prefix+with_llvm_bindir+'+ ac_precious_vars='build_alias+host_alias+target_alias+CXX+CXXFLAGS+LDFLAGS+LIBS+CPPFLAGS+CCC+CXXCPP'+++# Initialize some variables set by options.+ac_init_help=+ac_init_version=false+ac_unrecognized_opts=+ac_unrecognized_sep=+# The variables have the same names as the options, with+# dashes changed to underlines.+cache_file=/dev/null+exec_prefix=NONE+no_create=+no_recursion=+prefix=NONE+program_prefix=NONE+program_suffix=NONE+program_transform_name=s,x,x,+silent=+site=+srcdir=+verbose=+x_includes=NONE+x_libraries=NONE++# Installation directory options.+# These are left unexpanded so users can "make install exec_prefix=/foo"+# and all the variables that are supposed to be based on exec_prefix+# by default will actually change.+# Use braces instead of parens because sh, perl, etc. also accept them.+# (The list follows the same order as the GNU Coding Standards.)+bindir='${exec_prefix}/bin'+sbindir='${exec_prefix}/sbin'+libexecdir='${exec_prefix}/libexec'+datarootdir='${prefix}/share'+datadir='${datarootdir}'+sysconfdir='${prefix}/etc'+sharedstatedir='${prefix}/com'+localstatedir='${prefix}/var'+includedir='${prefix}/include'+oldincludedir='/usr/include'+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'+infodir='${datarootdir}/info'+htmldir='${docdir}'+dvidir='${docdir}'+pdfdir='${docdir}'+psdir='${docdir}'+libdir='${exec_prefix}/lib'+localedir='${datarootdir}/locale'+mandir='${datarootdir}/man'++ac_prev=+ac_dashdash=+for ac_option+do+ # If the previous option needs an argument, assign it.+ if test -n "$ac_prev"; then+ eval $ac_prev=\$ac_option+ ac_prev=+ continue+ fi++ case $ac_option in+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;+ *) ac_optarg=yes ;;+ esac++ # Accept the important Cygnus configure options, so we can diagnose typos.++ case $ac_dashdash$ac_option in+ --)+ ac_dashdash=yes ;;++ -bindir | --bindir | --bindi | --bind | --bin | --bi)+ ac_prev=bindir ;;+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)+ bindir=$ac_optarg ;;++ -build | --build | --buil | --bui | --bu)+ ac_prev=build_alias ;;+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)+ build_alias=$ac_optarg ;;++ -cache-file | --cache-file | --cache-fil | --cache-fi \+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)+ ac_prev=cache_file ;;+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)+ cache_file=$ac_optarg ;;++ --config-cache | -C)+ cache_file=config.cache ;;++ -datadir | --datadir | --datadi | --datad)+ ac_prev=datadir ;;+ -datadir=* | --datadir=* | --datadi=* | --datad=*)+ datadir=$ac_optarg ;;++ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \+ | --dataroo | --dataro | --datar)+ ac_prev=datarootdir ;;+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)+ datarootdir=$ac_optarg ;;++ -disable-* | --disable-*)+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`+ # Reject names that are not valid shell variable names.+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2+ { (exit 1); exit 1; }; }+ ac_useropt_orig=$ac_useropt+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+ case $ac_user_opts in+ *"+"enable_$ac_useropt"+"*) ;;+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"+ ac_unrecognized_sep=', ';;+ esac+ eval enable_$ac_useropt=no ;;++ -docdir | --docdir | --docdi | --doc | --do)+ ac_prev=docdir ;;+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)+ docdir=$ac_optarg ;;++ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)+ ac_prev=dvidir ;;+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)+ dvidir=$ac_optarg ;;++ -enable-* | --enable-*)+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`+ # Reject names that are not valid shell variable names.+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2+ { (exit 1); exit 1; }; }+ ac_useropt_orig=$ac_useropt+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+ case $ac_user_opts in+ *"+"enable_$ac_useropt"+"*) ;;+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"+ ac_unrecognized_sep=', ';;+ esac+ eval enable_$ac_useropt=\$ac_optarg ;;++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \+ | --exec | --exe | --ex)+ ac_prev=exec_prefix ;;+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \+ | --exec=* | --exe=* | --ex=*)+ exec_prefix=$ac_optarg ;;++ -gas | --gas | --ga | --g)+ # Obsolete; use --with-gas.+ with_gas=yes ;;++ -help | --help | --hel | --he | -h)+ ac_init_help=long ;;+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)+ ac_init_help=recursive ;;+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)+ ac_init_help=short ;;++ -host | --host | --hos | --ho)+ ac_prev=host_alias ;;+ -host=* | --host=* | --hos=* | --ho=*)+ host_alias=$ac_optarg ;;++ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)+ ac_prev=htmldir ;;+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \+ | --ht=*)+ htmldir=$ac_optarg ;;++ -includedir | --includedir | --includedi | --included | --include \+ | --includ | --inclu | --incl | --inc)+ ac_prev=includedir ;;+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \+ | --includ=* | --inclu=* | --incl=* | --inc=*)+ includedir=$ac_optarg ;;++ -infodir | --infodir | --infodi | --infod | --info | --inf)+ ac_prev=infodir ;;+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)+ infodir=$ac_optarg ;;++ -libdir | --libdir | --libdi | --libd)+ ac_prev=libdir ;;+ -libdir=* | --libdir=* | --libdi=* | --libd=*)+ libdir=$ac_optarg ;;++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \+ | --libexe | --libex | --libe)+ ac_prev=libexecdir ;;+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \+ | --libexe=* | --libex=* | --libe=*)+ libexecdir=$ac_optarg ;;++ -localedir | --localedir | --localedi | --localed | --locale)+ ac_prev=localedir ;;+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)+ localedir=$ac_optarg ;;++ -localstatedir | --localstatedir | --localstatedi | --localstated \+ | --localstate | --localstat | --localsta | --localst | --locals)+ ac_prev=localstatedir ;;+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)+ localstatedir=$ac_optarg ;;++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)+ ac_prev=mandir ;;+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)+ mandir=$ac_optarg ;;++ -nfp | --nfp | --nf)+ # Obsolete; use --without-fp.+ with_fp=no ;;++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \+ | --no-cr | --no-c | -n)+ no_create=yes ;;++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)+ no_recursion=yes ;;++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \+ | --oldin | --oldi | --old | --ol | --o)+ ac_prev=oldincludedir ;;+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)+ oldincludedir=$ac_optarg ;;++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)+ ac_prev=prefix ;;+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)+ prefix=$ac_optarg ;;++ -program-prefix | --program-prefix | --program-prefi | --program-pref \+ | --program-pre | --program-pr | --program-p)+ ac_prev=program_prefix ;;+ -program-prefix=* | --program-prefix=* | --program-prefi=* \+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)+ program_prefix=$ac_optarg ;;++ -program-suffix | --program-suffix | --program-suffi | --program-suff \+ | --program-suf | --program-su | --program-s)+ ac_prev=program_suffix ;;+ -program-suffix=* | --program-suffix=* | --program-suffi=* \+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)+ program_suffix=$ac_optarg ;;++ -program-transform-name | --program-transform-name \+ | --program-transform-nam | --program-transform-na \+ | --program-transform-n | --program-transform- \+ | --program-transform | --program-transfor \+ | --program-transfo | --program-transf \+ | --program-trans | --program-tran \+ | --progr-tra | --program-tr | --program-t)+ ac_prev=program_transform_name ;;+ -program-transform-name=* | --program-transform-name=* \+ | --program-transform-nam=* | --program-transform-na=* \+ | --program-transform-n=* | --program-transform-=* \+ | --program-transform=* | --program-transfor=* \+ | --program-transfo=* | --program-transf=* \+ | --program-trans=* | --program-tran=* \+ | --progr-tra=* | --program-tr=* | --program-t=*)+ program_transform_name=$ac_optarg ;;++ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)+ ac_prev=pdfdir ;;+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)+ pdfdir=$ac_optarg ;;++ -psdir | --psdir | --psdi | --psd | --ps)+ ac_prev=psdir ;;+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)+ psdir=$ac_optarg ;;++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \+ | -silent | --silent | --silen | --sile | --sil)+ silent=yes ;;++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)+ ac_prev=sbindir ;;+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \+ | --sbi=* | --sb=*)+ sbindir=$ac_optarg ;;++ -sharedstatedir | --sharedstatedir | --sharedstatedi \+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \+ | --sharedst | --shareds | --shared | --share | --shar \+ | --sha | --sh)+ ac_prev=sharedstatedir ;;+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \+ | --sha=* | --sh=*)+ sharedstatedir=$ac_optarg ;;++ -site | --site | --sit)+ ac_prev=site ;;+ -site=* | --site=* | --sit=*)+ site=$ac_optarg ;;++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)+ ac_prev=srcdir ;;+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)+ srcdir=$ac_optarg ;;++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \+ | --syscon | --sysco | --sysc | --sys | --sy)+ ac_prev=sysconfdir ;;+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)+ sysconfdir=$ac_optarg ;;++ -target | --target | --targe | --targ | --tar | --ta | --t)+ ac_prev=target_alias ;;+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)+ target_alias=$ac_optarg ;;++ -v | -verbose | --verbose | --verbos | --verbo | --verb)+ verbose=yes ;;++ -version | --version | --versio | --versi | --vers | -V)+ ac_init_version=: ;;++ -with-* | --with-*)+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`+ # Reject names that are not valid shell variable names.+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2+ { (exit 1); exit 1; }; }+ ac_useropt_orig=$ac_useropt+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+ case $ac_user_opts in+ *"+"with_$ac_useropt"+"*) ;;+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"+ ac_unrecognized_sep=', ';;+ esac+ eval with_$ac_useropt=\$ac_optarg ;;++ -without-* | --without-*)+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`+ # Reject names that are not valid shell variable names.+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2+ { (exit 1); exit 1; }; }+ ac_useropt_orig=$ac_useropt+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+ case $ac_user_opts in+ *"+"with_$ac_useropt"+"*) ;;+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"+ ac_unrecognized_sep=', ';;+ esac+ eval with_$ac_useropt=no ;;++ --x)+ # Obsolete; use --with-x.+ with_x=yes ;;++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \+ | --x-incl | --x-inc | --x-in | --x-i)+ ac_prev=x_includes ;;+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)+ x_includes=$ac_optarg ;;++ -x-libraries | --x-libraries | --x-librarie | --x-librari \+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)+ ac_prev=x_libraries ;;+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)+ x_libraries=$ac_optarg ;;++ -*) { $as_echo "$as_me: error: unrecognized option: $ac_option+Try \`$0 --help' for more information." >&2+ { (exit 1); exit 1; }; }+ ;;++ *=*)+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`+ # Reject names that are not valid shell variable names.+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&+ { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2+ { (exit 1); exit 1; }; }+ eval $ac_envvar=\$ac_optarg+ export $ac_envvar ;;++ *)+ # FIXME: should be removed in autoconf 3.0.+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}+ ;;++ esac+done++if test -n "$ac_prev"; then+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`+ { $as_echo "$as_me: error: missing argument to $ac_option" >&2+ { (exit 1); exit 1; }; }+fi++if test -n "$ac_unrecognized_opts"; then+ case $enable_option_checking in+ no) ;;+ fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2+ { (exit 1); exit 1; }; } ;;+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;+ esac+fi++# Check all directory arguments for consistency.+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \+ datadir sysconfdir sharedstatedir localstatedir includedir \+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \+ libdir localedir mandir+do+ eval ac_val=\$$ac_var+ # Remove trailing slashes.+ case $ac_val in+ */ )+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`+ eval $ac_var=\$ac_val;;+ esac+ # Be sure to have absolute directory names.+ case $ac_val in+ [\\/$]* | ?:[\\/]* ) continue;;+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;+ esac+ { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2+ { (exit 1); exit 1; }; }+done++# There might be people who depend on the old broken behavior: `$host'+# used to hold the argument of --host etc.+# FIXME: To remove some day.+build=$build_alias+host=$host_alias+target=$target_alias++# FIXME: To remove some day.+if test "x$host_alias" != x; then+ if test "x$build_alias" = x; then+ cross_compiling=maybe+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.+ If a cross compiler is detected then cross compile mode will be used." >&2+ elif test "x$build_alias" != "x$host_alias"; then+ cross_compiling=yes+ fi+fi++ac_tool_prefix=+test -n "$host_alias" && ac_tool_prefix=$host_alias-++test "$silent" = yes && exec 6>/dev/null+++ac_pwd=`pwd` && test -n "$ac_pwd" &&+ac_ls_di=`ls -di .` &&+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||+ { $as_echo "$as_me: error: working directory cannot be determined" >&2+ { (exit 1); exit 1; }; }+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||+ { $as_echo "$as_me: error: pwd does not report name of working directory" >&2+ { (exit 1); exit 1; }; }+++# Find the source files, if location was not specified.+if test -z "$srcdir"; then+ ac_srcdir_defaulted=yes+ # Try the directory containing this script, then the parent directory.+ ac_confdir=`$as_dirname -- "$as_myself" ||+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+ X"$as_myself" : 'X\(//\)[^/]' \| \+ X"$as_myself" : 'X\(//\)$' \| \+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$as_myself" |+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+ s//\1/+ q+ }+ /^X\(\/\/\)[^/].*/{+ s//\1/+ q+ }+ /^X\(\/\/\)$/{+ s//\1/+ q+ }+ /^X\(\/\).*/{+ s//\1/+ q+ }+ s/.*/./; q'`+ srcdir=$ac_confdir+ if test ! -r "$srcdir/$ac_unique_file"; then+ srcdir=..+ fi+else+ ac_srcdir_defaulted=no+fi+if test ! -r "$srcdir/$ac_unique_file"; then+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."+ { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2+ { (exit 1); exit 1; }; }+fi+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"+ac_abs_confdir=`(+ cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2+ { (exit 1); exit 1; }; }+ pwd)`+# When building in place, set srcdir=.+if test "$ac_abs_confdir" = "$ac_pwd"; then+ srcdir=.+fi+# Remove unnecessary trailing slashes from srcdir.+# Double slashes in file names in object file debugging info+# mess up M-x gdb in Emacs.+case $srcdir in+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;+esac+for ac_var in $ac_precious_vars; do+ eval ac_env_${ac_var}_set=\${${ac_var}+set}+ eval ac_env_${ac_var}_value=\$${ac_var}+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}+ eval ac_cv_env_${ac_var}_value=\$${ac_var}+done++#+# Report the --help message.+#+if test "$ac_init_help" = "long"; then+ # Omit some internal or obsolete options to make the list less imposing.+ # This message is too long to be a string in the A/UX 3.1 sh.+ cat <<_ACEOF+\`configure' configures Haskell LLVM data interoperability 0.3.0 to adapt to many kinds of systems.++Usage: $0 [OPTION]... [VAR=VALUE]...++To assign environment variables (e.g., CC, CFLAGS...), specify them as+VAR=VALUE. See below for descriptions of some of the useful variables.++Defaults for the options are specified in brackets.++Configuration:+ -h, --help display this help and exit+ --help=short display options specific to this package+ --help=recursive display the short help of all the included packages+ -V, --version display version information and exit+ -q, --quiet, --silent do not print \`checking...' messages+ --cache-file=FILE cache test results in FILE [disabled]+ -C, --config-cache alias for \`--cache-file=config.cache'+ -n, --no-create do not create output files+ --srcdir=DIR find the sources in DIR [configure dir or \`..']++Installation directories:+ --prefix=PREFIX install architecture-independent files in PREFIX+ [$ac_default_prefix]+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX+ [PREFIX]++By default, \`make install' will install all the files in+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify+an installation prefix other than \`$ac_default_prefix' using \`--prefix',+for instance \`--prefix=\$HOME'.++For better control, use the options below.++Fine tuning of the installation directories:+ --bindir=DIR user executables [EPREFIX/bin]+ --sbindir=DIR system admin executables [EPREFIX/sbin]+ --libexecdir=DIR program executables [EPREFIX/libexec]+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]+ --libdir=DIR object code libraries [EPREFIX/lib]+ --includedir=DIR C header files [PREFIX/include]+ --oldincludedir=DIR C header files for non-gcc [/usr/include]+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]+ --infodir=DIR info documentation [DATAROOTDIR/info]+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]+ --mandir=DIR man documentation [DATAROOTDIR/man]+ --docdir=DIR documentation root+ [DATAROOTDIR/doc/llvm-data-interop]+ --htmldir=DIR html documentation [DOCDIR]+ --dvidir=DIR dvi documentation [DOCDIR]+ --pdfdir=DIR pdf documentation [DOCDIR]+ --psdir=DIR ps documentation [DOCDIR]+_ACEOF++ cat <<\_ACEOF++System types:+ --target=TARGET configure for building compilers for TARGET [guessed]+_ACEOF+fi++if test -n "$ac_init_help"; then+ case $ac_init_help in+ short | recursive ) echo "Configuration of Haskell LLVM data interoperability 0.3.0:";;+ esac+ cat <<\_ACEOF++Optional Packages:+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)+ --with-compiler use the given Haskell compiler+ --with-llvm-prefix use the version of LLVM at the given location+ --with-llvm-bindir use LLVM binaries at the given location++Some influential environment variables:+ CXX C++ compiler command+ CXXFLAGS C++ compiler flags+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a+ nonstandard directory <lib dir>+ LIBS libraries to pass to the linker, e.g. -l<library>+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if+ you have headers in a nonstandard directory <include dir>+ CXXCPP C++ preprocessor++Use these variables to override the choices made by `configure' or to help+it to find libraries and programs with nonstandard names/locations.++Report bugs to <tristan@nochair.net>.+_ACEOF+ac_status=$?+fi++if test "$ac_init_help" = "recursive"; then+ # If there are subdirs, report their specific --help.+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue+ test -d "$ac_dir" ||+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||+ continue+ ac_builddir=.++case "$ac_dir" in+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;+*)+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`+ # A ".." for each directory in $ac_dir_suffix.+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`+ case $ac_top_builddir_sub in+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;+ esac ;;+esac+ac_abs_top_builddir=$ac_pwd+ac_abs_builddir=$ac_pwd$ac_dir_suffix+# for backward compatibility:+ac_top_builddir=$ac_top_build_prefix++case $srcdir in+ .) # We are building in place.+ ac_srcdir=.+ ac_top_srcdir=$ac_top_builddir_sub+ ac_abs_top_srcdir=$ac_pwd ;;+ [\\/]* | ?:[\\/]* ) # Absolute name.+ ac_srcdir=$srcdir$ac_dir_suffix;+ ac_top_srcdir=$srcdir+ ac_abs_top_srcdir=$srcdir ;;+ *) # Relative name.+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix+ ac_top_srcdir=$ac_top_build_prefix$srcdir+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;+esac+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix++ cd "$ac_dir" || { ac_status=$?; continue; }+ # Check for guested configure.+ if test -f "$ac_srcdir/configure.gnu"; then+ echo &&+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive+ elif test -f "$ac_srcdir/configure"; then+ echo &&+ $SHELL "$ac_srcdir/configure" --help=recursive+ else+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2+ fi || ac_status=$?+ cd "$ac_pwd" || { ac_status=$?; break; }+ done+fi++test -n "$ac_init_help" && exit $ac_status+if $ac_init_version; then+ cat <<\_ACEOF+Haskell LLVM data interoperability configure 0.3.0+generated by GNU Autoconf 2.63++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.+This configure script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it.+_ACEOF+ exit+fi+cat >config.log <<_ACEOF+This file contains any messages produced by compilers while+running configure, to aid debugging if configure makes a mistake.++It was created by Haskell LLVM data interoperability $as_me 0.3.0, which was+generated by GNU Autoconf 2.63. Invocation command line was++ $ $0 $@++_ACEOF+exec 5>>config.log+{+cat <<_ASUNAME+## --------- ##+## Platform. ##+## --------- ##++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`+uname -m = `(uname -m) 2>/dev/null || echo unknown`+uname -r = `(uname -r) 2>/dev/null || echo unknown`+uname -s = `(uname -s) 2>/dev/null || echo unknown`+uname -v = `(uname -v) 2>/dev/null || echo unknown`++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`++/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`++_ASUNAME++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ $as_echo "PATH: $as_dir"+done+IFS=$as_save_IFS++} >&5++cat >&5 <<_ACEOF+++## ----------- ##+## Core tests. ##+## ----------- ##++_ACEOF+++# Keep a trace of the command line.+# Strip out --no-create and --no-recursion so they do not pile up.+# Strip out --silent because we don't want to record it for future runs.+# Also quote any args containing shell meta-characters.+# Make two passes to allow for proper duplicate-argument suppression.+ac_configure_args=+ac_configure_args0=+ac_configure_args1=+ac_must_keep_next=false+for ac_pass in 1 2+do+ for ac_arg+ do+ case $ac_arg in+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \+ | -silent | --silent | --silen | --sile | --sil)+ continue ;;+ *\'*)+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;+ esac+ case $ac_pass in+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;+ 2)+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"+ if test $ac_must_keep_next = true; then+ ac_must_keep_next=false # Got value, back to normal.+ else+ case $ac_arg in+ *=* | --config-cache | -C | -disable-* | --disable-* \+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \+ | -with-* | --with-* | -without-* | --without-* | --x)+ case "$ac_configure_args0 " in+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;+ esac+ ;;+ -* ) ac_must_keep_next=true ;;+ esac+ fi+ ac_configure_args="$ac_configure_args '$ac_arg'"+ ;;+ esac+ done+done+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }++# When interrupted or exit'd, cleanup temporary files, and complete+# config.log. We remove comments because anyway the quotes in there+# would cause problems or look ugly.+# WARNING: Use '\'' to represent an apostrophe within the trap.+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.+trap 'exit_status=$?+ # Save into config.log some information that might help in debugging.+ {+ echo++ cat <<\_ASBOX+## ---------------- ##+## Cache variables. ##+## ---------------- ##+_ASBOX+ echo+ # The following way of writing the cache mishandles newlines in values,+(+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do+ eval ac_val=\$$ac_var+ case $ac_val in #(+ *${as_nl}*)+ case $ac_var in #(+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;+ esac+ case $ac_var in #(+ _ | IFS | as_nl) ;; #(+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(+ *) $as_unset $ac_var ;;+ esac ;;+ esac+ done+ (set) 2>&1 |+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(+ *${as_nl}ac_space=\ *)+ sed -n \+ "s/'\''/'\''\\\\'\'''\''/g;+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"+ ;; #(+ *)+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"+ ;;+ esac |+ sort+)+ echo++ cat <<\_ASBOX+## ----------------- ##+## Output variables. ##+## ----------------- ##+_ASBOX+ echo+ for ac_var in $ac_subst_vars+ do+ eval ac_val=\$$ac_var+ case $ac_val in+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;+ esac+ $as_echo "$ac_var='\''$ac_val'\''"+ done | sort+ echo++ if test -n "$ac_subst_files"; then+ cat <<\_ASBOX+## ------------------- ##+## File substitutions. ##+## ------------------- ##+_ASBOX+ echo+ for ac_var in $ac_subst_files+ do+ eval ac_val=\$$ac_var+ case $ac_val in+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;+ esac+ $as_echo "$ac_var='\''$ac_val'\''"+ done | sort+ echo+ fi++ if test -s confdefs.h; then+ cat <<\_ASBOX+## ----------- ##+## confdefs.h. ##+## ----------- ##+_ASBOX+ echo+ cat confdefs.h+ echo+ fi+ test "$ac_signal" != 0 &&+ $as_echo "$as_me: caught signal $ac_signal"+ $as_echo "$as_me: exit $exit_status"+ } >&5+ rm -f core *.core core.conftest.* &&+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&+ exit $exit_status+' 0+for ac_signal in 1 2 13 15; do+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal+done+ac_signal=0++# confdefs.h avoids OS command line length limits that DEFS can exceed.+rm -f -r conftest* confdefs.h++# Predefined preprocessor variables.++cat >>confdefs.h <<_ACEOF+#define PACKAGE_NAME "$PACKAGE_NAME"+_ACEOF+++cat >>confdefs.h <<_ACEOF+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"+_ACEOF+++cat >>confdefs.h <<_ACEOF+#define PACKAGE_VERSION "$PACKAGE_VERSION"+_ACEOF+++cat >>confdefs.h <<_ACEOF+#define PACKAGE_STRING "$PACKAGE_STRING"+_ACEOF+++cat >>confdefs.h <<_ACEOF+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"+_ACEOF+++# Let the site file select an alternate cache file if it wants to.+# Prefer an explicitly selected file to automatically selected ones.+ac_site_file1=NONE+ac_site_file2=NONE+if test -n "$CONFIG_SITE"; then+ ac_site_file1=$CONFIG_SITE+elif test "x$prefix" != xNONE; then+ ac_site_file1=$prefix/share/config.site+ ac_site_file2=$prefix/etc/config.site+else+ ac_site_file1=$ac_default_prefix/share/config.site+ ac_site_file2=$ac_default_prefix/etc/config.site+fi+for ac_site_file in "$ac_site_file1" "$ac_site_file2"+do+ test "x$ac_site_file" = xNONE && continue+ if test -r "$ac_site_file"; then+ { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5+$as_echo "$as_me: loading site script $ac_site_file" >&6;}+ sed 's/^/| /' "$ac_site_file" >&5+ . "$ac_site_file"+ fi+done++if test -r "$cache_file"; then+ # Some versions of bash will fail to source /dev/null (special+ # files actually), so we avoid doing that.+ if test -f "$cache_file"; then+ { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5+$as_echo "$as_me: loading cache $cache_file" >&6;}+ case $cache_file in+ [\\/]* | ?:[\\/]* ) . "$cache_file";;+ *) . "./$cache_file";;+ esac+ fi+else+ { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5+$as_echo "$as_me: creating cache $cache_file" >&6;}+ >$cache_file+fi++# Check that the precious variables saved in the cache have kept the same+# value.+ac_cache_corrupted=false+for ac_var in $ac_precious_vars; do+ eval ac_old_set=\$ac_cv_env_${ac_var}_set+ eval ac_new_set=\$ac_env_${ac_var}_set+ eval ac_old_val=\$ac_cv_env_${ac_var}_value+ eval ac_new_val=\$ac_env_${ac_var}_value+ case $ac_old_set,$ac_new_set in+ set,)+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}+ ac_cache_corrupted=: ;;+ ,set)+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}+ ac_cache_corrupted=: ;;+ ,);;+ *)+ if test "x$ac_old_val" != "x$ac_new_val"; then+ # differences in whitespace do not lead to failure.+ ac_old_val_w=`echo x $ac_old_val`+ ac_new_val_w=`echo x $ac_new_val`+ if test "$ac_old_val_w" != "$ac_new_val_w"; then+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}+ ac_cache_corrupted=:+ else+ { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}+ eval $ac_var=\$ac_old_val+ fi+ { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}+ { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}+ fi;;+ esac+ # Pass precious variables to config.status.+ if test "$ac_new_set" = set; then+ case $ac_new_val in+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;+ *) ac_arg=$ac_var=$ac_new_val ;;+ esac+ case " $ac_configure_args " in+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;+ esac+ fi+done+if $ac_cache_corrupted; then+ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+ { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}+ { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5+$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}+ { (exit 1); exit 1; }; }+fi++++++++++++++++++++++++++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++++ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu+++++ac_config_files="$ac_config_files llvm-data-interop.buildinfo"+++ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu+if test -z "$CXX"; then+ if test -n "$CCC"; then+ CXX=$CCC+ else+ if test -n "$ac_tool_prefix"; then+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC+ do+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.+set dummy $ac_tool_prefix$ac_prog; ac_word=$2+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if test "${ac_cv_prog_CXX+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ if test -n "$CXX"; then+ ac_cv_prog_CXX="$CXX" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ for ac_exec_ext in '' $ac_executable_extensions; do+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5+ break 2+ fi+done+done+IFS=$as_save_IFS++fi+fi+CXX=$ac_cv_prog_CXX+if test -n "$CXX"; then+ { $as_echo "$as_me:$LINENO: result: $CXX" >&5+$as_echo "$CXX" >&6; }+else+ { $as_echo "$as_me:$LINENO: result: no" >&5+$as_echo "no" >&6; }+fi+++ test -n "$CXX" && break+ done+fi+if test -z "$CXX"; then+ ac_ct_CXX=$CXX+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC+do+ # Extract the first word of "$ac_prog", so it can be a program name with args.+set dummy $ac_prog; ac_word=$2+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ if test -n "$ac_ct_CXX"; then+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ for ac_exec_ext in '' $ac_executable_extensions; do+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ ac_cv_prog_ac_ct_CXX="$ac_prog"+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5+ break 2+ fi+done+done+IFS=$as_save_IFS++fi+fi+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX+if test -n "$ac_ct_CXX"; then+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5+$as_echo "$ac_ct_CXX" >&6; }+else+ { $as_echo "$as_me:$LINENO: result: no" >&5+$as_echo "no" >&6; }+fi+++ test -n "$ac_ct_CXX" && break+done++ if test "x$ac_ct_CXX" = x; then+ CXX="g++"+ else+ case $cross_compiling:$ac_tool_warned in+yes:)+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+ CXX=$ac_ct_CXX+ fi+fi++ fi+fi+# Provide some information about the compiler.+$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5+set X $ac_compile+ac_compiler=$2+{ (ac_try="$ac_compiler --version >&5"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compiler --version >&5") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }+{ (ac_try="$ac_compiler -v >&5"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compiler -v >&5") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }+{ (ac_try="$ac_compiler -V >&5"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compiler -V >&5") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }++cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */++int+main ()+{++ ;+ return 0;+}+_ACEOF+ac_clean_files_save=$ac_clean_files+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"+# Try to create an executable without -o first, disregard a.out.+# It will help us diagnose broken compilers, and finding out an intuition+# of exeext.+{ $as_echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5+$as_echo_n "checking for C++ compiler default output file name... " >&6; }+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`++# The possible output files:+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"++ac_rmfiles=+for ac_file in $ac_files+do+ case $ac_file in+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;+ esac+done+rm -f $ac_rmfiles++if { (ac_try="$ac_link_default"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_link_default") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }; then+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'+# in a Makefile. We should not override ac_cv_exeext if it was cached,+# so that the user can short-circuit this test for compilers unknown to+# Autoconf.+for ac_file in $ac_files ''+do+ test -f "$ac_file" || continue+ case $ac_file in+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )+ ;;+ [ab].out )+ # We found the default executable, but exeext='' is most+ # certainly right.+ break;;+ *.* )+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;+ then :; else+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`+ fi+ # We set ac_cv_exeext here because the later test for it is not+ # safe: cross compilers may not add the suffix if given an `-o'+ # argument, so we may need to know it at that point already.+ # Even if this section looks crufty: it has the advantage of+ # actually working.+ break;;+ * )+ break;;+ esac+done+test "$ac_cv_exeext" = no && ac_cv_exeext=++else+ ac_file=''+fi++{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5+$as_echo "$ac_file" >&6; }+if test -z "$ac_file"; then+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+{ { $as_echo "$as_me:$LINENO: error: C++ compiler cannot create executables+See \`config.log' for more details." >&5+$as_echo "$as_me: error: C++ compiler cannot create executables+See \`config.log' for more details." >&2;}+ { (exit 77); exit 77; }; }; }+fi++ac_exeext=$ac_cv_exeext++# Check that the compiler produces executables we can run. If not, either+# the compiler is broken, or we cross compile.+{ $as_echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5+$as_echo_n "checking whether the C++ compiler works... " >&6; }+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0+# If not cross compiling, check that we can run a simple program.+if test "$cross_compiling" != yes; then+ if { ac_try='./$ac_file'+ { (case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_try") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }; }; then+ cross_compiling=no+ else+ if test "$cross_compiling" = maybe; then+ cross_compiling=yes+ else+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+{ { $as_echo "$as_me:$LINENO: error: cannot run C++ compiled programs.+If you meant to cross compile, use \`--host'.+See \`config.log' for more details." >&5+$as_echo "$as_me: error: cannot run C++ compiled programs.+If you meant to cross compile, use \`--host'.+See \`config.log' for more details." >&2;}+ { (exit 1); exit 1; }; }; }+ fi+ fi+fi+{ $as_echo "$as_me:$LINENO: result: yes" >&5+$as_echo "yes" >&6; }++rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out+ac_clean_files=$ac_clean_files_save+# Check that the compiler produces executables we can run. If not, either+# the compiler is broken, or we cross compile.+{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5+$as_echo_n "checking whether we are cross compiling... " >&6; }+{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5+$as_echo "$cross_compiling" >&6; }++{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5+$as_echo_n "checking for suffix of executables... " >&6; }+if { (ac_try="$ac_link"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_link") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }; then+ # If both `conftest.exe' and `conftest' are `present' (well, observable)+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will+# work properly (i.e., refer to `conftest.exe'), while it won't with+# `rm'.+for ac_file in conftest.exe conftest conftest.*; do+ test -f "$ac_file" || continue+ case $ac_file in+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`+ break;;+ * ) break;;+ esac+done+else+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link+See \`config.log' for more details." >&5+$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link+See \`config.log' for more details." >&2;}+ { (exit 1); exit 1; }; }; }+fi++rm -f conftest$ac_cv_exeext+{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5+$as_echo "$ac_cv_exeext" >&6; }++rm -f conftest.$ac_ext+EXEEXT=$ac_cv_exeext+ac_exeext=$EXEEXT+{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5+$as_echo_n "checking for suffix of object files... " >&6; }+if test "${ac_cv_objext+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */++int+main ()+{++ ;+ return 0;+}+_ACEOF+rm -f conftest.o conftest.obj+if { (ac_try="$ac_compile"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compile") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }; then+ for ac_file in conftest.o conftest.obj conftest.*; do+ test -f "$ac_file" || continue;+ case $ac_file in+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`+ break;;+ esac+done+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile+See \`config.log' for more details." >&5+$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile+See \`config.log' for more details." >&2;}+ { (exit 1); exit 1; }; }; }+fi++rm -f conftest.$ac_cv_objext conftest.$ac_ext+fi+{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5+$as_echo "$ac_cv_objext" >&6; }+OBJEXT=$ac_cv_objext+ac_objext=$OBJEXT+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */++int+main ()+{+#ifndef __GNUC__+ choke me+#endif++ ;+ return 0;+}+_ACEOF+rm -f conftest.$ac_objext+if { (ac_try="$ac_compile"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compile") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && {+ test -z "$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest.$ac_objext; then+ ac_compiler_gnu=yes+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ ac_compiler_gnu=no+fi++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu++fi+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }+if test $ac_compiler_gnu = yes; then+ GXX=yes+else+ GXX=+fi+ac_test_CXXFLAGS=${CXXFLAGS+set}+ac_save_CXXFLAGS=$CXXFLAGS+{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5+$as_echo_n "checking whether $CXX accepts -g... " >&6; }+if test "${ac_cv_prog_cxx_g+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag+ ac_cxx_werror_flag=yes+ ac_cv_prog_cxx_g=no+ CXXFLAGS="-g"+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */++int+main ()+{++ ;+ return 0;+}+_ACEOF+rm -f conftest.$ac_objext+if { (ac_try="$ac_compile"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compile") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && {+ test -z "$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest.$ac_objext; then+ ac_cv_prog_cxx_g=yes+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ CXXFLAGS=""+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */++int+main ()+{++ ;+ return 0;+}+_ACEOF+rm -f conftest.$ac_objext+if { (ac_try="$ac_compile"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compile") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && {+ test -z "$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest.$ac_objext; then+ :+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ ac_cxx_werror_flag=$ac_save_cxx_werror_flag+ CXXFLAGS="-g"+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */++int+main ()+{++ ;+ return 0;+}+_ACEOF+rm -f conftest.$ac_objext+if { (ac_try="$ac_compile"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compile") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && {+ test -z "$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest.$ac_objext; then+ ac_cv_prog_cxx_g=yes+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5+++fi++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+fi++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+fi++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag+fi+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5+$as_echo "$ac_cv_prog_cxx_g" >&6; }+if test "$ac_test_CXXFLAGS" = set; then+ CXXFLAGS=$ac_save_CXXFLAGS+elif test $ac_cv_prog_cxx_g = yes; then+ if test "$GXX" = yes; then+ CXXFLAGS="-g -O2"+ else+ CXXFLAGS="-g"+ fi+else+ if test "$GXX" = yes; then+ CXXFLAGS="-O2"+ else+ CXXFLAGS=+ fi+fi+ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu++++# Check whether --with-compiler was given.+if test "${with_compiler+set}" = set; then+ withval=$with_compiler; compiler="$withval"+else+ compiler=ghc+fi+++# Check whether --with-llvm_prefix was given.+if test "${with_llvm_prefix+set}" = set; then+ withval=$with_llvm_prefix; llvm_prefix="$withval"+else+ llvm_prefix="$prefix"+fi+++# Check whether --with-llvm_bindir was given.+if test "${with_llvm_bindir+set}" = set; then+ withval=$with_llvm_bindir; llvm_bindir="$withval"+else+ llvm_bindir="$llvm_prefix/bin"+fi++for ac_prog in llvm-config-3.3 llvm-config-3.2 llvm-config-3.1 llvm-config+do+ # Extract the first word of "$ac_prog", so it can be a program name with args.+set dummy $ac_prog; ac_word=$2+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if test "${ac_cv_path_llvm_config+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ case $llvm_config in+ [\\/]* | ?:[\\/]*)+ ac_cv_path_llvm_config="$llvm_config" # Let the user override the test with a path.+ ;;+ *)+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+as_dummy=""$llvm_bindir:$PATH""+for as_dir in $as_dummy+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ for ac_exec_ext in '' $ac_executable_extensions; do+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ ac_cv_path_llvm_config="$as_dir/$ac_word$ac_exec_ext"+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5+ break 2+ fi+done+done+IFS=$as_save_IFS++ ;;+esac+fi+llvm_config=$ac_cv_path_llvm_config+if test -n "$llvm_config"; then+ { $as_echo "$as_me:$LINENO: result: $llvm_config" >&5+$as_echo "$llvm_config" >&6; }+else+ { $as_echo "$as_me:$LINENO: result: no" >&5+$as_echo "no" >&6; }+fi+++ test -n "$llvm_config" && break+done+test -n "$llvm_config" || llvm_config="{ { $as_echo "$as_me:$LINENO: error: could not find llvm-config in $llvm_bindir" >&5+$as_echo "$as_me: error: could not find llvm-config in $llvm_bindir" >&2;}+ { (exit 1); exit 1; }; }"+++++if test "$target" = ""+then+ if test "${compiler}" != ""+ then+ target=`${compiler} +RTS --info | grep '^ ,("Target platform"' | sed -e 's/.*, "//' -e 's/")//' | tr -d '\r'`+ echo "Target platform inferred as: $target"+ else+ echo "Can't work out target platform"+ exit 1+ fi+fi++case $target in+i386-apple-darwin)+ TARGET_CPPFLAGS="-m32"+ TAGRET_LDFLAGS="-m32"+ ;;+x86_64-apple-darwin)+ TARGET_CPPFLAGS="-m64"+ TAGRET_LDFLAGS="-m64"+ ;;+esac++llvm_version="`$llvm_config --version`"+llvm_cppflags="`$llvm_config --cppflags`"+llvm_includedir="`$llvm_config --includedir`"+llvm_ldflags="`$llvm_config --ldflags`"++llvm_all_libs="`$llvm_config --libs all`"+llvm_target="`$llvm_config --libs engine | sed 's/.*LLVM\(.[^ ]*\)CodeGen.*/\1/'`"++llvm_extra_libs=""+llvm_extra_libdirs=""+llvm_ldoptions=""+for opt in $llvm_all_libs $llvm_ldflags; do+ case $opt in+ -l*) llvm_extra_libs="$llvm_extra_libs `echo $opt | sed 's/-l//'`";;+ -L*) llvm_extra_libdirs="$llvm_extra_libdirs `echo $opt | sed 's/-L//'`";;+ *) llvm_ldoptions="$llvm_ldoptions $opt";;+ esac+done++llvm_libdir="`$llvm_config --libdir`"++CPPFLAGS="$llvm_cppflags $CPPFLAGS $TARGET_CPPFLAGS"+LDFLAGS="$llvm_ldflags $LDFLAGS $TARGET_LDFLAGS"+++ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu+{ $as_echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }+if test -z "$CXXCPP"; then+ if test "${ac_cv_prog_CXXCPP+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ # Double quotes because CXXCPP needs to be expanded+ for CXXCPP in "$CXX -E" "/lib/cpp"+ do+ ac_preproc_ok=false+for ac_cxx_preproc_warn_flag in '' yes+do+ # Use a header file that comes with gcc, so configuring glibc+ # with a fresh cross-compiler works.+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since+ # <limits.h> exists even on freestanding compilers.+ # On the NeXT, cc -E runs the code through the compiler's parser,+ # not just through cpp. "Syntax error" is here to catch this case.+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#ifdef __STDC__+# include <limits.h>+#else+# include <assert.h>+#endif+ Syntax error+_ACEOF+if { (ac_try="$ac_cpp conftest.$ac_ext"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } >/dev/null && {+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ }; then+ :+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ # Broken: fails on valid input.+continue+fi++rm -f conftest.err conftest.$ac_ext++ # OK, works on sane cases. Now check whether nonexistent headers+ # can be detected and how.+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <ac_nonexistent.h>+_ACEOF+if { (ac_try="$ac_cpp conftest.$ac_ext"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } >/dev/null && {+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ }; then+ # Broken: success on invalid input.+continue+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ # Passes both tests.+ac_preproc_ok=:+break+fi++rm -f conftest.err conftest.$ac_ext++done+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.+rm -f conftest.err conftest.$ac_ext+if $ac_preproc_ok; then+ break+fi++ done+ ac_cv_prog_CXXCPP=$CXXCPP++fi+ CXXCPP=$ac_cv_prog_CXXCPP+else+ ac_cv_prog_CXXCPP=$CXXCPP+fi+{ $as_echo "$as_me:$LINENO: result: $CXXCPP" >&5+$as_echo "$CXXCPP" >&6; }+ac_preproc_ok=false+for ac_cxx_preproc_warn_flag in '' yes+do+ # Use a header file that comes with gcc, so configuring glibc+ # with a fresh cross-compiler works.+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since+ # <limits.h> exists even on freestanding compilers.+ # On the NeXT, cc -E runs the code through the compiler's parser,+ # not just through cpp. "Syntax error" is here to catch this case.+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#ifdef __STDC__+# include <limits.h>+#else+# include <assert.h>+#endif+ Syntax error+_ACEOF+if { (ac_try="$ac_cpp conftest.$ac_ext"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } >/dev/null && {+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ }; then+ :+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ # Broken: fails on valid input.+continue+fi++rm -f conftest.err conftest.$ac_ext++ # OK, works on sane cases. Now check whether nonexistent headers+ # can be detected and how.+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <ac_nonexistent.h>+_ACEOF+if { (ac_try="$ac_cpp conftest.$ac_ext"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } >/dev/null && {+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ }; then+ # Broken: success on invalid input.+continue+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ # Passes both tests.+ac_preproc_ok=:+break+fi++rm -f conftest.err conftest.$ac_ext++done+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.+rm -f conftest.err conftest.$ac_ext+if $ac_preproc_ok; then+ :+else+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+{ { $as_echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check+See \`config.log' for more details." >&5+$as_echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check+See \`config.log' for more details." >&2;}+ { (exit 1); exit 1; }; }; }+fi++ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu+++cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <llvm/Config/llvm-config.h>+int+main ()+{++ #if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 3+ #error llvm >= 3.3,+ #endif++ ;+ return 0;+}++_ACEOF+if { (ac_try="$ac_cpp conftest.$ac_ext"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } >/dev/null && {+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ }; then+ llvm_module_h="llvm/Module.h"+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ llvm_module_h="llvm/IR/Module.h"+fi++rm -f conftest.err conftest.$ac_ext++{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }+if test "${ac_cv_path_GREP+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ if test -z "$GREP"; then+ ac_path_GREP_found=false+ # Loop through the user's path and test for each of PROGNAME-LIST+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ for ac_prog in grep ggrep; do+ for ac_exec_ext in '' $ac_executable_extensions; do+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue+# Check for GNU ac_path_GREP and select it if it is found.+ # Check for GNU $ac_path_GREP+case `"$ac_path_GREP" --version 2>&1` in+*GNU*)+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;+*)+ ac_count=0+ $as_echo_n 0123456789 >"conftest.in"+ while :+ do+ cat "conftest.in" "conftest.in" >"conftest.tmp"+ mv "conftest.tmp" "conftest.in"+ cp "conftest.in" "conftest.nl"+ $as_echo 'GREP' >> "conftest.nl"+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break+ ac_count=`expr $ac_count + 1`+ if test $ac_count -gt ${ac_path_GREP_max-0}; then+ # Best one so far, save it but keep looking for a better one+ ac_cv_path_GREP="$ac_path_GREP"+ ac_path_GREP_max=$ac_count+ fi+ # 10*(2^10) chars as input seems more than enough+ test $ac_count -gt 10 && break+ done+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;+esac++ $ac_path_GREP_found && break 3+ done+ done+done+IFS=$as_save_IFS+ if test -z "$ac_cv_path_GREP"; then+ { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5+$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}+ { (exit 1); exit 1; }; }+ fi+else+ ac_cv_path_GREP=$GREP+fi++fi+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5+$as_echo "$ac_cv_path_GREP" >&6; }+ GREP="$ac_cv_path_GREP"+++{ $as_echo "$as_me:$LINENO: checking for egrep" >&5+$as_echo_n "checking for egrep... " >&6; }+if test "${ac_cv_path_EGREP+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1+ then ac_cv_path_EGREP="$GREP -E"+ else+ if test -z "$EGREP"; then+ ac_path_EGREP_found=false+ # Loop through the user's path and test for each of PROGNAME-LIST+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ for ac_prog in egrep; do+ for ac_exec_ext in '' $ac_executable_extensions; do+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue+# Check for GNU ac_path_EGREP and select it if it is found.+ # Check for GNU $ac_path_EGREP+case `"$ac_path_EGREP" --version 2>&1` in+*GNU*)+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;+*)+ ac_count=0+ $as_echo_n 0123456789 >"conftest.in"+ while :+ do+ cat "conftest.in" "conftest.in" >"conftest.tmp"+ mv "conftest.tmp" "conftest.in"+ cp "conftest.in" "conftest.nl"+ $as_echo 'EGREP' >> "conftest.nl"+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break+ ac_count=`expr $ac_count + 1`+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then+ # Best one so far, save it but keep looking for a better one+ ac_cv_path_EGREP="$ac_path_EGREP"+ ac_path_EGREP_max=$ac_count+ fi+ # 10*(2^10) chars as input seems more than enough+ test $ac_count -gt 10 && break+ done+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;+esac++ $ac_path_EGREP_found && break 3+ done+ done+done+IFS=$as_save_IFS+ if test -z "$ac_cv_path_EGREP"; then+ { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5+$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}+ { (exit 1); exit 1; }; }+ fi+else+ ac_cv_path_EGREP=$EGREP+fi++ fi+fi+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5+$as_echo "$ac_cv_path_EGREP" >&6; }+ EGREP="$ac_cv_path_EGREP"+++{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5+$as_echo_n "checking for ANSI C header files... " >&6; }+if test "${ac_cv_header_stdc+set}" = set; then+ $as_echo_n "(cached) " >&6+else+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <stdlib.h>+#include <stdarg.h>+#include <string.h>+#include <float.h>++int+main ()+{++ ;+ return 0;+}+_ACEOF+rm -f conftest.$ac_objext+if { (ac_try="$ac_compile"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compile") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && {+ test -z "$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest.$ac_objext; then+ ac_cv_header_stdc=yes+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ ac_cv_header_stdc=no+fi++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext++if test $ac_cv_header_stdc = yes; then+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <string.h>++_ACEOF+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |+ $EGREP "memchr" >/dev/null 2>&1; then+ :+else+ ac_cv_header_stdc=no+fi+rm -f conftest*++fi++if test $ac_cv_header_stdc = yes; then+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <stdlib.h>++_ACEOF+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |+ $EGREP "free" >/dev/null 2>&1; then+ :+else+ ac_cv_header_stdc=no+fi+rm -f conftest*++fi++if test $ac_cv_header_stdc = yes; then+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.+ if test "$cross_compiling" = yes; then+ :+else+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <ctype.h>+#include <stdlib.h>+#if ((' ' & 0x0FF) == 0x020)+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))+#else+# define ISLOWER(c) \+ (('a' <= (c) && (c) <= 'i') \+ || ('j' <= (c) && (c) <= 'r') \+ || ('s' <= (c) && (c) <= 'z'))+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))+#endif++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))+int+main ()+{+ int i;+ for (i = 0; i < 256; i++)+ if (XOR (islower (i), ISLOWER (i))+ || toupper (i) != TOUPPER (i))+ return 2;+ return 0;+}+_ACEOF+rm -f conftest$ac_exeext+if { (ac_try="$ac_link"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_link") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'+ { (case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_try") 2>&5+ ac_status=$?+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); }; }; then+ :+else+ $as_echo "$as_me: program exited with status $ac_status" >&5+$as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++( exit $ac_status )+ac_cv_header_stdc=no+fi+rm -rf conftest.dSYM+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext+fi+++fi+fi+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5+$as_echo "$ac_cv_header_stdc" >&6; }+if test $ac_cv_header_stdc = yes; then++cat >>confdefs.h <<\_ACEOF+#define STDC_HEADERS 1+_ACEOF++fi++# On IRIX 5.3, sys/types and inttypes.h are conflicting.++++++++++for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \+ inttypes.h stdint.h unistd.h+do+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5+$as_echo_n "checking for $ac_header... " >&6; }+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then+ $as_echo_n "(cached) " >&6+else+ cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+$ac_includes_default++#include <$ac_header>+_ACEOF+rm -f conftest.$ac_objext+if { (ac_try="$ac_compile"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compile") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && {+ test -z "$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest.$ac_objext; then+ eval "$as_ac_Header=yes"+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ eval "$as_ac_Header=no"+fi++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+fi+ac_res=`eval 'as_val=${'$as_ac_Header'}+ $as_echo "$as_val"'`+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5+$as_echo "$ac_res" >&6; }+as_val=`eval 'as_val=${'$as_ac_Header'}+ $as_echo "$as_val"'`+ if test "x$as_val" = x""yes; then+ cat >>confdefs.h <<_ACEOF+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1+_ACEOF++fi++done++++for ac_header in ${llvm_module_h}+do+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5+$as_echo_n "checking for $ac_header... " >&6; }+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then+ $as_echo_n "(cached) " >&6+fi+ac_res=`eval 'as_val=${'$as_ac_Header'}+ $as_echo "$as_val"'`+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5+$as_echo "$ac_res" >&6; }+else+ # Is the header compilable?+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5+$as_echo_n "checking $ac_header usability... " >&6; }+cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+$ac_includes_default+#include <$ac_header>+_ACEOF+rm -f conftest.$ac_objext+if { (ac_try="$ac_compile"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_compile") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && {+ test -z "$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest.$ac_objext; then+ ac_header_compiler=yes+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ ac_header_compiler=no+fi++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5+$as_echo "$ac_header_compiler" >&6; }++# Is the header present?+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5+$as_echo_n "checking $ac_header presence... " >&6; }+cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <$ac_header>+_ACEOF+if { (ac_try="$ac_cpp conftest.$ac_ext"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } >/dev/null && {+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ }; then+ ac_header_preproc=yes+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ ac_header_preproc=no+fi++rm -f conftest.err conftest.$ac_ext+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5+$as_echo "$ac_header_preproc" >&6; }++# So? What about this header?+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in+ yes:no: )+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}+ ac_header_preproc=yes+ ;;+ no:yes:* )+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}+ ( cat <<\_ASBOX+## ---------------------------------- ##+## Report this to tristan@nochair.net ##+## ---------------------------------- ##+_ASBOX+ ) | sed "s/^/$as_me: WARNING: /" >&2+ ;;+esac+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5+$as_echo_n "checking for $ac_header... " >&6; }+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then+ $as_echo_n "(cached) " >&6+else+ eval "$as_ac_Header=\$ac_header_preproc"+fi+ac_res=`eval 'as_val=${'$as_ac_Header'}+ $as_echo "$as_val"'`+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5+$as_echo "$ac_res" >&6; }++fi+as_val=`eval 'as_val=${'$as_ac_Header'}+ $as_echo "$as_val"'`+ if test "x$as_val" = x""yes; then+ cat >>confdefs.h <<_ACEOF+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1+_ACEOF++else+ { { $as_echo "$as_me:$LINENO: error: could not find LLVM headers" >&5+$as_echo "$as_me: error: could not find LLVM headers" >&2;}+ { (exit 1); exit 1; }; }+fi++done+++# We have to link using the C++ compiler.+CC=$CXX++save_LIBS="$LIBS"++cat >conftest.$ac_ext <<_ACEOF+/* confdefs.h. */+_ACEOF+cat confdefs.h >>conftest.$ac_ext+cat >>conftest.$ac_ext <<_ACEOF+/* end confdefs.h. */+#include <${llvm_module_h}>+int+main ()+{+llvm::Module *dummy+ ;+ return 0;+}+_ACEOF+rm -f conftest.$ac_objext conftest$ac_exeext+if { (ac_try="$ac_link"+case "(($ac_try" in+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+ *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""+$as_echo "$ac_try_echo") >&5+ (eval "$ac_link") 2>conftest.er1+ ac_status=$?+ grep -v '^ *+' conftest.er1 >conftest.err+ rm -f conftest.er1+ cat conftest.err >&5+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5+ (exit $ac_status); } && {+ test -z "$ac_cxx_werror_flag" ||+ test ! -s conftest.err+ } && test -s conftest$ac_exeext && {+ test "$cross_compiling" = yes ||+ $as_test_x conftest$ac_exeext+ }; then+ LIBS="-lLLVM-${llvm_version} $LIBS" HAVE_LLVM=1+else+ $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++ { { $as_echo "$as_me:$LINENO: error: \"The llvm-${llvm_version} shared library is not installed\"" >&5+$as_echo "$as_me: error: \"The llvm-${llvm_version} shared library is not installed\"" >&2;}+ { (exit 1); exit 1; }; }+fi++rm -rf conftest.dSYM+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \+ conftest$ac_exeext conftest.$ac_ext+++++++++++cat >confcache <<\_ACEOF+# This file is a shell script that caches the results of configure+# tests run on this system so they can be shared between configure+# scripts and configure runs, see configure's option --config-cache.+# It is not useful on other systems. If it contains results you don't+# want to keep, you may remove or edit it.+#+# config.status only pays attention to the cache file if you give it+# the --recheck option to rerun configure.+#+# `ac_cv_env_foo' variables (set or unset) will be overridden when+# loading this file, other *unset* `ac_cv_foo' will be assigned the+# following values.++_ACEOF++# The following way of writing the cache mishandles newlines in values,+# but we know of no workaround that is simple, portable, and efficient.+# So, we kill variables containing newlines.+# Ultrix sh set writes to stderr and can't be redirected directly,+# and sets the high bit in the cache file unless we assign to the vars.+(+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do+ eval ac_val=\$$ac_var+ case $ac_val in #(+ *${as_nl}*)+ case $ac_var in #(+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;+ esac+ case $ac_var in #(+ _ | IFS | as_nl) ;; #(+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(+ *) $as_unset $ac_var ;;+ esac ;;+ esac+ done++ (set) 2>&1 |+ case $as_nl`(ac_space=' '; set) 2>&1` in #(+ *${as_nl}ac_space=\ *)+ # `set' does not quote correctly, so add quotes (double-quote+ # substitution turns \\\\ into \\, and sed turns \\ into \).+ sed -n \+ "s/'/'\\\\''/g;+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"+ ;; #(+ *)+ # `set' quotes correctly as required by POSIX, so do not add quotes.+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"+ ;;+ esac |+ sort+) |+ sed '+ /^ac_cv_env_/b end+ t clear+ :clear+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/+ t end+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/+ :end' >>confcache+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else+ if test -w "$cache_file"; then+ test "x$cache_file" != "x/dev/null" &&+ { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5+$as_echo "$as_me: updating cache $cache_file" >&6;}+ cat confcache >$cache_file+ else+ { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}+ fi+fi+rm -f confcache++test "x$prefix" = xNONE && prefix=$ac_default_prefix+# Let make expand exec_prefix.+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'++# Transform confdefs.h into DEFS.+# Protect against shell expansion while executing Makefile rules.+# Protect against Makefile macro expansion.+#+# If the first sed substitution is executed (which looks for macros that+# take arguments), then branch to the quote section. Otherwise,+# look for a macro that doesn't take arguments.+ac_script='+:mline+/\\$/{+ N+ s,\\\n,,+ b mline+}+t clear+:clear+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g+t quote+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g+t quote+b any+:quote+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g+s/\[/\\&/g+s/\]/\\&/g+s/\$/$$/g+H+:any+${+ g+ s/^\n//+ s/\n/ /g+ p+}+'+DEFS=`sed -n "$ac_script" confdefs.h`+++ac_libobjs=+ac_ltlibobjs=+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue+ # 1. Remove the extension, and $U if already installed.+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR+ # will be set to the directory where LIBOBJS objects are built.+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'+done+LIBOBJS=$ac_libobjs++LTLIBOBJS=$ac_ltlibobjs++++: ${CONFIG_STATUS=./config.status}+ac_write_fail=0+ac_clean_files_save=$ac_clean_files+ac_clean_files="$ac_clean_files $CONFIG_STATUS"+{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}+cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+#! $SHELL+# Generated by $as_me.+# Run this file to recreate the current configuration.+# Compiler output produced by configure, useful for debugging+# configure, is in config.log if it exists.++debug=false+ac_cs_recheck=false+ac_cs_silent=false+SHELL=\${CONFIG_SHELL-$SHELL}+_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+## --------------------- ##+## M4sh Initialization. ##+## --------------------- ##++# Be more Bourne compatible+DUALCASE=1; export DUALCASE # for MKS sh+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then+ emulate sh+ NULLCMD=:+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+ # is contrary to our usage. Disable this feature.+ alias -g '${1+"$@"}'='"$@"'+ setopt NO_GLOB_SUBST+else+ case `(set -o) 2>/dev/null` in+ *posix*) set -o posix ;;+esac++fi+++++# PATH needs CR+# Avoid depending upon Character Ranges.+as_cr_letters='abcdefghijklmnopqrstuvwxyz'+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+as_cr_Letters=$as_cr_letters$as_cr_LETTERS+as_cr_digits='0123456789'+as_cr_alnum=$as_cr_Letters$as_cr_digits++as_nl='+'+export as_nl+# Printing a long string crashes Solaris 7 /usr/bin/printf.+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then+ as_echo='printf %s\n'+ as_echo_n='printf %s'+else+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'+ as_echo_n='/usr/ucb/echo -n'+ else+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'+ as_echo_n_body='eval+ arg=$1;+ case $arg in+ *"$as_nl"*)+ expr "X$arg" : "X\\(.*\\)$as_nl";+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;+ esac;+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"+ '+ export as_echo_n_body+ as_echo_n='sh -c $as_echo_n_body as_echo'+ fi+ export as_echo_body+ as_echo='sh -c $as_echo_body as_echo'+fi++# The user is always right.+if test "${PATH_SEPARATOR+set}" != set; then+ PATH_SEPARATOR=:+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+ PATH_SEPARATOR=';'+ }+fi++# Support unset when possible.+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then+ as_unset=unset+else+ as_unset=false+fi+++# IFS+# We need space, tab and new line, in precisely that order. Quoting is+# there to prevent editors from complaining about space-tab.+# (If _AS_PATH_WALK were called with IFS unset, it would disable word+# splitting by setting IFS to empty value.)+IFS=" "" $as_nl"++# Find who we are. Look in the path if we contain no directory separator.+case $0 in+ *[\\/]* ) as_myself=$0 ;;+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+ IFS=$as_save_IFS+ test -z "$as_dir" && as_dir=.+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break+done+IFS=$as_save_IFS++ ;;+esac+# We did not find ourselves, most probably we were run as `sh COMMAND'+# in which case we are not to be found in the path.+if test "x$as_myself" = x; then+ as_myself=$0+fi+if test ! -f "$as_myself"; then+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2+ { (exit 1); exit 1; }+fi++# Work around bugs in pre-3.0 UWIN ksh.+for as_var in ENV MAIL MAILPATH+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var+done+PS1='$ '+PS2='> '+PS4='+ '++# NLS nuisances.+LC_ALL=C+export LC_ALL+LANGUAGE=C+export LANGUAGE++# Required to use basename.+if expr a : '\(a\)' >/dev/null 2>&1 &&+ test "X`expr 00001 : '.*\(...\)'`" = X001; then+ as_expr=expr+else+ as_expr=false+fi++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then+ as_basename=basename+else+ as_basename=false+fi+++# Name of the executable.+as_me=`$as_basename -- "$0" ||+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \+ X"$0" : 'X\(//\)$' \| \+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X/"$0" |+ sed '/^.*\/\([^/][^/]*\)\/*$/{+ s//\1/+ q+ }+ /^X\/\(\/\/\)$/{+ s//\1/+ q+ }+ /^X\/\(\/\).*/{+ s//\1/+ q+ }+ s/.*/./; q'`++# CDPATH.+$as_unset CDPATH++++ as_lineno_1=$LINENO+ as_lineno_2=$LINENO+ test "x$as_lineno_1" != "x$as_lineno_2" &&+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO+ # uniformly replaced by the line number. The first 'sed' inserts a+ # line-number line after each line using $LINENO; the second 'sed'+ # does the real work. The second script uses 'N' to pair each+ # line-number line with the line containing $LINENO, and appends+ # trailing '-' during substitution so that $LINENO is not a special+ # case at line end.+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the+ # scripts with optimization help from Paolo Bonzini. Blame Lee+ # E. McMahon (1931-1989) for sed's syntax. :-)+ sed -n '+ p+ /[$]LINENO/=+ ' <$as_myself |+ sed '+ s/[$]LINENO.*/&-/+ t lineno+ b+ :lineno+ N+ :loop+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/+ t loop+ s/-\n.*//+ ' >$as_me.lineno &&+ chmod +x "$as_me.lineno" ||+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2+ { (exit 1); exit 1; }; }++ # Don't try to exec as it changes $[0], causing all sort of problems+ # (the dirname of $[0] is not the place where we might find the+ # original and so on. Autoconf is especially sensitive to this).+ . "./$as_me.lineno"+ # Exit status is that of the last command.+ exit+}+++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then+ as_dirname=dirname+else+ as_dirname=false+fi++ECHO_C= ECHO_N= ECHO_T=+case `echo -n x` in+-n*)+ case `echo 'x\c'` in+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.+ *) ECHO_C='\c';;+ esac;;+*)+ ECHO_N='-n';;+esac+if expr a : '\(a\)' >/dev/null 2>&1 &&+ test "X`expr 00001 : '.*\(...\)'`" = X001; then+ as_expr=expr+else+ as_expr=false+fi++rm -f conf$$ conf$$.exe conf$$.file+if test -d conf$$.dir; then+ rm -f conf$$.dir/conf$$.file+else+ rm -f conf$$.dir+ mkdir conf$$.dir 2>/dev/null+fi+if (echo >conf$$.file) 2>/dev/null; then+ if ln -s conf$$.file conf$$ 2>/dev/null; then+ as_ln_s='ln -s'+ # ... but there are two gotchas:+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.+ # In both cases, we have to default to `cp -p'.+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||+ as_ln_s='cp -p'+ elif ln conf$$.file conf$$ 2>/dev/null; then+ as_ln_s=ln+ else+ as_ln_s='cp -p'+ fi+else+ as_ln_s='cp -p'+fi+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file+rmdir conf$$.dir 2>/dev/null++if mkdir -p . 2>/dev/null; then+ as_mkdir_p=:+else+ test -d ./-p && rmdir ./-p+ as_mkdir_p=false+fi++if test -x / >/dev/null 2>&1; then+ as_test_x='test -x'+else+ if ls -dL / >/dev/null 2>&1; then+ as_ls_L_option=L+ else+ as_ls_L_option=+ fi+ as_test_x='+ eval sh -c '\''+ if test -d "$1"; then+ test -d "$1/.";+ else+ case $1 in+ -*)set "./$1";;+ esac;+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in+ ???[sx]*):;;*)false;;esac;fi+ '\'' sh+ '+fi+as_executable_p=$as_test_x++# Sed expression to map a string onto a valid CPP name.+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"++# Sed expression to map a string onto a valid variable name.+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"+++exec 6>&1++# Save the log message, to keep $[0] and so on meaningful, and to+# report actual input values of CONFIG_FILES etc. instead of their+# values after options handling.+ac_log="+This file was extended by Haskell LLVM data interoperability $as_me 0.3.0, which was+generated by GNU Autoconf 2.63. Invocation command line was++ CONFIG_FILES = $CONFIG_FILES+ CONFIG_HEADERS = $CONFIG_HEADERS+ CONFIG_LINKS = $CONFIG_LINKS+ CONFIG_COMMANDS = $CONFIG_COMMANDS+ $ $0 $@++on `(hostname || uname -n) 2>/dev/null | sed 1q`+"++_ACEOF++case $ac_config_files in *"+"*) set x $ac_config_files; shift; ac_config_files=$*;;+esac++++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+# Files that config.status was made for.+config_files="$ac_config_files"++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+ac_cs_usage="\+\`$as_me' instantiates files from templates according to the+current configuration.++Usage: $0 [OPTION]... [FILE]...++ -h, --help print this help, then exit+ -V, --version print version number and configuration settings, then exit+ -q, --quiet, --silent+ do not print progress messages+ -d, --debug don't remove temporary files+ --recheck update $as_me by reconfiguring in the same conditions+ --file=FILE[:TEMPLATE]+ instantiate the configuration file FILE++Configuration files:+$config_files++Report bugs to <bug-autoconf@gnu.org>."++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ac_cs_version="\\+Haskell LLVM data interoperability config.status 0.3.0+configured by $0, generated by GNU Autoconf 2.63,+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"++Copyright (C) 2008 Free Software Foundation, Inc.+This config.status script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it."++ac_pwd='$ac_pwd'+srcdir='$srcdir'+test -n "\$AWK" || AWK=awk+_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# The default lists apply if the user does not specify any file.+ac_need_defaults=:+while test $# != 0+do+ case $1 in+ --*=*)+ ac_option=`expr "X$1" : 'X\([^=]*\)='`+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`+ ac_shift=:+ ;;+ *)+ ac_option=$1+ ac_optarg=$2+ ac_shift=shift+ ;;+ esac++ case $ac_option in+ # Handling of the options.+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)+ ac_cs_recheck=: ;;+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )+ $as_echo "$ac_cs_version"; exit ;;+ --debug | --debu | --deb | --de | --d | -d )+ debug=: ;;+ --file | --fil | --fi | --f )+ $ac_shift+ case $ac_optarg in+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;+ esac+ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'"+ ac_need_defaults=false;;+ --he | --h | --help | --hel | -h )+ $as_echo "$ac_cs_usage"; exit ;;+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \+ | -silent | --silent | --silen | --sile | --sil | --si | --s)+ ac_cs_silent=: ;;++ # This is an error.+ -*) { $as_echo "$as_me: error: unrecognized option: $1+Try \`$0 --help' for more information." >&2+ { (exit 1); exit 1; }; } ;;++ *) ac_config_targets="$ac_config_targets $1"+ ac_need_defaults=false ;;++ esac+ shift+done++ac_configure_extra_args=++if $ac_cs_silent; then+ exec 6>/dev/null+ ac_configure_extra_args="$ac_configure_extra_args --silent"+fi++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+if \$ac_cs_recheck; then+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion+ shift+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6+ CONFIG_SHELL='$SHELL'+ export CONFIG_SHELL+ exec "\$@"+fi++_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+exec 5>>config.log+{+ echo+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX+## Running $as_me. ##+_ASBOX+ $as_echo "$ac_log"+} >&5++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1++# Handling of arguments.+for ac_config_target in $ac_config_targets+do+ case $ac_config_target in+ "llvm-data-interop.buildinfo") CONFIG_FILES="$CONFIG_FILES llvm-data-interop.buildinfo" ;;++ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5+$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}+ { (exit 1); exit 1; }; };;+ esac+done+++# If the user did not use the arguments to specify the items to instantiate,+# then the envvar interface is used. Set only those that are not.+# We use the long form for the default assignment because of an extremely+# bizarre bug on SunOS 4.1.3.+if $ac_need_defaults; then+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files+fi++# Have a temporary directory for convenience. Make it in the build tree+# simply because there is no reason against having it here, and in addition,+# creating and moving files from /tmp can sometimes cause problems.+# Hook for its removal unless debugging.+# Note that there is a small window in which the directory will not be cleaned:+# after its creation but before its name has been assigned to `$tmp'.+$debug ||+{+ tmp=+ trap 'exit_status=$?+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status+' 0+ trap '{ (exit 1); exit 1; }' 1 2 13 15+}+# Create a (secure) tmp directory for tmp files.++{+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&+ test -n "$tmp" && test -d "$tmp"+} ||+{+ tmp=./conf$$-$RANDOM+ (umask 077 && mkdir "$tmp")+} ||+{+ $as_echo "$as_me: cannot create a temporary directory in ." >&2+ { (exit 1); exit 1; }+}++# Set up the scripts for CONFIG_FILES section.+# No need to generate them if there are no CONFIG_FILES.+# This happens for instance with `./config.status config.h'.+if test -n "$CONFIG_FILES"; then+++ac_cr=' '+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then+ ac_cs_awk_cr='\\r'+else+ ac_cs_awk_cr=$ac_cr+fi++echo 'BEGIN {' >"$tmp/subs1.awk" &&+_ACEOF+++{+ echo "cat >conf$$subs.awk <<_ACEOF" &&+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&+ echo "_ACEOF"+} >conf$$subs.sh ||+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}+ { (exit 1); exit 1; }; }+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`+ac_delim='%!_!# '+for ac_last_try in false false false false false :; do+ . ./conf$$subs.sh ||+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}+ { (exit 1); exit 1; }; }++ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`+ if test $ac_delim_n = $ac_delim_num; then+ break+ elif $ac_last_try; then+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}+ { (exit 1); exit 1; }; }+ else+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "+ fi+done+rm -f conf$$subs.sh++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&+_ACEOF+sed -n '+h+s/^/S["/; s/!.*/"]=/+p+g+s/^[^!]*!//+:repl+t repl+s/'"$ac_delim"'$//+t delim+:nl+h+s/\(.\{148\}\).*/\1/+t more1+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/+p+n+b repl+:more1+s/["\\]/\\&/g; s/^/"/; s/$/"\\/+p+g+s/.\{148\}//+t nl+:delim+h+s/\(.\{148\}\).*/\1/+t more2+s/["\\]/\\&/g; s/^/"/; s/$/"/+p+b+:more2+s/["\\]/\\&/g; s/^/"/; s/$/"\\/+p+g+s/.\{148\}//+t delim+' <conf$$subs.awk | sed '+/^[^""]/{+ N+ s/\n//+}+' >>$CONFIG_STATUS || ac_write_fail=1+rm -f conf$$subs.awk+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+_ACAWK+cat >>"\$tmp/subs1.awk" <<_ACAWK &&+ for (key in S) S_is_set[key] = 1+ FS = ""++}+{+ line = $ 0+ nfields = split(line, field, "@")+ substed = 0+ len = length(field[1])+ for (i = 2; i < nfields; i++) {+ key = field[i]+ keylen = length(key)+ if (S_is_set[key]) {+ value = S[key]+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)+ len += length(value) + length(field[++i])+ substed = 1+ } else+ len += 1 + keylen+ }++ print line+}++_ACAWK+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"+else+ cat+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \+ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5+$as_echo "$as_me: error: could not setup config files machinery" >&2;}+ { (exit 1); exit 1; }; }+_ACEOF++# VPATH may cause trouble with some makes, so we remove $(srcdir),+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and+# trailing colons and then remove the whole line if VPATH becomes empty+# (actually we leave an empty line to preserve line numbers).+if test "x$srcdir" = x.; then+ ac_vpsub='/^[ ]*VPATH[ ]*=/{+s/:*\$(srcdir):*/:/+s/:*\${srcdir}:*/:/+s/:*@srcdir@:*/:/+s/^\([^=]*=[ ]*\):*/\1/+s/:*$//+s/^[^=]*=[ ]*$//+}'+fi++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+fi # test -n "$CONFIG_FILES"+++eval set X " :F $CONFIG_FILES "+shift+for ac_tag+do+ case $ac_tag in+ :[FHLC]) ac_mode=$ac_tag; continue;;+ esac+ case $ac_mode$ac_tag in+ :[FHL]*:*);;+ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5+$as_echo "$as_me: error: invalid tag $ac_tag" >&2;}+ { (exit 1); exit 1; }; };;+ :[FH]-) ac_tag=-:-;;+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;+ esac+ ac_save_IFS=$IFS+ IFS=:+ set x $ac_tag+ IFS=$ac_save_IFS+ shift+ ac_file=$1+ shift++ case $ac_mode in+ :L) ac_source=$1;;+ :[FH])+ ac_file_inputs=+ for ac_f+ do+ case $ac_f in+ -) ac_f="$tmp/stdin";;+ *) # Look for the file first in the build tree, then in the source tree+ # (if the path is not absolute). The absolute path cannot be DOS-style,+ # because $ac_f cannot contain `:'.+ test -f "$ac_f" ||+ case $ac_f in+ [\\/$]*) false;;+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;+ esac ||+ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5+$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;}+ { (exit 1); exit 1; }; };;+ esac+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac+ ac_file_inputs="$ac_file_inputs '$ac_f'"+ done++ # Let's still pretend it is `configure' which instantiates (i.e., don't+ # use $as_me), people would be surprised to read:+ # /* config.h. Generated by config.status. */+ configure_input='Generated from '`+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'+ `' by configure.'+ if test x"$ac_file" != x-; then+ configure_input="$ac_file. $configure_input"+ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5+$as_echo "$as_me: creating $ac_file" >&6;}+ fi+ # Neutralize special characters interpreted by sed in replacement strings.+ case $configure_input in #(+ *\&* | *\|* | *\\* )+ ac_sed_conf_input=`$as_echo "$configure_input" |+ sed 's/[\\\\&|]/\\\\&/g'`;; #(+ *) ac_sed_conf_input=$configure_input;;+ esac++ case $ac_tag in+ *:-:* | *:-) cat >"$tmp/stdin" \+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5+$as_echo "$as_me: error: could not create $ac_file" >&2;}+ { (exit 1); exit 1; }; } ;;+ esac+ ;;+ esac++ ac_dir=`$as_dirname -- "$ac_file" ||+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+ X"$ac_file" : 'X\(//\)[^/]' \| \+ X"$ac_file" : 'X\(//\)$' \| \+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$ac_file" |+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+ s//\1/+ q+ }+ /^X\(\/\/\)[^/].*/{+ s//\1/+ q+ }+ /^X\(\/\/\)$/{+ s//\1/+ q+ }+ /^X\(\/\).*/{+ s//\1/+ q+ }+ s/.*/./; q'`+ { as_dir="$ac_dir"+ case $as_dir in #(+ -*) as_dir=./$as_dir;;+ esac+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {+ as_dirs=+ while :; do+ case $as_dir in #(+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(+ *) as_qdir=$as_dir;;+ esac+ as_dirs="'$as_qdir' $as_dirs"+ as_dir=`$as_dirname -- "$as_dir" ||+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+ X"$as_dir" : 'X\(//\)[^/]' \| \+ X"$as_dir" : 'X\(//\)$' \| \+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$as_dir" |+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+ s//\1/+ q+ }+ /^X\(\/\/\)[^/].*/{+ s//\1/+ q+ }+ /^X\(\/\/\)$/{+ s//\1/+ q+ }+ /^X\(\/\).*/{+ s//\1/+ q+ }+ s/.*/./; q'`+ test -d "$as_dir" && break+ done+ test -z "$as_dirs" || eval "mkdir $as_dirs"+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}+ { (exit 1); exit 1; }; }; }+ ac_builddir=.++case "$ac_dir" in+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;+*)+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`+ # A ".." for each directory in $ac_dir_suffix.+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`+ case $ac_top_builddir_sub in+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;+ esac ;;+esac+ac_abs_top_builddir=$ac_pwd+ac_abs_builddir=$ac_pwd$ac_dir_suffix+# for backward compatibility:+ac_top_builddir=$ac_top_build_prefix++case $srcdir in+ .) # We are building in place.+ ac_srcdir=.+ ac_top_srcdir=$ac_top_builddir_sub+ ac_abs_top_srcdir=$ac_pwd ;;+ [\\/]* | ?:[\\/]* ) # Absolute name.+ ac_srcdir=$srcdir$ac_dir_suffix;+ ac_top_srcdir=$srcdir+ ac_abs_top_srcdir=$srcdir ;;+ *) # Relative name.+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix+ ac_top_srcdir=$ac_top_build_prefix$srcdir+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;+esac+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix+++ case $ac_mode in+ :F)+ #+ # CONFIG_FILE+ #++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# If the template does not know about datarootdir, expand it.+# FIXME: This hack should be removed a few years after 2.60.+ac_datarootdir_hack=; ac_datarootdir_seen=++ac_sed_dataroot='+/datarootdir/ {+ p+ q+}+/@datadir@/p+/@docdir@/p+/@infodir@/p+/@localedir@/p+/@mandir@/p+'+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in+*datarootdir*) ac_datarootdir_seen=yes;;+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}+_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ ac_datarootdir_hack='+ s&@datadir@&$datadir&g+ s&@docdir@&$docdir&g+ s&@infodir@&$infodir&g+ s&@localedir@&$localedir&g+ s&@mandir@&$mandir&g+ s&\\\${datarootdir}&$datarootdir&g' ;;+esac+_ACEOF++# Neutralize VPATH when `$srcdir' = `.'.+# Shell code in configure.ac might set extrasub.+# FIXME: do we really want to maintain this feature?+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ac_sed_extra="$ac_vpsub+$extrasub+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+:t+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b+s|@configure_input@|$ac_sed_conf_input|;t t+s&@top_builddir@&$ac_top_builddir_sub&;t t+s&@top_build_prefix@&$ac_top_build_prefix&;t t+s&@srcdir@&$ac_srcdir&;t t+s&@abs_srcdir@&$ac_abs_srcdir&;t t+s&@top_srcdir@&$ac_top_srcdir&;t t+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t+s&@builddir@&$ac_builddir&;t t+s&@abs_builddir@&$ac_abs_builddir&;t t+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t+$ac_datarootdir_hack+"+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5+$as_echo "$as_me: error: could not create $ac_file" >&2;}+ { (exit 1); exit 1; }; }++test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'+which seems to be undefined. Please make sure it is defined." >&5+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'+which seems to be undefined. Please make sure it is defined." >&2;}++ rm -f "$tmp/stdin"+ case $ac_file in+ -) cat "$tmp/out" && rm -f "$tmp/out";;+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;+ esac \+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5+$as_echo "$as_me: error: could not create $ac_file" >&2;}+ { (exit 1); exit 1; }; }+ ;;++++ esac++done # for ac_tag+++{ (exit 0); exit 0; }+_ACEOF+chmod +x $CONFIG_STATUS+ac_clean_files=$ac_clean_files_save++test $ac_write_fail = 0 ||+ { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5+$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;}+ { (exit 1); exit 1; }; }+++# configure is writing to config.log, and then calls config.status.+# config.status does its own redirection, appending to config.log.+# Unfortunately, on DOS this fails, as config.log is still kept open+# by configure, so config.status won't be able to write to it; its+# output is simply discarded. So we exec the FD to /dev/null,+# effectively closing config.log, so it can be properly (re)opened and+# appended to by config.status. When coming back to configure, we+# need to make the FD available again.+if test "$no_create" != yes; then+ ac_cs_success=:+ ac_config_status_args=+ test "$silent" = yes &&+ ac_config_status_args="$ac_config_status_args --quiet"+ exec 5>/dev/null+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false+ exec 5>>config.log+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which+ # would make configure fail if this is the last instruction.+ $ac_cs_success || { (exit 1); exit 1; }+fi+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then+ { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}+fi+
+ llvm-data-interop.buildinfo.in view
@@ -0,0 +1,7 @@+cpp-options: @llvm_cppflags@ -DTARGET=@llvm_target@+ghc-options: -pgml @CXX@+extra-libraries: LLVM-@llvm_version@ stdc+++extra-lib-dirs: @llvm_extra_libdirs@+x-extra-ghci-libraries: LLVM-@llvm_version@+ld-options: @llvm_ldoptions@ -Wl,-rpath,@llvm_libdir@+include-dirs: @llvm_includedir@
+ llvm-data-interop.cabal view
@@ -0,0 +1,50 @@+name: llvm-data-interop+version: 0.3.0+synopsis: A low-level data interoperability binding for LLVM+license: BSD3+license-file: LICENSE+author: Tristan Ravitch+maintainer: travitch@cs.wisc.edu+category: Data+build-type: Custom+tested-with: GHC == 7.6.3+cabal-version: >=1.10+Description: This package converts the LLVM IR (either bitcode files or LLVM+ assembly) into a Haskell data type (defined in llvm-base-types).+ The conversion uses the LLVM libraries to read bitcode. It then+ traverses the IR and produces a Haskell structure that can be+ pattern matched against in pure code.++ Note that this library works with LLVM 3.0-3.3.++ There are incompatible changes in this release relative to+ llvm-data-interop 0.2.0. See the changelog in llvm-analysis-0.3.0.++extra-source-files: configure,+ llvm-data-interop.buildinfo.in,+ src/c++/marshal.h,+ README.md++library+ default-language: Haskell2010+ build-depends: base == 4.*,+ data-default >= 0.3,+ mtl > 2,+ hashable >= 1.1.2.0,+ llvm-base-types >= 0.3.0,+ loch-th >= 0.2,+ unification-fd >= 0.8,+ unordered-containers >= 0.2.1.0,+ hashtables, vector, transformers, text,+ array, bytestring, containers, dwarf, deepseq+ other-modules: LLVM.Internal.Interop+ LLVM.Internal.TypeUnification+ exposed-modules: LLVM.Parse+ build-tools: c2hs+ c-sources: src/c++/marshal.cpp+ extra-libraries: stdc+++ ghc-options: -Wall+ ghc-prof-options: -auto-all+ include-dirs: src+ hs-source-dirs: src+ cc-options: -fvisibility-inlines-hidden -fvisibility=hidden
+ src/LLVM/Internal/Interop.chs view
@@ -0,0 +1,644 @@+{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable, RankNTypes, OverloadedStrings, CPP #-}+module LLVM.Internal.Interop where++import Control.Applicative+import Control.Monad ( when )+import Control.Monad.Trans ( MonadIO, liftIO )+import Data.Array.Storable ( getElems )+#if __GLASGOW_HASKELL__ >= 704+import Data.Array.Unsafe ( unsafeForeignPtrToStorableArray )+#else+import Data.Array.Storable ( unsafeForeignPtrToStorableArray )+#endif+import qualified Data.ByteString.Char8 as BS+import Data.Int+import Data.Text ( Text )+import Data.Text.Encoding ( decodeUtf8 )+import Foreign.C+import Foreign.ForeignPtr+import Foreign.Marshal.Utils+import Foreign.Ptr+import Foreign.Storable++import Data.LLVM.Types++#include "c++/marshal.h"++{#enum TypeTag {} deriving (Show, Eq) #}+{#enum ValueTag {underscoreToCase} deriving (Show, Eq) #}+{#enum MetaTag {underscoreToCase} deriving (Show, Eq) #}++data CModule+{#pointer *CModule as ModulePtr -> CModule #}++makeText :: CString -> IO Text+makeText p = do+ s <- BS.packCString p+ return (decodeUtf8 s)++cModuleIdentifier :: ModulePtr -> IO Text+cModuleIdentifier m = ({#get CModule->moduleIdentifier#} m) >>= makeText++cModuleDataLayout :: ModulePtr -> IO Text+cModuleDataLayout m = ({#get CModule->moduleDataLayout#} m) >>= makeText++cModuleTargetTriple :: ModulePtr -> IO Text+cModuleTargetTriple m = ({#get CModule->targetTriple#} m) >>= makeText++cModuleInlineAsm :: ModulePtr -> IO Text+cModuleInlineAsm m = ({#get CModule->moduleInlineAsm#} m) >>= makeText++cModuleHasError :: ModulePtr -> IO Bool+cModuleHasError m = toBool <$> ({#get CModule->hasError#} m)++cModuleErrorMessage :: ModulePtr -> IO (Maybe String)+cModuleErrorMessage m = do+ hasError <- cModuleHasError m+ case hasError of+ True -> do+ msgPtr <- ({#get CModule->errMsg#} m)+ s <- peekCString msgPtr+ return (Just s)+ False -> return Nothing++cModuleLittleEndian :: ModulePtr -> IO Bool+cModuleLittleEndian m = toBool <$> ({#get CModule->littleEndian#} m)++cModulePointerSize :: ModulePtr -> IO Int+cModulePointerSize m = fromIntegral <$> ({#get CModule->pointerSize#} m)++cModuleGlobalVariables :: ModulePtr -> IO [ValuePtr]+cModuleGlobalVariables m =+ peekArray m {#get CModule->globalVariables#} {#get CModule->numGlobalVariables#}++cModuleGlobalAliases :: ModulePtr -> IO [ValuePtr]+cModuleGlobalAliases m =+ peekArray m ({#get CModule->globalAliases#}) ({#get CModule->numGlobalAliases#})++cModuleFunctions :: ModulePtr -> IO [ValuePtr]+cModuleFunctions m =+ peekArray m ({#get CModule->functions#}) ({#get CModule->numFunctions#})++cModuleEnumMetadata :: ModulePtr -> IO [MetaPtr]+cModuleEnumMetadata m =+ peekArray m {#get CModule->enumMetadata#} {#get CModule->numEnumMetadata#}++cModuleRetainedTypeMetadata :: ModulePtr -> IO [MetaPtr]+cModuleRetainedTypeMetadata m =+ peekArray m {#get CModule->retainedTypeMetadata#} {#get CModule->numRetainedTypes#}++cModuleTypes :: ModulePtr -> IO [TypePtr]+cModuleTypes m =+ peekArray m {#get CModule->types#} {#get CModule->numTypes#}++peekArray :: forall a b c e . (Integral c, Storable e) =>+ a -> (a -> IO (Ptr b)) -> (a -> IO c) -> IO [e]+peekArray obj arrAccessor sizeAccessor = do+ nElts <- sizeAccessor obj+ arrPtr <- arrAccessor obj+ case nElts == 0 || arrPtr == nullPtr of+ True -> return []+ False -> do+ fArrPtr <- newForeignPtr_ (castPtr arrPtr)+ let elementCount :: Int+ elementCount = fromIntegral nElts+ arr <- unsafeForeignPtrToStorableArray fArrPtr (1, elementCount)+ getElems arr++data CType+{#pointer *CType as TypePtr -> CType #}+cTypeTag :: TypePtr -> IO TypeTag+cTypeTag t = toEnum . fromIntegral <$> {#get CType->typeTag#} t+cTypeSize :: TypePtr -> IO Int+cTypeSize t = fromIntegral <$> {#get CType->size#} t+cTypeIsVarArg :: TypePtr -> IO Bool+cTypeIsVarArg t = toBool <$> {#get CType->isVarArg#} t+cTypeIsPacked :: TypePtr -> IO Bool+cTypeIsPacked t = toBool <$> {#get CType->isPacked#} t+cTypeList :: TypePtr -> IO [TypePtr]+cTypeList t =+ peekArray t {#get CType->typeList#} {#get CType->typeListLen#}+cTypeInner :: TypePtr -> IO TypePtr+cTypeInner = {#get CType->innerType#}+cTypeName :: TypePtr -> IO (Maybe String)+cTypeName t = do+ n <- optionalField {#get CType->name#} t+ case n of+ Nothing -> return Nothing+ Just n' -> do+ s <- peekCString n'+ return (Just s)+cTypeAddrSpace :: TypePtr -> IO Int+cTypeAddrSpace t = fromIntegral <$> {#get CType->addrSpace#} t++cTypeSizeInBytes :: TypePtr -> IO Int+cTypeSizeInBytes t = fromIntegral <$> {#get CType->sizeInBytes#} t++data CValue+{#pointer *CValue as ValuePtr -> CValue #}+data CMeta+{#pointer *CMeta as MetaPtr -> CMeta #}++cValueTag :: ValuePtr -> IO ValueTag+cValueTag v = toEnum . fromIntegral <$> ({#get CValue->valueTag#} v)+cValueType :: ValuePtr -> IO TypePtr+cValueType = {#get CValue->valueType#}+cValueName :: (InternString m) => ValuePtr -> m (Maybe Identifier)+cValueName v = do+ tag <- liftIO $ cValueTag v+ namePtr <- liftIO $ ({#get CValue->name#}) v+ case namePtr == nullPtr of+ True -> return Nothing+ False -> do+ rawName <- liftIO $ makeText namePtr+ name <- internString rawName+ rawIdent <- case tag of+ ValFunction -> return $! makeGlobalIdentifier name+ ValGlobalvariable -> return $! makeGlobalIdentifier name+ ValAlias -> return $! makeGlobalIdentifier name+ _ -> return $! makeLocalIdentifier name+ ident <- internIdentifier rawIdent+ return $! (Just ident)+cValueMetadata :: ValuePtr -> IO [MetaPtr]+cValueMetadata v = peekArray v {#get CValue->md#} {#get CValue->numMetadata#}+cValueSrcLoc :: ValuePtr -> IO MetaPtr+cValueSrcLoc = {#get CValue->srcLoc#}+cValueData :: ValuePtr -> IO (Ptr ())+cValueData = {#get CValue->data#}+++cMetaTypeTag :: MetaPtr -> IO MetaTag+cMetaTypeTag v = toEnum . fromIntegral <$> {#get CMeta->metaTag #} v++cMetaTag :: MetaPtr -> IO DW_TAG+cMetaTag p = do+ t <- {#get CMeta->tag#} p+ case dw_tag t of+ Nothing -> return DW_TAG_unspecified_type+ Just t' -> return t'++cMetaArrayElts :: MetaPtr -> IO [Maybe MetaPtr]+cMetaArrayElts p = map convertNull <$>+ peekArray p {#get CMeta->u.metaArrayInfo.arrayElts#} {#get CMeta->u.metaArrayInfo.arrayLen#}+ where+ convertNull ptr =+ case ptr == nullPtr of+ True -> Nothing+ False -> Just ptr++cMetaEnumeratorName :: InternString m => MetaPtr -> m Text+cMetaEnumeratorName = shareString {#get CMeta->u.metaEnumeratorInfo.enumName#}+cMetaEnumeratorValue :: MetaPtr -> IO Int64+cMetaEnumeratorValue p = fromIntegral <$> {#get CMeta->u.metaEnumeratorInfo.enumValue#} p+cMetaGlobalContext :: MetaPtr -> IO (Maybe MetaPtr)+cMetaGlobalContext = optionalField {#get CMeta->u.metaGlobalInfo.context #}+cMetaGlobalName :: InternString m => MetaPtr -> m Text+cMetaGlobalName = shareString {#get CMeta->u.metaGlobalInfo.name#}+cMetaGlobalDisplayName :: InternString m => MetaPtr -> m Text+cMetaGlobalDisplayName = shareString {#get CMeta->u.metaGlobalInfo.displayName#}+cMetaGlobalLinkageName :: InternString m => MetaPtr -> m Text+cMetaGlobalLinkageName = shareString {#get CMeta->u.metaGlobalInfo.linkageName#}+-- cMetaGlobalCompileUnit :: MetaPtr -> IO MetaPtr+-- cMetaGlobalCompileUnit = {#get CMeta->u.metaGlobalInfo.compileUnit#}+cMetaGlobalLine :: MetaPtr -> IO Int32+cMetaGlobalLine p = fromIntegral <$> {#get CMeta->u.metaGlobalInfo.lineNumber#} p+cMetaGlobalType :: MetaPtr -> IO (Maybe MetaPtr)+cMetaGlobalType = optionalField {#get CMeta->u.metaGlobalInfo.globalType#}+cMetaGlobalIsLocal :: MetaPtr -> IO Bool+cMetaGlobalIsLocal p = toBool <$> {#get CMeta->u.metaGlobalInfo.isLocalToUnit#} p+cMetaGlobalIsDefinition :: MetaPtr -> IO Bool+cMetaGlobalIsDefinition p = toBool <$> {#get CMeta->u.metaGlobalInfo.isDefinition#} p+cMetaLocationLine :: MetaPtr -> IO Int32+cMetaLocationLine p = fromIntegral <$> {#get CMeta->u.metaLocationInfo.lineNumber#} p+cMetaLocationColumn :: MetaPtr -> IO Int32+cMetaLocationColumn p = fromIntegral <$> {#get CMeta->u.metaLocationInfo.columnNumber#} p+cMetaLocationScope :: MetaPtr -> IO (Maybe MetaPtr)+cMetaLocationScope = optionalField {#get CMeta->u.metaLocationInfo.scope#}+cMetaSubrangeLo :: MetaPtr -> IO Int64+cMetaSubrangeLo p = fromIntegral <$> {#get CMeta->u.metaSubrangeInfo.lo#} p+cMetaSubrangeHi :: MetaPtr -> IO Int64+cMetaSubrangeHi p = fromIntegral <$> {#get CMeta->u.metaSubrangeInfo.hi#} p+cMetaTemplateTypeContext :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTemplateTypeContext = optionalField {#get CMeta->u.metaTemplateTypeInfo.context#}+cMetaTemplateTypeName :: InternString m => MetaPtr -> m Text+cMetaTemplateTypeName = shareString {#get CMeta->u.metaTemplateTypeInfo.name#}+cMetaTemplateTypeType :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTemplateTypeType = optionalField {#get CMeta->u.metaTemplateTypeInfo.type#}+cMetaTemplateTypeLine :: MetaPtr -> IO Int32+cMetaTemplateTypeLine p = fromIntegral <$> {#get CMeta->u.metaTemplateTypeInfo.lineNumber#} p+cMetaTemplateTypeColumn :: MetaPtr -> IO Int32+cMetaTemplateTypeColumn p = fromIntegral <$> {#get CMeta->u.metaTemplateTypeInfo.columnNumber#} p+cMetaTemplateValueContext :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTemplateValueContext = optionalField {#get CMeta->u.metaTemplateValueInfo.context#}+cMetaTemplateValueName :: InternString m => MetaPtr -> m Text+cMetaTemplateValueName = shareString {#get CMeta->u.metaTemplateValueInfo.name#}+cMetaTemplateValueType :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTemplateValueType = optionalField {#get CMeta->u.metaTemplateValueInfo.type#}+cMetaTemplateValueValue :: MetaPtr -> IO Int64+cMetaTemplateValueValue p = fromIntegral <$> {#get CMeta->u.metaTemplateValueInfo.value#} p+cMetaTemplateValueLine :: MetaPtr -> IO Int32+cMetaTemplateValueLine p = fromIntegral <$> {#get CMeta->u.metaTemplateValueInfo.lineNumber#} p+cMetaTemplateValueColumn :: MetaPtr -> IO Int32+cMetaTemplateValueColumn p = fromIntegral <$> {#get CMeta->u.metaTemplateValueInfo.columnNumber#} p+cMetaVariableContext :: MetaPtr -> IO (Maybe MetaPtr)+cMetaVariableContext = optionalField {#get CMeta->u.metaVariableInfo.context#}+cMetaVariableName :: InternString m => MetaPtr -> m Text+cMetaVariableName = shareString {#get CMeta->u.metaVariableInfo.name#}+-- cMetaVariableCompileUnit :: MetaPtr -> IO MetaPtr+-- cMetaVariableCompileUnit = {#get CMeta->u.metaVariableInfo.compileUnit#}+cMetaVariableLine :: MetaPtr -> IO Int32+cMetaVariableLine p = fromIntegral <$> {#get CMeta->u.metaVariableInfo.lineNumber#} p+cMetaVariableArgNumber :: MetaPtr -> IO Int32+cMetaVariableArgNumber p = fromIntegral <$> {#get CMeta->u.metaVariableInfo.argNumber#} p+cMetaVariableType :: MetaPtr -> IO (Maybe MetaPtr)+cMetaVariableType = optionalField {#get CMeta->u.metaVariableInfo.type#}+cMetaVariableIsArtificial :: MetaPtr -> IO Bool+cMetaVariableIsArtificial p = toBool <$> {#get CMeta->u.metaVariableInfo.isArtificial#} p+cMetaVariableHasComplexAddress :: MetaPtr -> IO Bool+cMetaVariableHasComplexAddress p = toBool <$> {#get CMeta->u.metaVariableInfo.hasComplexAddress #} p+cMetaVariableAddrElements :: MetaPtr -> IO [Int64]+cMetaVariableAddrElements p = do+ ca <- cMetaVariableHasComplexAddress p+ case ca of+ True -> peekArray p {#get CMeta->u.metaVariableInfo.addrElements#} {#get CMeta->u.metaVariableInfo.numAddrElements#}+ False -> return []+cMetaVariableIsBlockByRefVar :: MetaPtr -> IO Bool+cMetaVariableIsBlockByRefVar p = toBool <$> {#get CMeta->u.metaVariableInfo.isBlockByRefVar#} p+cMetaCompileUnitLanguage :: MetaPtr -> IO DW_LANG+cMetaCompileUnitLanguage p = dw_lang <$> {#get CMeta->u.metaCompileUnitInfo.language#} p+cMetaCompileUnitFilename :: InternString m => MetaPtr -> m Text+cMetaCompileUnitFilename = shareString {#get CMeta->u.metaCompileUnitInfo.filename#}+cMetaCompileUnitDirectory :: InternString m => MetaPtr -> m Text+cMetaCompileUnitDirectory = shareString {#get CMeta->u.metaCompileUnitInfo.directory#}+cMetaCompileUnitProducer :: InternString m => MetaPtr -> m Text+cMetaCompileUnitProducer = shareString {#get CMeta->u.metaCompileUnitInfo.producer#}+cMetaCompileUnitIsMain :: MetaPtr -> IO Bool+cMetaCompileUnitIsMain p = toBool <$> {#get CMeta->u.metaCompileUnitInfo.isMain#} p+cMetaCompileUnitIsOptimized :: MetaPtr -> IO Bool+cMetaCompileUnitIsOptimized p = toBool <$> {#get CMeta->u.metaCompileUnitInfo.isOptimized#} p+cMetaCompileUnitFlags :: InternString m => MetaPtr -> m Text+cMetaCompileUnitFlags = shareString {#get CMeta->u.metaCompileUnitInfo.flags#}+cMetaCompileUnitRuntimeVersion :: MetaPtr -> IO Int32+cMetaCompileUnitRuntimeVersion p = fromIntegral <$> {#get CMeta->u.metaCompileUnitInfo.runtimeVersion#} p+cMetaCompileUnitEnumTypes :: MetaPtr -> IO (Maybe MetaPtr)+cMetaCompileUnitEnumTypes = optionalField {#get CMeta->u.metaCompileUnitInfo.enumTypes#}+cMetaCompileUnitRetainedTypes :: MetaPtr -> IO (Maybe MetaPtr)+cMetaCompileUnitRetainedTypes = optionalField {#get CMeta->u.metaCompileUnitInfo.retainedTypes#}+cMetaCompileUnitSubprograms :: MetaPtr -> IO (Maybe MetaPtr)+cMetaCompileUnitSubprograms = optionalField {#get CMeta->u.metaCompileUnitInfo.subprograms#}+cMetaCompileUnitGlobalVariables :: MetaPtr -> IO (Maybe MetaPtr)+cMetaCompileUnitGlobalVariables = optionalField {#get CMeta->u.metaCompileUnitInfo.globalVariables#}+cMetaFileFilename :: InternString m => MetaPtr -> m Text+cMetaFileFilename = shareString {#get CMeta->u.metaFileInfo.filename#}+cMetaFileDirectory :: InternString m => MetaPtr -> m Text+cMetaFileDirectory = shareString {#get CMeta->u.metaFileInfo.directory#}+-- cMetaFileCompileUnit :: MetaPtr -> IO MetaPtr+-- cMetaFileCompileUnit = {#get CMeta->u.metaFileInfo.compileUnit#}+cMetaLexicalBlockContext :: MetaPtr -> IO (Maybe MetaPtr)+cMetaLexicalBlockContext = optionalField {#get CMeta->u.metaLexicalBlockInfo.context#}+cMetaLexicalBlockLine :: MetaPtr -> IO Int32+cMetaLexicalBlockLine p = fromIntegral <$> {#get CMeta->u.metaLexicalBlockInfo.lineNumber#} p+cMetaLexicalBlockColumn :: MetaPtr -> IO Int32+cMetaLexicalBlockColumn p = fromIntegral <$> {#get CMeta->u.metaLexicalBlockInfo.columnNumber#} p+cMetaNamespaceContext :: MetaPtr -> IO (Maybe MetaPtr)+cMetaNamespaceContext = optionalField {#get CMeta->u.metaNamespaceInfo.context#}+cMetaNamespaceName :: InternString m => MetaPtr -> m Text+cMetaNamespaceName = shareString {#get CMeta->u.metaNamespaceInfo.name#}+-- cMetaNamespaceCompileUnit :: MetaPtr -> IO MetaPtr+-- cMetaNamespaceCompileUnit = {#get CMeta->u.metaNamespaceInfo.compileUnit#}+cMetaNamespaceLine :: MetaPtr -> IO Int32+cMetaNamespaceLine p = fromIntegral <$> {#get CMeta->u.metaNamespaceInfo.lineNumber#} p+cMetaSubprogramContext :: MetaPtr -> IO (Maybe MetaPtr)+cMetaSubprogramContext = optionalField {#get CMeta->u.metaSubprogramInfo.context#}+cMetaSubprogramName :: InternString m => MetaPtr -> m Text+cMetaSubprogramName = shareString {#get CMeta->u.metaSubprogramInfo.name#}+cMetaSubprogramDisplayName :: InternString m => MetaPtr -> m Text+cMetaSubprogramDisplayName = shareString {#get CMeta->u.metaSubprogramInfo.displayName#}+cMetaSubprogramLinkageName :: InternString m => MetaPtr -> m Text+cMetaSubprogramLinkageName = shareString {#get CMeta->u.metaSubprogramInfo.linkageName#}+-- cMetaSubprogramCompileUnit :: MetaPtr -> IO MetaPtr+-- cMetaSubprogramCompileUnit = {#get CMeta->u.metaSubprogramInfo.compileUnit#}+cMetaSubprogramLine :: MetaPtr -> IO Int32+cMetaSubprogramLine p = fromIntegral <$> {#get CMeta->u.metaSubprogramInfo.lineNumber#} p+cMetaSubprogramType :: MetaPtr -> IO (Maybe MetaPtr)+cMetaSubprogramType = optionalField {#get CMeta->u.metaSubprogramInfo.type#}+cMetaSubprogramIsLocal :: MetaPtr -> IO Bool+cMetaSubprogramIsLocal p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isLocalToUnit#} p+cMetaSubprogramIsDefinition :: MetaPtr -> IO Bool+cMetaSubprogramIsDefinition p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isDefinition#} p+cMetaSubprogramVirtuality :: MetaPtr -> IO DW_VIRTUALITY+cMetaSubprogramVirtuality p = dw_virtuality <$> {#get CMeta->u.metaSubprogramInfo.virtuality#} p+cMetaSubprogramVirtualIndex :: MetaPtr -> IO Int32+cMetaSubprogramVirtualIndex p = fromIntegral <$> {#get CMeta->u.metaSubprogramInfo.virtualIndex#} p+cMetaSubprogramContainingType :: MetaPtr -> IO (Maybe MetaPtr)+cMetaSubprogramContainingType = optionalField {#get CMeta->u.metaSubprogramInfo.containingType#}+cMetaSubprogramIsArtificial :: MetaPtr -> IO Bool+cMetaSubprogramIsArtificial p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isArtificial#} p+cMetaSubprogramIsPrivate :: MetaPtr -> IO Bool+cMetaSubprogramIsPrivate p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isPrivate#} p+cMetaSubprogramIsProtected :: MetaPtr -> IO Bool+cMetaSubprogramIsProtected p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isProtected#} p+cMetaSubprogramIsExplicit :: MetaPtr -> IO Bool+cMetaSubprogramIsExplicit p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isExplicit#} p+cMetaSubprogramIsPrototyped :: MetaPtr -> IO Bool+cMetaSubprogramIsPrototyped p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isPrototyped#} p+cMetaSubprogramIsOptimized :: MetaPtr -> IO Bool+cMetaSubprogramIsOptimized p = toBool <$> {#get CMeta->u.metaSubprogramInfo.isOptimized#} p+cMetaTypeContext :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTypeContext = optionalField {#get CMeta->u.metaTypeInfo.context#}+cMetaTypeName :: InternString m => MetaPtr -> m Text+cMetaTypeName = shareString {#get CMeta->u.metaTypeInfo.name#}+-- cMetaTypeCompileUnit :: MetaPtr -> IO (Maybe MetaPtr)+-- cMetaTypeCompileUnit = optionalField {#get CMeta->u.metaTypeInfo.compileUnit#}+-- cMetaTypeFile :: MetaPtr -> IO (Maybe MetaPtr)+-- cMetaTypeFile = optionalField {#get CMeta->u.metaTypeInfo.file#}+cMetaTypeLine :: MetaPtr -> IO Int32+cMetaTypeLine p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.lineNumber#} p+cMetaTypeSize :: MetaPtr -> IO Int64+cMetaTypeSize p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.sizeInBits#} p+cMetaTypeAlign :: MetaPtr -> IO Int64+cMetaTypeAlign p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.alignInBits#} p+cMetaTypeOffset :: MetaPtr -> IO Int64+cMetaTypeOffset p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.offsetInBits#} p+cMetaTypeFlags :: MetaPtr -> IO Int32+cMetaTypeFlags p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.flags#} p+cMetaTypeIsPrivate :: MetaPtr -> IO Bool+cMetaTypeIsPrivate p = toBool <$> {#get CMeta->u.metaTypeInfo.isPrivate#} p+cMetaTypeIsProtected :: MetaPtr -> IO Bool+cMetaTypeIsProtected p = toBool <$> {#get CMeta->u.metaTypeInfo.isProtected#} p+cMetaTypeIsForward :: MetaPtr -> IO Bool+cMetaTypeIsForward p = toBool <$> {#get CMeta->u.metaTypeInfo.isForward#} p+cMetaTypeIsByRefStruct :: MetaPtr -> IO Bool+cMetaTypeIsByRefStruct p = toBool <$> {#get CMeta->u.metaTypeInfo.isByRefStruct#} p+cMetaTypeIsVirtual :: MetaPtr -> IO Bool+cMetaTypeIsVirtual p = toBool <$> {#get CMeta->u.metaTypeInfo.isVirtual#} p+cMetaTypeIsArtificial :: MetaPtr -> IO Bool+cMetaTypeIsArtificial p = toBool <$> {#get CMeta->u.metaTypeInfo.isArtificial#} p+cMetaTypeDirectory :: InternString m => MetaPtr -> m Text+cMetaTypeDirectory = shareString {#get CMeta->u.metaTypeInfo.directory#}+cMetaTypeFilename :: InternString m => MetaPtr -> m Text+cMetaTypeFilename = shareString {#get CMeta->u.metaTypeInfo.filename#}+cMetaTypeEncoding :: MetaPtr -> IO DW_ATE+cMetaTypeEncoding p = dw_ate <$> {#get CMeta->u.metaTypeInfo.encoding#} p+cMetaTypeDerivedFrom :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTypeDerivedFrom = optionalField {#get CMeta->u.metaTypeInfo.typeDerivedFrom#}+cMetaTypeCompositeComponents :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTypeCompositeComponents = optionalField {#get CMeta->u.metaTypeInfo.typeArray#}+cMetaTypeRuntimeLanguage :: MetaPtr -> IO Int32+cMetaTypeRuntimeLanguage p = fromIntegral <$> {#get CMeta->u.metaTypeInfo.runTimeLang#} p+cMetaTypeContainingType :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTypeContainingType = optionalField {#get CMeta->u.metaTypeInfo.containingType#}+cMetaTypeTemplateParams :: MetaPtr -> IO (Maybe MetaPtr)+cMetaTypeTemplateParams = optionalField {#get CMeta->u.metaTypeInfo.templateParams#}+cMetaUnknownRepr :: InternString m => MetaPtr -> m Text+cMetaUnknownRepr = shareString {#get CMeta->u.metaUnknownInfo.repr#}++optionalField :: (a -> IO (Ptr b)) -> a -> IO (Maybe (Ptr b))+optionalField accessor p = do+ v <- accessor p+ case v == nullPtr of+ True -> return Nothing+ False -> return (Just v)++class MonadIO m => InternString m where+ internString :: Text -> m Text+ internIdentifier :: Identifier -> m Identifier++-- | This helper converts C char* strings into Texts, sharing+-- identical bytestrings on the Haskell side. This is a simple+-- space-saving optimization (assuming the entire cache is garbage+-- collected)+shareString :: InternString m => (a -> IO CString) -> a -> m Text+shareString accessor ptr = do+ sp <- liftIO $ accessor ptr+ str <- case sp == nullPtr of+ False -> liftIO $ BS.packCString sp+ True -> return $ BS.pack ""+ internString (decodeUtf8 str)++data CGlobalInfo+{#pointer *CGlobalInfo as GlobalInfoPtr -> CGlobalInfo #}+cGlobalIsExternal :: GlobalInfoPtr -> IO Bool+cGlobalIsExternal g = toBool <$> ({#get CGlobalInfo->isExternal#} g)+cGlobalAlignment :: GlobalInfoPtr -> IO Int64+cGlobalAlignment g = fromIntegral <$> ({#get CGlobalInfo->alignment#} g)+cGlobalVisibility :: GlobalInfoPtr -> IO VisibilityStyle+cGlobalVisibility g = toEnum . fromIntegral <$> ({#get CGlobalInfo->visibility#} g)+cGlobalLinkage :: GlobalInfoPtr -> IO LinkageType+cGlobalLinkage g = toEnum . fromIntegral <$> ({#get CGlobalInfo->linkage#} g)+cGlobalSection :: GlobalInfoPtr -> IO (Maybe Text)+cGlobalSection g = do+ s <- {#get CGlobalInfo->section#} g+ case s == nullPtr of+ True -> return Nothing+ False -> do+ bs <- BS.packCString s+ return $! Just (decodeUtf8 bs)+cGlobalInitializer :: GlobalInfoPtr -> IO ValuePtr+cGlobalInitializer = {#get CGlobalInfo->initializer#}+cGlobalIsThreadLocal :: GlobalInfoPtr -> IO Bool+cGlobalIsThreadLocal g = toBool <$> ({#get CGlobalInfo->isThreadLocal#} g)+cGlobalAliasee :: GlobalInfoPtr -> IO ValuePtr+cGlobalAliasee = {#get CGlobalInfo->aliasee#}+cGlobalIsConstant :: GlobalInfoPtr -> IO Bool+cGlobalIsConstant g = toBool <$> {#get CGlobalInfo->isConstant#} g++data CFunctionInfo+{#pointer *CFunctionInfo as FunctionInfoPtr -> CFunctionInfo #}+cFunctionIsExternal :: FunctionInfoPtr -> IO Bool+cFunctionIsExternal f = toBool <$> {#get CFunctionInfo->isExternal#} f+cFunctionAlignment :: FunctionInfoPtr -> IO Int64+cFunctionAlignment f = fromIntegral <$> {#get CFunctionInfo->alignment#} f+cFunctionVisibility :: FunctionInfoPtr -> IO VisibilityStyle+cFunctionVisibility f = toEnum . fromIntegral <$> {#get CFunctionInfo->visibility#} f+cFunctionLinkage :: FunctionInfoPtr -> IO LinkageType+cFunctionLinkage f = toEnum . fromIntegral <$> {#get CFunctionInfo->linkage#} f+cFunctionSection :: FunctionInfoPtr -> IO (Maybe Text)+cFunctionSection f = do+ s <- {#get CFunctionInfo->section#} f+ case s == nullPtr of+ True -> return Nothing+ False -> do+ bs <- BS.packCString s+ return $! Just (decodeUtf8 bs)+cFunctionIsVarArg :: FunctionInfoPtr -> IO Bool+cFunctionIsVarArg f = toBool <$> {#get CFunctionInfo->isVarArg#} f+cFunctionCallingConvention :: FunctionInfoPtr -> IO CallingConvention+cFunctionCallingConvention f = toEnum . fromIntegral <$> {#get CFunctionInfo->callingConvention#} f+cFunctionGCName :: FunctionInfoPtr -> IO (Maybe Text)+cFunctionGCName f = do+ s <- {#get CFunctionInfo->gcName#} f+ case s == nullPtr of+ True -> return Nothing+ False -> do+ bs <- BS.packCString s+ return $! Just (decodeUtf8 bs)+cFunctionArguments :: FunctionInfoPtr -> IO [ValuePtr]+cFunctionArguments f =+ peekArray f {#get CFunctionInfo->arguments#} {#get CFunctionInfo->argListLen#}+cFunctionBlocks :: FunctionInfoPtr -> IO [ValuePtr]+cFunctionBlocks f =+ peekArray f {#get CFunctionInfo->body#} {#get CFunctionInfo->blockListLen#}++data CArgInfo+{#pointer *CArgumentInfo as ArgInfoPtr -> CArgInfo #}+cArgInfoHasSRet :: ArgInfoPtr -> IO Bool+cArgInfoHasSRet a = toBool <$> ({#get CArgumentInfo->hasSRet#} a)+cArgInfoHasByVal :: ArgInfoPtr -> IO Bool+cArgInfoHasByVal a = toBool <$> ({#get CArgumentInfo->hasByVal#} a)+cArgInfoHasNest :: ArgInfoPtr -> IO Bool+cArgInfoHasNest a = toBool <$> ({#get CArgumentInfo->hasNest#} a)+cArgInfoHasNoAlias :: ArgInfoPtr -> IO Bool+cArgInfoHasNoAlias a = toBool <$> ({#get CArgumentInfo->hasNoAlias#} a)+cArgInfoHasNoCapture :: ArgInfoPtr -> IO Bool+cArgInfoHasNoCapture a = toBool <$> ({#get CArgumentInfo->hasNoCapture#} a)++data CBasicBlockInfo+{#pointer *CBasicBlockInfo as BasicBlockPtr -> CBasicBlockInfo #}++cBasicBlockInstructions :: BasicBlockPtr -> IO [ValuePtr]+cBasicBlockInstructions b =+ peekArray b {#get CBasicBlockInfo->instructions#} {#get CBasicBlockInfo->blockLen#}++data CInlineAsmInfo+{#pointer *CInlineAsmInfo as InlineAsmInfoPtr -> CInlineAsmInfo #}++cInlineAsmString :: InlineAsmInfoPtr -> IO Text+cInlineAsmString a =+ ({#get CInlineAsmInfo->asmString#} a) >>= makeText+cInlineAsmConstraints :: InlineAsmInfoPtr -> IO Text+cInlineAsmConstraints a =+ ({#get CInlineAsmInfo->constraintString#} a) >>= makeText++data CBlockAddrInfo+{#pointer *CBlockAddrInfo as BlockAddrInfoPtr -> CBlockAddrInfo #}++cBlockAddrFunc :: BlockAddrInfoPtr -> IO ValuePtr+cBlockAddrFunc = {#get CBlockAddrInfo->func #}+cBlockAddrBlock :: BlockAddrInfoPtr -> IO ValuePtr+cBlockAddrBlock = {#get CBlockAddrInfo->block #}++data CAggregateInfo+{#pointer *CConstAggregate as AggregateInfoPtr -> CAggregateInfo #}++cAggregateValues :: AggregateInfoPtr -> IO [ValuePtr]+cAggregateValues a =+ peekArray a {#get CConstAggregate->constants#} {#get CConstAggregate->numElements#}++data CConstFP+{#pointer *CConstFP as FPInfoPtr -> CConstFP #}+cFPVal :: FPInfoPtr -> IO Double+cFPVal f = realToFrac <$> ({#get CConstFP->val#} f)++data CConstInt+{#pointer *CConstInt as IntInfoPtr -> CConstInt #}+cIntVal :: IntInfoPtr -> IO Integer+cIntVal i = fromIntegral <$> ({#get CConstInt->val#} i)+cIntHugeVal :: IntInfoPtr -> IO (Maybe Integer)+cIntHugeVal i = do+ s <- {#get CConstInt->hugeVal#} i+ case s == nullPtr of+ True -> return Nothing+ False -> (Just . read) <$> peekCString s++data CInstructionInfo+{#pointer *CInstructionInfo as InstInfoPtr -> CInstructionInfo #}+cInstructionOperands :: InstInfoPtr -> IO [ValuePtr]+cInstructionOperands i =+ peekArray i {#get CInstructionInfo->operands#} {#get CInstructionInfo->numOperands#}+cInstructionArithFlags :: InstInfoPtr -> IO ArithFlags+cInstructionArithFlags o = toEnum . fromIntegral <$> {#get CInstructionInfo->flags#} o+cInstructionAlign :: InstInfoPtr -> IO Int64+cInstructionAlign u = fromIntegral <$> {#get CInstructionInfo->align#} u+cInstructionIsVolatile :: InstInfoPtr -> IO Bool+cInstructionIsVolatile u = toBool <$> {#get CInstructionInfo->isVolatile#} u+cInstructionAddrSpace :: InstInfoPtr -> IO Int+cInstructionAddrSpace u = fromIntegral <$> {#get CInstructionInfo->addrSpace#} u+cInstructionCmpPred :: InstInfoPtr -> IO CmpPredicate+cInstructionCmpPred c = toEnum . fromIntegral <$> {#get CInstructionInfo->cmpPred#} c+cInstructionInBounds :: InstInfoPtr -> IO Bool+cInstructionInBounds g = toBool <$> {#get CInstructionInfo->inBounds#} g+cInstructionIndices :: InstInfoPtr -> IO [Int]+cInstructionIndices i =+ peekArray i {#get CInstructionInfo->indices#} {#get CInstructionInfo->numIndices#}++data CConstExprInfo+{#pointer *CConstExprInfo as ConstExprPtr -> CConstExprInfo #}+cConstExprTag :: ConstExprPtr -> IO ValueTag+cConstExprTag e = toEnum . fromIntegral <$> {#get CConstExprInfo->instrType#} e+cConstExprInstInfo :: ConstExprPtr -> IO InstInfoPtr+cConstExprInstInfo = {#get CConstExprInfo->ii#}++data CPHIInfo+{#pointer *CPHIInfo as PHIInfoPtr -> CPHIInfo #}+cPHIValues :: PHIInfoPtr -> IO [ValuePtr]+cPHIValues p =+ peekArray p {#get CPHIInfo->incomingValues#} {#get CPHIInfo->numIncomingValues#}+cPHIBlocks :: PHIInfoPtr -> IO [ValuePtr]+cPHIBlocks p =+ peekArray p {#get CPHIInfo->valueBlocks#} {#get CPHIInfo->numIncomingValues#}++data CCallInfo+{#pointer *CCallInfo as CallInfoPtr -> CCallInfo #}+cCallValue :: CallInfoPtr -> IO ValuePtr+cCallValue = {#get CCallInfo->calledValue #}+cCallArguments :: CallInfoPtr -> IO [ValuePtr]+cCallArguments c =+ peekArray c {#get CCallInfo->arguments#} {#get CCallInfo->argListLen#}+cCallConvention :: CallInfoPtr -> IO CallingConvention+cCallConvention c = toEnum . fromIntegral <$> {#get CCallInfo->callingConvention#} c+cCallHasSRet :: CallInfoPtr -> IO Bool+cCallHasSRet c = toBool <$> {#get CCallInfo->hasSRet#} c+cCallIsTail :: CallInfoPtr -> IO Bool+cCallIsTail c = toBool <$> {#get CCallInfo->isTail#} c+cCallUnwindDest :: CallInfoPtr -> IO ValuePtr+cCallUnwindDest = {#get CCallInfo->unwindDest#}+cCallNormalDest :: CallInfoPtr -> IO ValuePtr+cCallNormalDest = {#get CCallInfo->normalDest#}++data CAtomicInfo+{#pointer *CAtomicInfo as AtomicInfoPtr -> CAtomicInfo #}+cAtomicOrdering :: AtomicInfoPtr -> IO AtomicOrdering+cAtomicOrdering ai = toEnum . fromIntegral <$> {#get CAtomicInfo->ordering#} ai+cAtomicScope :: AtomicInfoPtr -> IO SynchronizationScope+cAtomicScope ai = toEnum . fromIntegral <$> {#get CAtomicInfo->scope#} ai+cAtomicOperation :: AtomicInfoPtr -> IO AtomicOperation+cAtomicOperation ai = toEnum . fromIntegral <$> {#get CAtomicInfo->operation#} ai+cAtomicIsVolatile :: AtomicInfoPtr -> IO Bool+cAtomicIsVolatile ai = toBool <$> {#get CAtomicInfo->isVolatile#} ai+cAtomicAddressSpace :: AtomicInfoPtr -> IO Int+cAtomicAddressSpace ai = fromIntegral <$> {#get CAtomicInfo->addrSpace#} ai+cAtomicPointerOperand :: AtomicInfoPtr -> IO ValuePtr+cAtomicPointerOperand = {#get CAtomicInfo->pointerOperand#}+cAtomicValueOperand :: AtomicInfoPtr -> IO ValuePtr+cAtomicValueOperand = {#get CAtomicInfo->valueOperand#}+cAtomicCompareOperand :: AtomicInfoPtr -> IO ValuePtr+cAtomicCompareOperand = {#get CAtomicInfo->compareOperand#}++data CLandingPadInfo+{#pointer *CLandingPadInfo as LandingPadInfoPtr -> CLandingPadInfo#}+cLandingPadPersonality :: LandingPadInfoPtr -> IO ValuePtr+cLandingPadPersonality = {#get CLandingPadInfo->personality#}+cLandingPadIsCleanup :: LandingPadInfoPtr -> IO Bool+cLandingPadIsCleanup li = toBool <$> {#get CLandingPadInfo->isCleanup#} li+cLandingPadClauses :: LandingPadInfoPtr -> IO [ValuePtr]+cLandingPadClauses li =+ peekArray li {#get CLandingPadInfo->clauses #} {#get CLandingPadInfo->numClauses#}+cLandingPadClauseTypes :: LandingPadInfoPtr -> IO [LandingPadClause]+cLandingPadClauseTypes li = do+ arr <- peekArray li {#get CLandingPadInfo->clauseTypes #} {#get CLandingPadInfo->numClauses#}+ return $ map toEnum arr++-- | Parse the named file into an FFI-friendly representation of an+-- LLVM module.+{#fun marshalLLVM { id `Ptr CChar', `Int', fromBool `Bool' } -> `ModulePtr' id #}+{#fun marshalLLVMFile { `String', fromBool `Bool' } -> `ModulePtr' id #}++-- | Free all of the resources allocated by 'marshalLLVM'+{#fun disposeCModule { id `ModulePtr' } -> `()' #}++-- Helpers++-- This only seems to be necessary on i386 for some reason.+cIntConv :: (Integral a, Num b) => a -> b+cIntConv = fromIntegral
+ src/LLVM/Internal/TypeUnification.hs view
@@ -0,0 +1,416 @@+{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}+{-# LANGUAGE FlexibleContexts, TemplateHaskell #-}+-- | This module defines a function to perform unification of LLVM types.+--+-- The unification step is intended to eliminate duplicate struct+-- definitions wherever possible. Duplicate structs have .NNN+-- suffixes after their names and are constructed by the linker when+-- it cannot prove that types are equivalent.+--+-- In theory, llvm-link should do this (and it does try). However,+-- the implementation in llvm-link is poor and gives up on even+-- trivial cases. This implementation is a bit more robust and+-- sensitive to some frontend quirks.+--+-- This is a low-level implementation that is run at IR translation+-- time. The result of 'unifyTypes' is a map from CType pointers to+-- Type objects. This map can be used at IR construction time to map each+-- C type to a canonical high-level representation if at all possible.+--+-- * Opaque types are eliminated if there is a core of unifiable+-- definitions of types with the same name+--+-- * A canonical representative is chosen for each base type name+--+-- Moving this analysis to very early in the translation process has+-- two major benefits: 1) all higher-level analyses can do type-level+-- comparisons without ad-hoc normalization steps, and 2) the knot+-- tying process in the IR translation is simpler because types are+-- already fully resolved.+--+-- TODO: This could be made more configurable for more aggressive+-- unification (e.g., in the presence of {}* fields - this elimination is not+-- exactly safe)+module LLVM.Internal.TypeUnification (+ unifyTypes+ ) where++import Control.Applicative+import Control.Monad ( filterM, foldM, forM_, forM )+import Control.Monad.Trans.Class+import Control.Monad.Error.Class+import Control.Monad.EitherK+import Control.Unification+import Control.Unification.IntVar+import Data.Foldable ( Foldable )+import Data.Traversable ( Traversable )+import Data.Set ( Set )+import qualified Data.Set as S+import Data.HashMap.Strict ( HashMap )+import qualified Data.HashMap.Strict as HM+import Data.HashTable.IO ( BasicHashTable )+import qualified Data.HashTable.IO as HT+import Data.Map ( Map )+import qualified Data.Map as M+import Data.Maybe ( fromMaybe )+import Data.Monoid+import qualified Data.Text as T+import Data.Word ( Word64 )+import Debug.Trace.LocationTH+import Foreign.Ptr+import System.IO.Unsafe ( unsafePerformIO )++import Data.LLVM.Types+import LLVM.Internal.Interop++-- This is adapted from one of the tests in unification-fd++-- | A type of Type terms+data T a = T String [a]+ deriving (Show, Eq, Ord, Functor, Foldable, Traversable)++instance Unifiable T where+ zipMatch (T a xs) (T b ys) =+ case a == b of+ True ->+ case pair xs ys of+ Nothing -> Nothing+ Just p -> Just (T a (map Right p))+ False -> Nothing++type TTerm = UTerm T IntVar++-- | Build a term from a name and a list of term arguments.+typeTerm :: String -> [TTerm] -> TTerm+typeTerm = (UTerm .) . T++unifyTypes :: [TypePtr] -> IO (BasicHashTable Word64 Type, Map Type Int)+unifyTypes tptrs = do+ tmap <- HT.new+ smap <- HT.new++ -- Translate all non-struct types directly into the hash table. The+ -- fold only accumulates struct types (including unions and classes) into+ -- a HashMap from name to ptr.+ --+ -- This accumulated map is the one that will be unified over.+ structsByName <- foldM (translateAndGroup tmap smap) mempty tptrs++ -- Now, for each name in structsByName, attempt to unify all of the+ -- types in the group. For each type that does unify, make an entry+ -- in tmap for its pointer to the single representative Type. For+ -- the rest, do a basic translation.+ mapM_ (unifyStructTypes tmap smap) (HM.toList structsByName)++ typeSizes <- HT.foldM (htToMap tmap) mempty smap++ return (tmap, typeSizes)++htToMap :: BasicHashTable Word64 Type+ -> Map Type Int+ -> (Word64, Int)+ -> IO (Map Type Int)+htToMap tmap a (ip, v) = do+ Just t <- HT.lookup tmap ip+ return $ M.insert t v a++unifyStructTypes :: BasicHashTable Word64 Type+ -> BasicHashTable Word64 Int+ -> (String, [(TypePtr, Int)])+ -> IO ()+unifyStructTypes tmap smap (name, allPtrs) = do+ sizedPtrs <- filterM (isNotOpaque . fst) allPtrs+ let ptrs = map fst sizedPtrs+ -- All of the types reachable from the list of input types @ptrs@+ retainedTypes <- retainedTypeSearch ptrs++ -- The struct types that are reachable from the input types, grouped+ -- by their base names.+ namedStructs <- filterM isStruct (S.toList retainedTypes)+ let dependencyTypes = filter (`notElem` ptrs) namedStructs+ groupedDependencyTypes <- groupByBaseName dependencyTypes++ (unifyResult, _) <- runIntBindingT $ do+ -- Assign a logic variable to each struct type reachable from+ -- the input types (including the input types)+ varMap <- assignVars (HM.insert name ptrs groupedDependencyTypes)+ -- Convert everything to terms, then start unifying groups.+ -- The final unification gives us the answer we want.+ primaryTerms <- mapM (toTerm varMap) ptrs+ let dterms = map snd $ HM.toList groupedDependencyTypes+ depTermGroups <- forM dterms $ \dptrs -> do+ -- If a dependency is opaque, don't bother trying to unify it+ -- since it won't have the right arity.+ nonOpaqueDeps <- lift $ filterM isNotOpaque dptrs+ dts <- mapM (toTerm varMap) nonOpaqueDeps+ return dts+ runEitherKT $ do+ mapM_ unifies depTermGroups+ unifies primaryTerms+ case unifyResult of+ Left _ ->+ -- Make an entry in tmap for each input+ forM_ allPtrs $ \(p, sz) -> do+ Just name' <- cTypeName p+ isPacked <- cTypeIsPacked p+ mptrs <- cTypeList p+ let t = TypeStruct (Right (T.pack name')) (map (delayedLookup tmap) mptrs) isPacked+ ip = fromIntegral (ptrToIntPtr p)+ HT.insert tmap ip t+ HT.insert smap ip sz+ Right _ ->+ case sizedPtrs of+ [] -> do+ -- Make a single opaque entry for allPtrs+ let t = TypeStruct (Right (T.pack name)) [] False+ forM_ allPtrs $ \(p, sz) -> do+ let ip = fromIntegral (ptrToIntPtr p)+ HT.insert tmap ip t+ HT.insert smap ip sz+ (p0, _) : _ -> do+ -- Make one type to represent all of these types that were unified+ -- and use it as the entry for each of the input pointers.+ mptrs <- cTypeList p0+ isPacked <- cTypeIsPacked p0+ let t = TypeStruct (Right (T.pack name)) (map (delayedLookup tmap) mptrs) isPacked+ forM_ allPtrs $ \(p, sz) -> do+ let ip = fromIntegral (ptrToIntPtr p)+ HT.insert tmap ip t+ HT.insert smap ip sz++translateAndGroup :: BasicHashTable Word64 Type+ -> BasicHashTable Word64 Int+ -> HashMap String [(TypePtr, Int)]+ -> TypePtr+ -> IO (HashMap String [(TypePtr, Int)])+translateAndGroup tmap sizeMap structs tptr = do+ let ip = fromIntegral $ ptrToIntPtr tptr+ tag <- cTypeTag tptr+ byteSize <- cTypeSizeInBytes tptr+ HT.insert sizeMap ip byteSize+ case tag of+ TYPE_STRUCT -> do+ name <- cTypeName tptr+ case name of+ Just n -> return $ HM.insertWith (++) (structBaseName n) [(tptr, byteSize)] structs+ -- Anonymous struct+ Nothing -> do+ isPacked <- cTypeIsPacked tptr+ ptrs <- cTypeList tptr+ let ts = map (delayedLookup tmap) ptrs+ stype = TypeStruct (Left ip) ts isPacked+ HT.insert tmap ip stype+ return structs+ _ -> do+ t' <- case tag of+ TYPE_VOID -> return TypeVoid+ TYPE_FLOAT -> return TypeFloat+ TYPE_DOUBLE -> return TypeDouble+ TYPE_X86_FP80 -> return TypeX86FP80+ TYPE_FP128 -> return TypeFP128+ TYPE_PPC_FP128 -> return TypePPCFP128+ TYPE_LABEL -> return TypeLabel+ TYPE_METADATA -> return TypeMetadata+ TYPE_X86_MMX -> return TypeX86MMX+ TYPE_INTEGER -> do+ sz <- cTypeSize tptr+ return $ TypeInteger sz+ TYPE_FUNCTION -> do+ isVa <- cTypeIsVarArg tptr+ rtp <- cTypeInner tptr+ argTypePtrs <- cTypeList tptr++ let rt = delayedLookup tmap rtp+ argTs = map (delayedLookup tmap) argTypePtrs+ return $ TypeFunction rt argTs isVa+ TYPE_ARRAY -> do+ sz <- cTypeSize tptr+ itp <- cTypeInner tptr+ let innerType = delayedLookup tmap itp+ return $ TypeArray sz innerType+ TYPE_VECTOR -> do+ sz <- cTypeSize tptr+ itp <- cTypeInner tptr+ let innerType = delayedLookup tmap itp+ return $ TypeVector sz innerType+ TYPE_POINTER -> do+ itp <- cTypeInner tptr+ addrSpc <- cTypeAddrSpace tptr+ let innerType = delayedLookup tmap itp+ return $ TypePointer innerType addrSpc+ TYPE_STRUCT -> $failure "Impossible, cannot have a struct here"+ HT.insert tmap ip t'+ return structs++-- | Look up the Type associated with a TypePtr lazily and impurely.+-- This relies on no entries in the hash table being inspected until+-- everything is unified and all entries are made.+--+-- This is simpler, faster, and more space efficient than using real+-- knot tying. It is also safe here since there are never any lookups+-- in the hash table in this algorithm - only the IR translator+-- actually performs lookups.+delayedLookup :: BasicHashTable Word64 Type -> TypePtr -> Type+delayedLookup tmap ptr = unsafePerformIO $ do+ res <- HT.lookup tmap $ fromIntegral (ptrToIntPtr ptr)+ return $ fromMaybe errMsg res+ where+ errMsg = $failure ("Type lookup failure for " ++ show ptr)++-- | Perform a breadth-first search to discover all types referenced+-- by the given input type list+retainedTypeSearch :: [TypePtr] -> IO (Set TypePtr)+retainedTypeSearch = go mempty . S.fromList+ where+ go visited q = do+ let vals = q `S.difference` visited+ case S.null vals of+ True -> return visited+ False -> do+ let visited' = visited `S.union` vals+ q' <- foldM addValuesFrom mempty (S.toList vals)+ go visited' q'++ addValuesFrom q tp = do+ tag <- cTypeTag tp+ case tag of+ TYPE_STRUCT -> do+ ptrs <- cTypeList tp+ return $ q `S.union` S.fromList ptrs+ TYPE_FUNCTION -> do+ rtp <- cTypeInner tp+ atps <- cTypeList tp+ return $ q `S.union` S.fromList (rtp : atps)+ TYPE_ARRAY -> do+ itp <- cTypeInner tp+ return $ S.insert itp q+ TYPE_VECTOR -> do+ itp <- cTypeInner tp+ return $ S.insert itp q+ TYPE_POINTER -> do+ itp <- cTypeInner tp+ return $ S.insert itp q+ _ -> return $ S.insert tp q++-- | Top level term creator; this only works for named structs.+toTerm :: Map TypePtr TTerm -> TypePtr -> IntBindingT T IO TTerm+toTerm varMap tp = do+ let Just svar = M.lookup tp varMap+ Just name <- lift $ cTypeName tp+ ptrs <- lift $ cTypeList tp+ innerTerms <- mapM (toTerm' varMap) ptrs+ return $ typeTerm (structBaseName name) (svar : innerTerms)++-- | Inner term creator; for structs, just return the variable+-- assigned to that Type.+toTerm' :: Map TypePtr TTerm -> TypePtr -> IntBindingT T IO TTerm+toTerm' varMap tp = do+ tag <- lift $ cTypeTag tp+ case tag of+ TYPE_VOID -> return $ typeTerm "%primitive.void" []+ TYPE_FLOAT -> return $ typeTerm "%primitive.float" []+ TYPE_DOUBLE -> return $ typeTerm "%primtive.double" []+ TYPE_X86_FP80 -> return $ typeTerm "%primitive.x86_fp80" []+ TYPE_FP128 -> return $ typeTerm "%primitive.fp128" []+ TYPE_PPC_FP128 -> return $ typeTerm "%primitive.ppc_fp128" []+ TYPE_LABEL -> return $ typeTerm "%primitive.label" []+ TYPE_METADATA -> return $ typeTerm "%primitive.metadata" []+ TYPE_X86_MMX -> return $ typeTerm "%primitive.x86_mmx" []+ TYPE_INTEGER -> do+ sz <- lift $ cTypeSize tp+ return $ typeTerm ("%primitive.i" ++ show sz) []+ TYPE_FUNCTION -> do+ rtp <- lift $ cTypeInner tp+ atps <- lift $ cTypeList tp+ innerTerms <- mapM (toTerm' varMap) (rtp : atps)+ return $ typeTerm "%primitive.function" innerTerms+ TYPE_ARRAY -> do+ sz <- lift $ cTypeSize tp+ itp <- lift $ cTypeInner tp+ ity <- toTerm' varMap itp+ return $ typeTerm ("%primitive.array." ++ show sz) [ity]+ TYPE_VECTOR -> do+ sz <- lift $ cTypeSize tp+ itp <- lift $ cTypeInner tp+ ity <- toTerm' varMap itp+ return $ typeTerm ("%primitive.vector." ++ show sz) [ity]+ TYPE_POINTER -> do+ -- If the struct is an opaque literal ptr {}*, assign it a fresh+ -- variable (we will allow such an opaque ref to be anything+ -- since the frontend seems to put them in strange places).+ itp <- lift $ cTypeInner tp+ innerTag <- lift $ cTypeTag itp+ case innerTag of+ TYPE_STRUCT -> do+ mptrs <- lift $ cTypeList itp+ case null mptrs of+ True -> UVar <$> freeVar+ False -> do+ ity <- toTerm' varMap itp+ return $ typeTerm "*" [ity]+ _ -> do+ ity <- toTerm' varMap itp+ return $ typeTerm "*" [ity]+ TYPE_STRUCT ->+ case M.lookup tp varMap of+ Nothing -> do+ mptrs <- lift $ cTypeList tp+ innerTerms <- mapM (toTerm' varMap) mptrs+ return $ typeTerm "%anon.struct" innerTerms+ Just v -> return v++-- | Assign fresh unification variables to every struct type in the+-- input map.+assignVars :: HashMap String [TypePtr] -> IntBindingT T IO (Map TypePtr TTerm)+assignVars = foldM assignVarL mempty . HM.toList+ where+ assignVarL acc (_, ts) = foldM assignVar acc ts+ assignVar acc ty = do+ x <- freeVar+ return $! M.insert ty (UVar x) acc++-- | Take a list of types and group them by their base names (that is,+-- the part of the name up to the trailing .NNN).+groupByBaseName :: [TypePtr] -> IO (HashMap String [TypePtr])+groupByBaseName = foldM addToMap mempty+ where+ addToMap m tp = do+ -- All struct types that make it here are named.+ Just name <- cTypeName tp+ return $ HM.insertWith (++) (structBaseName name) [tp] m++-- | Unify a list of terms+unifies :: (Functor (e m), BindingMonad t v m, MonadTrans e, MonadError (UnificationFailure t v) (e m))+ => [UTerm t v] -> e m ()+unifies [] = return ()+unifies [_] = return ()+unifies (y:ys) = go ys y+ where+ go [] _ = return ()+ go (x:xs) z = unify x z >>= go xs++-- Helpers++-- | Like zip, but only returns a result if the two input lists are+-- the same length+pair :: [a] -> [b] -> Maybe [(a, b)]+pair xs ys =+ case length xs == length ys of+ False -> Nothing+ True -> Just (zip xs ys)++isStruct :: TypePtr -> IO Bool+isStruct tp = do+ tag <- cTypeTag tp+ case tag of+ TYPE_STRUCT -> do+ n <- cTypeName tp+ case n of+ Nothing -> return False+ Just _ -> return True+ _ -> return False++isNotOpaque :: TypePtr -> IO Bool+isNotOpaque tp = do+ ptrs <- cTypeList tp+ return (not (null ptrs))
+ src/LLVM/Parse.hs view
@@ -0,0 +1,1862 @@+-- | This module converts the C form of the LLVM IR into a fully+-- referential Haskell version of the IR. The translation is slightly+-- lossy around integral types in some cases, as Haskell Ints do not+-- have the same range as C ints. In the vast majority of cases this+-- should not really be an issue, but it is possible to lose+-- information. If it is an issue it can be changed.+--+-- Note that this uses BasicHashTables as mappings. Switching to+-- LinearHashTable has less space overhead but makes performance tank.+-- Don't be tempted.+{-# LANGUAGE DeriveDataTypeable, RankNTypes, FlexibleInstances #-}+{-# LANGUAGE TemplateHaskell #-}+module LLVM.Parse (+ -- * Types+ ParserOptions(..),+ PositionPrecision(..),+ TranslationException(..),+ -- * Helpers+ defaultParserOptions,+ -- * Parser+ parseLLVM,+ hParseLLVM,+ parseLLVMFile+ ) where++import Control.Applicative+import Control.DeepSeq+import Control.Exception as E+import Control.Monad.State.Strict+import Data.ByteString.Char8 ( ByteString )+import qualified Data.ByteString.Char8 as BS+import Data.ByteString.Unsafe ( unsafeUseAsCStringLen )+import Data.IORef+import Data.HashTable.IO ( BasicHashTable )+import Data.Set ( Set )+import qualified Data.HashTable.IO as HT+import qualified Data.Set as S+import Data.Maybe ( catMaybes )+import Data.Map ( Map )+import qualified Data.Map as M+import Data.Monoid+import Data.Text ( Text )+import Data.Typeable+import qualified Data.Vector as V+import Data.Word ( Word64 )+import Debug.Trace.LocationTH+import Foreign.Ptr+import System.IO ( Handle, hSetBinaryMode )+import System.IO.Unsafe ( unsafePerformIO )++import Data.LLVM.Types+import LLVM.Internal.Interop+import LLVM.Internal.TypeUnification++-- | Defines the level of precision of position information in the+-- metadata. LLVM gives very precise information, but tracking all of+-- it can consume excessive amounts of space. This option allows it+-- to be selectively discarded.+data PositionPrecision = PositionPrecise+ -- ^ Preserve all information from LLVM (line+ -- and column numbers)+ | PositionNone+ -- ^ Discard all position information+ deriving (Show, Eq)++-- | Options controlling how 'Module's are constructed.+data ParserOptions = ParserOptions { metaPositionPrecision :: PositionPrecision }+ deriving (Show, Eq)++-- | Reasonable default parsing options+defaultParserOptions :: ParserOptions+defaultParserOptions = ParserOptions { metaPositionPrecision = PositionPrecise }++data TranslationException = TooManyReturnValues+ | InvalidBranchInst+ | InvalidSwitchLayout+ | InvalidIndirectBranchOperands+ | KnotTyingFailure ValueTag+ | TypeKnotTyingFailure TypeTag+ | MetaKnotFailure+ | InvalidSelectArgs !Int+ | InvalidExtractElementInst !Int+ | InvalidInsertElementInst !Int+ | InvalidShuffleVectorInst !Int+ | InvalidFunctionInTranslateValue+ | InvalidAliasInTranslateValue+ | InvalidGlobalVarInTranslateValue+ | InvalidBinaryOp !Int+ | InvalidUnaryOp !Int+ | InvalidGEPInst !Int+ | InvalidExtractValueInst !Int+ | InvalidInsertValueInst !Int+ | InvalidTag String ValueTag+ | InvalidBlockAddressFunction Value+ | InvalidBlockAddressBlock Value+ | InvalidUnconditionalBranchTarget Value+ | NonConstantTag ValueTag+ | NonInstructionTag ValueTag+ | InvalidBranchTarget Value+ | InvalidSwitchTarget Value+ | InvalidResumeInst !Int+ | InvalidDataLayout Text String+ | UnparsableBitcode String+ | NoModule+ deriving (Show, Typeable)+instance Exception TranslationException++type KnotMonad = StateT KnotState IO+data KnotState = KnotState { valueMap :: BasicHashTable Word64 Value+ , typeMap :: BasicHashTable Word64 Type+ , metaMap :: BasicHashTable Word64 Metadata+ , idSrc :: IORef Int+ , metaIdSrc :: IORef Int+ , result :: Maybe Module+ , visitedMetadata :: Set IntPtr+ , localId :: Int+ , stringCache :: BasicHashTable Text Text+ , identCache :: BasicHashTable Identifier Identifier+ }++instance InternString (StateT KnotState IO) where+ internString str = do+ s <- get+ let cache = stringCache s+ v <- liftIO $ HT.lookup cache str+ case v of+ Just cval -> return cval+ Nothing -> do+ liftIO $ HT.insert cache str str+ return str+ internIdentifier ident = do+ s <- get+ let cache = identCache s+ v <- liftIO $ HT.lookup cache ident+ case v of+ Just val -> return val+ Nothing -> do+ liftIO $ HT.insert cache ident ident+ return ident+++emptyState :: IORef Int+ -> IORef Int+ -> BasicHashTable Word64 Value+ -> BasicHashTable Word64 Metadata+ -> BasicHashTable Word64 Type+ -> BasicHashTable Text Text+ -> BasicHashTable Identifier Identifier+ -> KnotState+emptyState r1 r2 vm mm tm sc ic =+ KnotState { valueMap = vm+ , typeMap = tm+ , metaMap = mm+ , idSrc = r1+ , metaIdSrc = r2+ , result = Nothing+ , visitedMetadata = mempty+ , localId = 0+ , stringCache = sc+ , identCache = ic+ }++genId :: (KnotState -> IORef Int) -> KnotMonad Int+genId accessor = do+ s <- get+ let r = accessor s+ thisId <- liftIO $ readIORef r+ let nid = thisId + 1+ nid `seq` return ()+ liftIO $ writeIORef r nid++ return thisId++nextId :: KnotMonad Int+nextId = genId idSrc++nextMetaId :: KnotMonad Int+nextMetaId = genId metaIdSrc++-- | Parse the named LLVM file into the LLVM form of the IR (a+-- 'Module'). In the case of an error, a descriptive string will be+-- returned. The input file can be either LLVM assembly or bitcode.+parseLLVMFile :: ParserOptions -> FilePath -> IO Module+parseLLVMFile opts filename = do+ let includeLineNumbers = metaPositionPrecision opts == PositionPrecise+ m <- marshalLLVMFile filename includeLineNumbers++ hasError <- cModuleHasError m+ case hasError of+ True -> do+ Just errMsg <- cModuleErrorMessage m+ disposeCModule m+ E.throwIO $ UnparsableBitcode errMsg+ False -> translateCModule m++-- | Parse LLVM IR from a Handle into a 'Module'+hParseLLVM :: ParserOptions -> Handle -> IO Module+hParseLLVM opts h = do+ hSetBinaryMode h True+ bs <- BS.hGetContents h+ parseLLVM opts bs++-- | Parse the LLVM IR (either assembly or bitcode) from a lazy ByteString+-- into a 'Module'.+parseLLVM :: ParserOptions -> ByteString -> IO Module+parseLLVM opts content = do+ let includeLineNumbers = metaPositionPrecision opts == PositionPrecise+ unsafeUseAsCStringLen content $ \(s, len) -> do+ m <- marshalLLVM s len includeLineNumbers+ hasError <- cModuleHasError m+ case hasError of+ True -> do+ Just errMsg <- cModuleErrorMessage m+ disposeCModule m+ E.throwIO $ UnparsableBitcode errMsg+ False -> translateCModule m++translateCModule :: ModulePtr -> IO Module+translateCModule m = do+ idref <- newIORef 1+ mref <- newIORef 1++ -- Default these tables to be slightly large to reduce resizing+ valMap <- HT.newSized 2000+ mmMap <- HT.newSized 2000+ sCache <- HT.newSized 2000+ iCache <- HT.newSized 2000++ -- Do a preliminary pass over all of the types in the Module. This+ -- pass will unify structurally identical types (and basically+ -- ignore opaque types). This step should happen in llvm-link, but+ -- that seems to miss many trivial cases.+ --+ -- The result of the unification step will be a map of CType -> Type+ -- to be used in the IR translation.+ --+ -- Note that this up-front type translation will make the IR+ -- translation simpler since there will be no type knot. This also+ -- means that+ modTypes <- cModuleTypes m+ (tyMap, typeSizes) <- unifyTypes modTypes++ let s0 = emptyState idref mref valMap mmMap tyMap sCache iCache+ res <- evalStateT (mfix (tieKnot m typeSizes)) s0+ disposeCModule m+ case result res of+ Just r -> do+ r `deepseq` return ()+ return r+ Nothing -> E.throwIO $ NoModule++isExternVar :: ValuePtr -> KnotMonad Bool+isExternVar vp = do+ dataPtr <- liftIO $ cValueData vp+ let dataPtr' = castPtr dataPtr+ liftIO $ cGlobalIsExternal dataPtr'++isExternFunc :: ValuePtr -> KnotMonad Bool+isExternFunc vp = do+ dataPtr <- liftIO $ cValueData vp+ let dataPtr' = castPtr dataPtr+ liftIO $ cFunctionIsExternal dataPtr'++-- swiped from http://www.haskell.org/pipermail/beginners/2009-December/002882.html+partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a],[a])+partitionM p xs = do+ (f,g) <- pMHelper p xs+ return (f [], g [])++pMHelper :: Monad m => (a -> m Bool) -> [a] -> m ([a] -> [a],[a] -> [a])+pMHelper p xs = foldM help (id,id) xs+ where+ help (f,g) x = do+ b <- p x+ return (if b then (f . (x:),g) else (f,g . (x:)))++tieKnot :: ModulePtr -> Map Type Int -> KnotState -> KnotMonad KnotState+tieKnot m typeSizes finalState = do+ modIdent <- liftIO $ cModuleIdentifier m+ dataLayout <- liftIO $ cModuleDataLayout m+ triple <- liftIO $ cModuleTargetTriple m+ inlineAsm <- liftIO $ cModuleInlineAsm m++ vars <- liftIO $ cModuleGlobalVariables m+ aliases <- liftIO $ cModuleGlobalAliases m+ funcs <- liftIO $ cModuleFunctions m+ enumMetaPtrs <- liftIO $ cModuleEnumMetadata m+ retainedMetaPtrs <- liftIO $ cModuleRetainedTypeMetadata m++ (externVs, globalVs) <- partitionM isExternVar vars+ (externFs, globalFs) <- partitionM isExternFunc funcs++ globalVars <- mapM (translateGlobalVariable finalState) globalVs+ externVars <- mapM (translateExternalVariable finalState) externVs+ globalAliases <- mapM (translateAlias finalState) aliases+ definedFuncs <- mapM (translateFunction finalState) globalFs+ externFuncs <- mapM (translateExternalFunction finalState) externFs++ enumMeta <- mapM (translateMetadata finalState) enumMetaPtrs+ typeMeta <- mapM (translateMetadata finalState) retainedMetaPtrs++ s <- get+ tm <- liftIO $ HT.toList (typeMap s)+ lastId <- liftIO $ readIORef (idSrc s)+ case parseDataLayout dataLayout of+ Left err -> throw (InvalidDataLayout dataLayout err)+ Right dl -> do+ let ir = Module { moduleIdentifier = modIdent+ , moduleDataLayoutString = dataLayout+ , moduleDataLayout = dl+ , moduleTarget = triple+ , moduleAssembly = Assembly inlineAsm+ , moduleAliases = globalAliases+ , moduleGlobalVariables = globalVars+ , moduleDefinedFunctions = definedFuncs+ , moduleExternalValues = externVars+ , moduleExternalFunctions = externFuncs+ , moduleEnumMetadata = enumMeta+ , moduleRetainedTypeMetadata = typeMeta+ , moduleRetainedTypes = unique $ map snd tm+ , moduleNextId = lastId + 1+ , moduleTypeSizes = \t -> M.lookup t typeSizes+ }+ return s { result = Just ir }++unique :: (Ord a) => [a] -> [a]+unique = S.toList . S.fromList++translateType :: TypePtr -> KnotMonad Type+translateType tp = do+ tm <- gets typeMap+ let ip = fromIntegral $ ptrToIntPtr tp+ res <- liftIO $ HT.lookup tm ip+ case res of+ Nothing -> $failure ("No translation for type " ++ show tp)+ Just t -> return t++recordValue :: ValuePtr -> Value -> KnotMonad ()+recordValue vp v = do+ s <- get+ let key = fromIntegral $ ptrToIntPtr vp+ liftIO $ HT.insert (valueMap s) key v++translateAlias :: KnotState -> ValuePtr -> KnotMonad GlobalAlias+translateAlias finalState vp = do+ Just name <- cValueName vp+ dataPtr <- liftIO $ cValueData vp+ metaPtr <- liftIO $ cValueMetadata vp+ let dataPtr' = castPtr dataPtr++ mds <- mapM (translateMetadata finalState) metaPtr++ vis <- liftIO $ cGlobalVisibility dataPtr'+ link <- liftIO $ cGlobalLinkage dataPtr'+ aliasee <- liftIO $ cGlobalAliasee dataPtr'++ ta <- translateConstOrRef finalState aliasee++ uid <- nextId++ let ga = GlobalAlias { globalAliasLinkage = link+ , globalAliasVisibility = vis+ , globalAliasTarget = ta+ , globalAliasName = name+ , globalAliasMetadata = mds+ , globalAliasUniqueId = uid+ }++ recordValue vp (toValue ga)++ return ga++translateExternalVariable :: KnotState -> ValuePtr -> KnotMonad ExternalValue+translateExternalVariable finalState vp = do+ Just name <- cValueName vp+ typePtr <- liftIO $ cValueType vp+ metaPtr <- liftIO $ cValueMetadata vp+ tt <- translateType typePtr++ mds <- mapM (translateMetadata finalState) metaPtr+ uid <- nextId++ let ev = ExternalValue { externalValueType = tt+ , externalValueName = name+ , externalValueMetadata = mds+ , externalValueUniqueId = uid+ }+ recordValue vp (toValue ev)+ return ev+++translateGlobalVariable :: KnotState -> ValuePtr -> KnotMonad GlobalVariable+translateGlobalVariable finalState vp = do+ Just name <- cValueName vp+ typePtr <- liftIO $ cValueType vp+ dataPtr <- liftIO $ cValueData vp+ metaPtr <- liftIO $ cValueMetadata vp+ tt <- translateType typePtr++ mds <- mapM (translateMetadata finalState) metaPtr+ uid <- nextId++ let dataPtr' = castPtr dataPtr+ align <- liftIO $ cGlobalAlignment dataPtr'+ vis <- liftIO $ cGlobalVisibility dataPtr'+ link <- liftIO $ cGlobalLinkage dataPtr'+ section <- liftIO $ cGlobalSection dataPtr'+ isThreadLocal <- liftIO $ cGlobalIsThreadLocal dataPtr'+ initializer <- liftIO $ cGlobalInitializer dataPtr'+ isConst <- liftIO $ cGlobalIsConstant dataPtr'++ ti <- case initializer == nullPtr of+ True -> return Nothing+ False -> do+ tv <- translateConstOrRef finalState initializer+ return $ Just tv++ let gv = GlobalVariable { globalVariableLinkage = link+ , globalVariableVisibility = vis+ , globalVariableInitializer = ti+ , globalVariableAlignment = align+ , globalVariableSection = section+ , globalVariableIsThreadLocal = isThreadLocal+ , globalVariableIsConstant = isConst+ , globalVariableMetadata = mds+ , globalVariableType = tt+ , globalVariableName = name+ , globalVariableUniqueId = uid+ }+ recordValue vp (toValue gv)+ return gv++translateExternalFunction :: KnotState -> ValuePtr -> KnotMonad ExternalFunction+translateExternalFunction finalState vp = do+ Just name <- cValueName vp+ typePtr <- liftIO $ cValueType vp+ metaPtr <- liftIO $ cValueMetadata vp+ tt <- translateType typePtr++ mds <- mapM (translateMetadata finalState) metaPtr++ uid <- nextId++ let ef = ExternalFunction { externalFunctionType = tt+ , externalFunctionName = name+ , externalFunctionMetadata = mds+ , externalFunctionUniqueId = uid+ , externalFunctionAttrs = [] -- FIXME: Need to figure out how to find attrs+ }+ recordValue vp (toValue ef)+ return ef+++resetLocalIdCounter :: KnotMonad ()+resetLocalIdCounter = do+ s <- get+ put s { localId = 0 }++translateFunction :: KnotState -> ValuePtr -> KnotMonad Function+translateFunction finalState vp = do+ Just name <- cValueName vp+ typePtr <- liftIO $ cValueType vp+ dataPtr <- liftIO $ cValueData vp+ metaPtr <- liftIO $ cValueMetadata vp+ tt <- translateType typePtr++ mds <- mapM (translateMetadata finalState) metaPtr++ uid <- nextId++ resetLocalIdCounter++ let dataPtr' = castPtr dataPtr+ align <- liftIO $ cFunctionAlignment dataPtr'+ vis <- liftIO $ cFunctionVisibility dataPtr'+ link <- liftIO $ cFunctionLinkage dataPtr'+ section <- liftIO $ cFunctionSection dataPtr'+ cc <- liftIO $ cFunctionCallingConvention dataPtr'+ gcname <- liftIO $ cFunctionGCName dataPtr'+ args <- liftIO $ cFunctionArguments dataPtr'+ blocks <- liftIO $ cFunctionBlocks dataPtr'++ f <- mfix (\finalF -> do+ args' <- mapM (translateArgument finalState finalF) args+ blocks' <- mapM (translateBasicBlock finalState finalF) blocks+ let f' = Function { functionParameters = args'+ , functionBodyVector = V.fromList blocks'+ , functionLinkage = link+ , functionVisibility = vis+ , functionCC = cc+ , functionRetAttrs = [] -- FIXME+ , functionAttrs = [] -- FIXME+ , functionSection = section+ , functionAlign = align+ , functionGCName = gcname+ , functionType = tt+ , functionName = name+ , functionMetadata = mds+ , functionUniqueId = uid+ }+ return f')++ recordValue vp (toValue f)+ return f++translateConstant :: KnotState -> ValuePtr -> KnotMonad Constant+translateConstant finalState vp = do+ tag <- liftIO $ cValueTag vp+ typePtr <- liftIO $ cValueType vp+ dataPtr <- liftIO $ cValueData vp+ tt <- translateType typePtr++ constant <- case tag of+ ValInlineasm -> translateInlineAsm finalState (castPtr dataPtr) tt+ ValBlockaddress -> translateBlockAddress finalState (castPtr dataPtr) tt+ ValConstantaggregatezero -> do+ uid <- nextId+ return ConstantAggregateZero { constantType = tt+ , constantUniqueId = uid+ }+ ValConstantpointernull -> do+ uid <- nextId+ return ConstantPointerNull { constantType = tt+ , constantUniqueId = uid+ }+ ValUndefvalue -> do+ uid <- nextId+ return UndefValue { constantType = tt+ , constantUniqueId = uid+ }+ ValConstantarray -> translateConstantAggregate finalState ConstantArray (castPtr dataPtr) tt+ ValConstantstruct -> translateConstantAggregate finalState ConstantStruct (castPtr dataPtr) tt+ ValConstantvector -> translateConstantAggregate finalState ConstantVector (castPtr dataPtr) tt+ ValConstantfp -> translateConstantFP finalState (castPtr dataPtr) tt+ ValConstantint -> translateConstantInt finalState (castPtr dataPtr) tt+ ValConstantexpr -> do+ uid <- nextId+ i <- translateConstantExpr finalState (castPtr dataPtr) tt+ return ConstantValue { constantType = tt+ , constantUniqueId = uid+ , constantInstruction = i+ }+ _ -> throw $ NonConstantTag tag++ recordValue vp (toValue constant)++ return constant+++-- | Most instructions don't have explicit names in LLVM - when they+-- are printed the LLVM libraries just generate numeric names and they+-- are never stored. This function takes the stated name of an+-- instruction and, if it should have a temporary name like that, we+-- generate one using a local counter.+computeRealName :: Maybe Identifier -> KnotMonad (Maybe Identifier)+computeRealName name = do+ s <- get+ let idCtr = localId s+ case name of+ Just n -> return (Just n)+ Nothing -> do+ put s { localId = idCtr + 1 }+ let rawAnonId = makeAnonymousLocal idCtr+ anonId <- internIdentifier rawAnonId+ return $! Just anonId++-- | Compute the name of a call or invoke instruction. If the call is+-- void, it does not get a name; otherwise, it does need a+-- sequentially-generated name.+computeNameIfNotVoid :: Maybe Identifier -> Type -> KnotMonad (Maybe Identifier)+computeNameIfNotVoid mid t =+ case t of+ TypeVoid -> return Nothing+ _ -> computeRealName mid++translateInstruction :: KnotState -> Maybe BasicBlock -> ValuePtr -> KnotMonad Instruction+translateInstruction finalState bb vp = do+ tag <- liftIO $ cValueTag vp+ name <- cValueName vp+ typePtr <- liftIO $ cValueType vp+ dataPtr <- liftIO $ cValueData vp+ metaPtr <- liftIO $ cValueMetadata vp+ srcLocPtr <- liftIO $ cValueSrcLoc vp++ metas <- mapM (translateMetadata finalState) metaPtr+ mds <- case srcLocPtr == nullPtr of+ True -> return metas+ False -> do+ srcLoc <- translateMetadata finalState srcLocPtr+ return $ srcLoc : metas++ tt <- translateType typePtr++ inst <- case tag of+ ValRetinst -> translateRetInst finalState (castPtr dataPtr) mds bb+ ValBranchinst -> translateBranchInst finalState (castPtr dataPtr) mds bb+ ValSwitchinst -> translateSwitchInst finalState (castPtr dataPtr) mds bb+ ValIndirectbrinst -> translateIndirectBrInst finalState (castPtr dataPtr) mds bb+ ValUnreachableinst -> do+ uid <- nextId+ return UnreachableInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ }+ ValInvokeinst -> translateInvokeInst finalState (castPtr dataPtr) name tt mds bb+ ValAddinst -> translateFlaggedBinaryOp finalState AddInst (castPtr dataPtr) name tt mds bb+ ValFaddinst -> translateFlaggedBinaryOp finalState AddInst (castPtr dataPtr) name tt mds bb+ ValSubinst -> translateFlaggedBinaryOp finalState SubInst (castPtr dataPtr) name tt mds bb+ ValFsubinst -> translateFlaggedBinaryOp finalState SubInst (castPtr dataPtr) name tt mds bb+ ValMulinst -> translateFlaggedBinaryOp finalState MulInst (castPtr dataPtr) name tt mds bb+ ValFmulinst -> translateFlaggedBinaryOp finalState MulInst (castPtr dataPtr) name tt mds bb+ ValUdivinst -> translateBinaryOp finalState DivInst (castPtr dataPtr) name tt mds bb+ ValSdivinst -> translateBinaryOp finalState DivInst (castPtr dataPtr) name tt mds bb+ ValFdivinst -> translateBinaryOp finalState DivInst (castPtr dataPtr) name tt mds bb+ ValUreminst -> translateBinaryOp finalState RemInst (castPtr dataPtr) name tt mds bb+ ValSreminst -> translateBinaryOp finalState RemInst (castPtr dataPtr) name tt mds bb+ ValFreminst -> translateBinaryOp finalState RemInst (castPtr dataPtr) name tt mds bb+ ValShlinst -> translateBinaryOp finalState ShlInst (castPtr dataPtr) name tt mds bb+ ValLshrinst -> translateBinaryOp finalState LshrInst (castPtr dataPtr) name tt mds bb+ ValAshrinst -> translateBinaryOp finalState AshrInst (castPtr dataPtr) name tt mds bb+ ValAndinst -> translateBinaryOp finalState AndInst (castPtr dataPtr) name tt mds bb+ ValOrinst -> translateBinaryOp finalState OrInst (castPtr dataPtr) name tt mds bb+ ValXorinst -> translateBinaryOp finalState XorInst (castPtr dataPtr) name tt mds bb+ ValAllocainst -> translateAllocaInst finalState (castPtr dataPtr) name tt mds bb+ ValLoadinst -> translateLoadInst finalState (castPtr dataPtr) name tt mds bb+ ValStoreinst -> translateStoreInst finalState (castPtr dataPtr) mds bb+ ValGetelementptrinst -> translateGEPInst finalState (castPtr dataPtr) name tt mds bb+ ValTruncinst -> translateCastInst finalState TruncInst (castPtr dataPtr) name tt mds bb+ ValZextinst -> translateCastInst finalState ZExtInst (castPtr dataPtr) name tt mds bb+ ValSextinst -> translateCastInst finalState SExtInst (castPtr dataPtr) name tt mds bb+ ValFptruncinst -> translateCastInst finalState FPTruncInst (castPtr dataPtr) name tt mds bb+ ValFpextinst -> translateCastInst finalState FPExtInst (castPtr dataPtr) name tt mds bb+ ValFptouiinst -> translateCastInst finalState FPToUIInst (castPtr dataPtr) name tt mds bb+ ValFptosiinst -> translateCastInst finalState FPToSIInst (castPtr dataPtr) name tt mds bb+ ValUitofpinst -> translateCastInst finalState UIToFPInst (castPtr dataPtr) name tt mds bb+ ValSitofpinst -> translateCastInst finalState SIToFPInst (castPtr dataPtr) name tt mds bb+ ValPtrtointinst -> translateCastInst finalState PtrToIntInst (castPtr dataPtr) name tt mds bb+ ValInttoptrinst -> translateCastInst finalState IntToPtrInst (castPtr dataPtr) name tt mds bb+ ValBitcastinst -> translateCastInst finalState BitcastInst (castPtr dataPtr) name tt mds bb+ ValIcmpinst -> translateCmpInst finalState ICmpInst (castPtr dataPtr) name tt mds bb+ ValFcmpinst -> translateCmpInst finalState FCmpInst (castPtr dataPtr) name tt mds bb+ ValPhinode -> translatePhiNode finalState (castPtr dataPtr) name tt mds bb+ ValCallinst -> translateCallInst finalState (castPtr dataPtr) name tt mds bb+ ValSelectinst -> translateSelectInst finalState (castPtr dataPtr) name tt mds bb+ ValVaarginst -> translateVarArgInst finalState (castPtr dataPtr) name tt mds bb+ ValExtractelementinst -> translateExtractElementInst finalState (castPtr dataPtr) name tt mds bb+ ValInsertelementinst -> translateInsertElementInst finalState (castPtr dataPtr) name tt mds bb+ ValShufflevectorinst -> translateShuffleVectorInst finalState (castPtr dataPtr) name tt mds bb+ ValExtractvalueinst -> translateExtractValueInst finalState (castPtr dataPtr) name tt mds bb+ ValInsertvalueinst -> translateInsertValueInst finalState (castPtr dataPtr) name tt mds bb+ ValResumeinst -> translateResumeInst finalState (castPtr dataPtr) mds bb+ ValFenceinst -> translateFenceInst finalState (castPtr dataPtr) mds bb+ ValAtomiccmpxchginst -> translateAtomicCmpXchgInst finalState (castPtr dataPtr) mds bb+ ValAtomicrmwinst -> translateAtomicRMWInst finalState (castPtr dataPtr) mds bb+ ValLandingpadinst -> translateLandingPadInst finalState (castPtr dataPtr) name tt mds bb+ _ -> throw $ NonInstructionTag tag++ recordValue vp (toValue inst)++ return inst++isConstant :: ValueTag -> Bool+isConstant vt = case vt of+ ValConstantaggregatezero -> True+ ValConstantarray -> True+ ValConstantfp -> True+ ValConstantint -> True+ ValConstantpointernull -> True+ ValConstantstruct -> True+ ValConstantvector -> True+ ValUndefvalue -> True+ ValConstantexpr -> True+ ValBlockaddress -> True+ ValInlineasm -> True+ _ -> False++translateConstOrRef :: KnotState -> ValuePtr -> KnotMonad Value+translateConstOrRef finalState vp = do+ s <- get+ let key = fromIntegral (ptrToIntPtr vp)+ existingVal <- liftIO $ HT.lookup (valueMap s) key+ case existingVal of+ Just v -> return v+ Nothing -> do+ tag <- liftIO $ cValueTag vp+ case isConstant tag of+ -- translateConstant handles making the hash table entry for+ -- this pointer+ True -> toValue <$> translateConstant finalState vp+ False -> do+ -- This cheats in the knot tying. The map is read again+ -- /after/ it has been filled in (since these values are not+ -- forced until after the whole module is processed)+ let finalRes = unsafePerformIO $ HT.lookup (valueMap s) key+ return (maybe (throw (KnotTyingFailure tag)) id finalRes)++translateArgument :: KnotState -> Function -> ValuePtr -> KnotMonad Argument+translateArgument finalState finalF vp = do+ tag <- liftIO $ cValueTag vp+ Just name <- cValueName vp+ typePtr <- liftIO $ cValueType vp+ dataPtr <- liftIO $ cValueData vp+ metaPtr <- liftIO $ cValueMetadata vp++ mds <- mapM (translateMetadata finalState) metaPtr+ uid <- nextId++ when (tag /= ValArgument) (throw $ InvalidTag "Argument" tag)++ tt <- translateType typePtr++ let dataPtr' = castPtr dataPtr++ hasSRet <- liftIO $ cArgInfoHasSRet dataPtr'+ hasByVal <- liftIO $ cArgInfoHasByVal dataPtr'+ hasNest <- liftIO $ cArgInfoHasNest dataPtr'+ hasNoAlias <- liftIO $ cArgInfoHasNoAlias dataPtr'+ hasNoCapture <- liftIO $ cArgInfoHasNoCapture dataPtr'+ let attrOrNothing b att = if b then Just att else Nothing+ atts = [ attrOrNothing hasSRet PASRet+ , attrOrNothing hasByVal PAByVal+ , attrOrNothing hasNest PANest+ , attrOrNothing hasNoAlias PANoAlias+ , attrOrNothing hasNoCapture PANoCapture+ ]+ let a = Argument { argumentType = tt+ , argumentName = name+ , argumentMetadata = mds+ , argumentUniqueId = uid+ , argumentParamAttrs = catMaybes atts+ , argumentFunction = finalF+ }+ recordValue vp (toValue a)+ return a+++translateBasicBlock :: KnotState -> Function -> ValuePtr -> KnotMonad BasicBlock+translateBasicBlock finalState f vp = do+ tag <- liftIO $ cValueTag vp+ name <- cValueName vp+ dataPtr <- liftIO $ cValueData vp+ metaPtr <- liftIO $ cValueMetadata vp++ mds <- mapM (translateMetadata finalState) metaPtr++ when (tag /= ValBasicblock) (throw $ InvalidTag "BasicBlock" tag)+++ uid <- nextId++ let dataPtr' = castPtr dataPtr+ Just realName <- computeRealName name++ insts <- liftIO $ cBasicBlockInstructions dataPtr'+ -- Use mfix here to let instructions have a reference to their+ -- enclosing basic block. mfix is needed since the block doesn't+ -- exist until after the instructions are translated+ bb <- mfix (\finalBB -> do+ tinsts <- mapM (translateInstruction finalState (Just finalBB)) insts+ let block' = BasicBlock { basicBlockName = realName+ , basicBlockMetadata = mds+ , basicBlockUniqueId = uid+ , basicBlockInstructionVector = V.fromList tinsts+ , basicBlockFunction = f+ }+ return block')++ recordValue vp (toValue bb)+ return bb++translateInlineAsm :: KnotState -> InlineAsmInfoPtr -> Type -> KnotMonad Constant+translateInlineAsm _ dataPtr tt = do+ uid <- nextId+ asmString <- liftIO $ cInlineAsmString dataPtr+ constraints <- liftIO $ cInlineAsmConstraints dataPtr+ return InlineAsm { constantType = tt+ , constantUniqueId = uid+ , inlineAsmString = asmString+ , inlineAsmConstraints = constraints+ }++translateBlockAddress :: KnotState -> BlockAddrInfoPtr -> Type -> KnotMonad Constant+translateBlockAddress finalState dataPtr tt = do+ uid <- nextId+ fval <- liftIO $ cBlockAddrFunc dataPtr+ bval <- liftIO $ cBlockAddrBlock dataPtr+ f' <- translateConstOrRef finalState fval+ b' <- translateConstOrRef finalState bval+ let f'' = case valueContent f' of+ FunctionC f -> f+ _ -> throw (InvalidBlockAddressFunction f')+ b'' = case valueContent b' of+ BasicBlockC b -> b+ _ -> throw (InvalidBlockAddressBlock b')+ return BlockAddress { constantType = tt+ , constantUniqueId = uid+ , blockAddressFunction = f''+ , blockAddressBlock = b''+ }++translateConstantAggregate :: KnotState -> (Type -> UniqueId -> [Value] -> Constant)+ -> AggregateInfoPtr -> Type -> KnotMonad Constant+translateConstantAggregate finalState constructor dataPtr tt = do+ uid <- nextId+ vals <- liftIO $ cAggregateValues dataPtr+ vals' <- mapM (translateConstOrRef finalState) vals+ return $ constructor tt uid vals'++translateConstantFP :: KnotState -> FPInfoPtr -> Type -> KnotMonad Constant+translateConstantFP _ dataPtr tt = do+ uid <- nextId+ fpval <- liftIO $ cFPVal dataPtr+ return ConstantFP { constantType = tt+ , constantUniqueId = uid+ , constantFPValue = fpval+ }++translateConstantInt :: KnotState -> IntInfoPtr -> Type -> KnotMonad Constant+translateConstantInt _ dataPtr tt = do+ uid <- nextId+ hugeVal <- liftIO $ cIntHugeVal dataPtr+ intval <- case hugeVal of+ Nothing -> liftIO $ cIntVal dataPtr+ Just hv -> return hv+ return $ ConstantInt { constantType = tt+ , constantUniqueId = uid+ , constantIntValue = intval+ }++translateRetInst :: KnotState -> InstInfoPtr -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateRetInst finalState dataPtr mds bb = do+ uid <- nextId+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ rv <- case opPtrs of+ [] -> return Nothing+ [val] -> do+ val' <- translateConstOrRef finalState val+ return (Just val')+ _ -> throw TooManyReturnValues+ return RetInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , retInstValue = rv+ }++-- | Note, in LLVM the operands of the Branch instruction are ordered as+--+-- [Condition, FalseTarget,] TrueTarget+--+-- This is not exactly as expected.+translateBranchInst :: KnotState -> InstInfoPtr -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateBranchInst finalState dataPtr mds bb = do+ uid <- nextId+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ case opPtrs of+ [dst] -> do+ dst' <- translateConstOrRef finalState dst+ let dst'' = case valueContent dst' of+ BasicBlockC b -> b+ _ -> throw (InvalidUnconditionalBranchTarget dst')+ return UnconditionalBranchInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , unconditionalBranchTarget = dst''+ }+ [val, f, t] -> do+ val' <- translateConstOrRef finalState val+ fbranch <- translateConstOrRef finalState f+ tbranch <- translateConstOrRef finalState t+ let tbr' = case valueContent tbranch of+ BasicBlockC b -> b+ _ -> throw (InvalidBranchTarget tbranch)+ fbr' = case valueContent fbranch of+ BasicBlockC b -> b+ _ -> throw (InvalidBranchTarget fbranch)+ return BranchInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , branchCondition = val'+ , branchTrueTarget = tbr'+ , branchFalseTarget = fbr'+ }+ _ -> throw InvalidBranchInst++translateSwitchInst :: KnotState -> InstInfoPtr -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateSwitchInst finalState dataPtr mds bb = do+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ case opPtrs of+ (swVal:defTarget:cases) -> do+ val' <- translateConstOrRef finalState swVal+ def' <- translateConstOrRef finalState defTarget+ -- Process the rest of the list in pairs since that is how LLVM+ -- stores them, but transform it into a nice list of actual+ -- pairs+ let tpairs acc (v1:dest:rest) = do+ v1' <- translateConstOrRef finalState v1+ dest' <- translateConstOrRef finalState dest+ let dest'' = case valueContent dest' of+ BasicBlockC b -> b+ _ -> throw (InvalidSwitchTarget dest')+ tpairs ((v1', dest''):acc) rest+ tpairs acc [] = return $ reverse acc+ tpairs _ _ = throw InvalidSwitchLayout+ def'' = case valueContent def' of+ BasicBlockC b -> b+ _ -> throw (InvalidSwitchTarget def')+ cases' <- tpairs [] cases+ uid <- nextId+ return SwitchInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , switchValue = val'+ , switchDefaultTarget = def''+ , switchCases = cases'+ }+ _ -> throw InvalidSwitchLayout++translateIndirectBrInst :: KnotState -> InstInfoPtr -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateIndirectBrInst finalState dataPtr mds bb = do+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ uid <- nextId+ case opPtrs of+ (addr:targets) -> do+ addr' <- translateConstOrRef finalState addr+ targets' <- mapM (translateConstOrRef finalState) targets+ return IndirectBranchInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , indirectBranchAddress = addr'+ , indirectBranchTargets = map toBasicBlock targets'+ }+ _ -> throw InvalidIndirectBranchOperands+ where+ toBasicBlock b = case valueContent b of+ BasicBlockC b' -> b'+ _ -> throw (InvalidBranchTarget b)+++translateInvokeInst :: KnotState -> CallInfoPtr -> Maybe Identifier -> Type+ -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateInvokeInst finalState dataPtr name tt mds bb = do+ n <- computeNameIfNotVoid name tt+ func <- liftIO $ cCallValue dataPtr+ args <- liftIO $ cCallArguments dataPtr+ cc <- liftIO $ cCallConvention dataPtr+ hasSRet <- liftIO $ cCallHasSRet dataPtr+ ndest <- liftIO $ cCallNormalDest dataPtr+ udest <- liftIO $ cCallUnwindDest dataPtr++ f' <- translateConstOrRef finalState func+ args' <- mapM (translateConstOrRef finalState) args+ n' <- translateConstOrRef finalState ndest+ u' <- translateConstOrRef finalState udest++ uid <- nextId++ let n'' = case valueContent n' of+ BasicBlockC b -> b+ _ -> $failure "Expected BasicBlock for normal invoke label"+ u'' = case valueContent u' of+ BasicBlockC b -> b+ _ -> $failure "Expected BasicBlock for unwind invoke label"++ return InvokeInst { _instructionName = n+ , _instructionType = tt+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , invokeConvention = cc+ , invokeParamAttrs = [] -- FIXME+ , invokeFunction = f'+ , invokeArguments = zip args' (repeat []) -- FIXME+ , invokeAttrs = [] -- FIXME+ , invokeNormalLabel = n''+ , invokeUnwindLabel = u''+ , invokeHasSRet = hasSRet+ }++translateFlaggedBinaryOp :: KnotState+ -> (Type -> Maybe Identifier -> [Metadata] -> UniqueId -> Maybe BasicBlock -> ArithFlags -> Value -> Value -> Instruction)+ -> InstInfoPtr -> Maybe Identifier -> Type+ -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateFlaggedBinaryOp finalState constructor dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ flags <- liftIO $ cInstructionArithFlags dataPtr++ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId++ case ops of+ [lhs, rhs] -> return $ constructor tt n mds uid bb flags lhs rhs+ _ -> throw $ InvalidBinaryOp (length ops)++translateBinaryOp :: KnotState+ -> (Type -> Maybe Identifier -> [Metadata] -> UniqueId -> Maybe BasicBlock -> Value -> Value -> Instruction)+ -> InstInfoPtr -> Maybe Identifier -> Type+ -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateBinaryOp finalState constructor dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId++ case ops of+ [lhs, rhs] -> return $ constructor tt n mds uid bb lhs rhs+ _ -> throw $ InvalidBinaryOp (length ops)++translateAllocaInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateAllocaInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ align <- liftIO $ cInstructionAlign dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId++ case ops of+ [val] -> return AllocaInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , allocaNumElements = val+ , allocaAlign = align+ }+ _ -> throw $ InvalidUnaryOp (length ops)+++translateLoadInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateLoadInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ align <- liftIO $ cInstructionAlign dataPtr+ vol <- liftIO $ cInstructionIsVolatile dataPtr+ uid <- nextId++ ops <- mapM (translateConstOrRef finalState) opPtrs++ case ops of+ [addr] -> return LoadInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , loadIsVolatile = vol+ , loadAddress = addr+ , loadAlignment = align+ }+ _ -> throw $ InvalidUnaryOp (length ops)++translateStoreInst :: KnotState -> InstInfoPtr -> [Metadata]+ -> Maybe BasicBlock -> KnotMonad Instruction+translateStoreInst finalState dataPtr mds bb = do+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ addrSpace <- liftIO $ cInstructionAddrSpace dataPtr+ align <- liftIO $ cInstructionAlign dataPtr+ isVol <- liftIO $ cInstructionIsVolatile dataPtr++ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId++ case ops of+ [val, ptr] -> return StoreInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , storeIsVolatile = isVol+ , storeValue = val+ , storeAddress = ptr+ , storeAlignment = align+ , storeAddressSpace = addrSpace+ }+ _ -> throw $ InvalidBinaryOp (length ops)++translateGEPInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateGEPInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ inBounds <- liftIO $ cInstructionInBounds dataPtr+ addrSpace <- liftIO $ cInstructionAddrSpace dataPtr+ uid <- nextId++ ops <- mapM (translateConstOrRef finalState) opPtrs++ case ops of+ (val:indices) -> return GetElementPtrInst { _instructionName = n+ , _instructionType = tt+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , getElementPtrInBounds = inBounds+ , getElementPtrValue = val+ , getElementPtrIndices = indices+ , getElementPtrAddrSpace = addrSpace+ }+ _ -> throw $ InvalidGEPInst (length ops)++translateCastInst :: KnotState+ -> (Type -> Maybe Identifier -> [Metadata] -> UniqueId -> Maybe BasicBlock -> Value -> Instruction)+ -> InstInfoPtr -> Maybe Identifier -> Type+ -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateCastInst finalState constructor dataPtr name tt mds bb = do+ n <- computeRealName name+ uid <- nextId+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs++ case ops of+ [v] -> return $ constructor tt n mds uid bb v+ _ -> throw $ InvalidUnaryOp (length ops)++translateCmpInst :: KnotState+ -> (Type -> Maybe Identifier -> [Metadata] -> UniqueId -> Maybe BasicBlock -> CmpPredicate -> Value -> Value -> Instruction)+ -> InstInfoPtr -> Maybe Identifier -> Type -> [Metadata]+ -> Maybe BasicBlock -> KnotMonad Instruction+translateCmpInst finalState constructor dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ predicate <- liftIO $ cInstructionCmpPred dataPtr+ uid <- nextId++ ops <- mapM (translateConstOrRef finalState) opPtrs++ case ops of+ [op1, op2] -> return $ constructor tt n mds uid bb predicate op1 op2+ _ -> throw $ InvalidBinaryOp (length ops)++translatePhiNode :: KnotState -> PHIInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translatePhiNode finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ vptrs <- liftIO $ cPHIValues dataPtr+ bptrs <- liftIO $ cPHIBlocks dataPtr+ uid <- nextId++ vals <- mapM (translateConstOrRef finalState) vptrs+ blocks <- mapM (translateConstOrRef finalState) bptrs++ return PhiNode { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , phiIncomingValues = zip vals blocks+ }++translateCallInst :: KnotState -> CallInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateCallInst finalState dataPtr name tt mds bb = do+ n <- computeNameIfNotVoid name tt+ vptr <- liftIO $ cCallValue dataPtr+ aptrs <- liftIO $ cCallArguments dataPtr+ cc <- liftIO $ cCallConvention dataPtr+ hasSRet <- liftIO $ cCallHasSRet dataPtr+ isTail <- liftIO $ cCallIsTail dataPtr+ uid <- nextId++ val <- translateConstOrRef finalState vptr+ args <- mapM (translateConstOrRef finalState) aptrs++ return CallInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , callIsTail = isTail+ , callConvention = cc+ , callParamAttrs = [] -- FIXME+ , callFunction = val+ , callArguments = zip args (repeat []) -- FIXME+ , callAttrs = [] -- FIXME+ , callHasSRet = hasSRet+ }++translateSelectInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateSelectInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId+ case ops of+ [cond, trueval, falseval] ->+ return SelectInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , selectCondition = cond+ , selectTrueValue = trueval+ , selectFalseValue = falseval+ }+ _ -> throw $ InvalidSelectArgs (length ops)++translateVarArgInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateVarArgInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId+ case ops of+ [op] -> return VaArgInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , vaArgValue = op+ }+ _ -> throw $ InvalidUnaryOp (length ops)++translateExtractElementInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateExtractElementInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId+ case ops of+ [vec, idx] ->+ return ExtractElementInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , extractElementVector = vec+ , extractElementIndex = idx+ }+ _ -> throw $ InvalidExtractElementInst (length ops)++translateInsertElementInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateInsertElementInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId+ case ops of+ [vec, val, idx] ->+ return InsertElementInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , insertElementVector = vec+ , insertElementValue = val+ , insertElementIndex = idx+ }+ _ -> throw $ InvalidInsertElementInst (length ops)++translateShuffleVectorInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateShuffleVectorInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs+ uid <- nextId+ case ops of+ [v1, v2, vecMask] ->+ return ShuffleVectorInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , shuffleVectorV1 = v1+ , shuffleVectorV2 = v2+ , shuffleVectorMask = vecMask+ }+ _ -> throw $ InvalidShuffleVectorInst (length ops)++translateExtractValueInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateExtractValueInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ indices <- liftIO $ cInstructionIndices dataPtr+ uid <- nextId+ ops <- mapM (translateConstOrRef finalState) opPtrs+ case ops of+ [agg] -> return ExtractValueInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , extractValueAggregate = agg+ , extractValueIndices = indices+ }+ _ -> throw $ InvalidExtractValueInst (length ops)++translateInsertValueInst :: KnotState -> InstInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateInsertValueInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ indices <- liftIO $ cInstructionIndices dataPtr+ uid <- nextId+ ops <- mapM (translateConstOrRef finalState) opPtrs+ case ops of+ [agg, val] ->+ return InsertValueInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , insertValueAggregate = agg+ , insertValueValue = val+ , insertValueIndices = indices+ }+ _ -> throw $ InvalidInsertValueInst (length ops)++translateResumeInst :: KnotState -> InstInfoPtr -> [Metadata]+ -> Maybe BasicBlock -> KnotMonad Instruction+translateResumeInst finalState dataPtr mds bb = do+ uid <- nextId+ opPtrs <- liftIO $ cInstructionOperands dataPtr+ ops <- mapM (translateConstOrRef finalState) opPtrs+ case ops of+ [val] ->+ return ResumeInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , resumeException = val+ }+ _ -> throw $ InvalidResumeInst (length ops)++translateFenceInst :: KnotState -> AtomicInfoPtr -> [Metadata]+ -> Maybe BasicBlock -> KnotMonad Instruction+translateFenceInst _ dataPtr mds bb = do+ uid <- nextId+ order <- liftIO $ cAtomicOrdering dataPtr+ scope <- liftIO $ cAtomicScope dataPtr+ return FenceInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , fenceOrdering = order+ , fenceScope = scope+ }++translateAtomicCmpXchgInst :: KnotState -> AtomicInfoPtr -> [Metadata]+ -> Maybe BasicBlock -> KnotMonad Instruction+translateAtomicCmpXchgInst finalState dataPtr mds bb = do+ uid <- nextId+ order <- liftIO $ cAtomicOrdering dataPtr+ scope <- liftIO $ cAtomicScope dataPtr+ isVol <- liftIO $ cAtomicIsVolatile dataPtr+ addrSpc <- liftIO $ cAtomicAddressSpace dataPtr+ ptrPtr <- liftIO $ cAtomicPointerOperand dataPtr+ cmpPtr <- liftIO $ cAtomicCompareOperand dataPtr+ valPtr <- liftIO $ cAtomicValueOperand dataPtr++ ptr <- translateConstOrRef finalState ptrPtr+ cmp <- translateConstOrRef finalState cmpPtr+ val <- translateConstOrRef finalState valPtr++ return AtomicCmpXchgInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , atomicCmpXchgOrdering = order+ , atomicCmpXchgScope = scope+ , atomicCmpXchgIsVolatile = isVol+ , atomicCmpXchgAddressSpace = addrSpc+ , atomicCmpXchgPointer = ptr+ , atomicCmpXchgComparison = cmp+ , atomicCmpXchgNewValue = val+ }++translateAtomicRMWInst :: KnotState -> AtomicInfoPtr -> [Metadata]+ -> Maybe BasicBlock -> KnotMonad Instruction+translateAtomicRMWInst finalState dataPtr mds bb = do+ uid <- nextId+ order <- liftIO $ cAtomicOrdering dataPtr+ scope <- liftIO $ cAtomicScope dataPtr+ op <- liftIO $ cAtomicOperation dataPtr+ isVol <- liftIO $ cAtomicIsVolatile dataPtr+ addrSpc <- liftIO $ cAtomicAddressSpace dataPtr+ ptrPtr <- liftIO $ cAtomicPointerOperand dataPtr+ valPtr <- liftIO $ cAtomicValueOperand dataPtr++ ptr <- translateConstOrRef finalState ptrPtr+ val <- translateConstOrRef finalState valPtr++ return AtomicRMWInst { instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , atomicRMWOrdering = order+ , atomicRMWScope = scope+ , atomicRMWOperation = op+ , atomicRMWIsVolatile = isVol+ , atomicRMWAddressSpace = addrSpc+ , atomicRMWPointer = ptr+ , atomicRMWValue = val+ }++translateLandingPadInst :: KnotState -> LandingPadInfoPtr -> Maybe Identifier+ -> Type -> [Metadata] -> Maybe BasicBlock -> KnotMonad Instruction+translateLandingPadInst finalState dataPtr name tt mds bb = do+ n <- computeRealName name+ uid <- nextId+ personPtr <- liftIO $ cLandingPadPersonality dataPtr+ isClean <- liftIO $ cLandingPadIsCleanup dataPtr+ clausePtrs <- liftIO $ cLandingPadClauses dataPtr+ clauseTypes <- liftIO $ cLandingPadClauseTypes dataPtr++ personality <- translateConstOrRef finalState personPtr+ clauses <- mapM (translateConstOrRef finalState) clausePtrs++ let taggedClauses = zip clauses clauseTypes+ return LandingPadInst { _instructionType = tt+ , _instructionName = n+ , instructionMetadata = mds+ , instructionUniqueId = uid+ , instructionBasicBlock = bb+ , landingPadPersonality = personality+ , landingPadIsCleanup = isClean+ , landingPadClauses = taggedClauses+ }++translateConstantExpr :: KnotState -> ConstExprPtr -> Type -> KnotMonad Instruction+translateConstantExpr finalState dataPtr tt = do+ let mds = []+ bb = Nothing+ ii <- liftIO $ cConstExprInstInfo dataPtr+ tag <- liftIO $ cConstExprTag dataPtr+ case tag of+ ValAddinst -> translateFlaggedBinaryOp finalState AddInst ii Nothing tt mds bb+ ValFaddinst -> translateFlaggedBinaryOp finalState AddInst ii Nothing tt mds bb+ ValSubinst -> translateFlaggedBinaryOp finalState SubInst ii Nothing tt mds bb+ ValFsubinst -> translateFlaggedBinaryOp finalState SubInst ii Nothing tt mds bb+ ValMulinst -> translateFlaggedBinaryOp finalState MulInst ii Nothing tt mds bb+ ValFmulinst -> translateFlaggedBinaryOp finalState MulInst ii Nothing tt mds bb+ ValUdivinst -> translateBinaryOp finalState DivInst ii Nothing tt mds bb+ ValSdivinst -> translateBinaryOp finalState DivInst ii Nothing tt mds bb+ ValFdivinst -> translateBinaryOp finalState DivInst ii Nothing tt mds bb+ ValUreminst -> translateBinaryOp finalState RemInst ii Nothing tt mds bb+ ValSreminst -> translateBinaryOp finalState RemInst ii Nothing tt mds bb+ ValFreminst -> translateBinaryOp finalState RemInst ii Nothing tt mds bb+ ValShlinst -> translateBinaryOp finalState ShlInst ii Nothing tt mds bb+ ValLshrinst -> translateBinaryOp finalState LshrInst ii Nothing tt mds bb+ ValAshrinst -> translateBinaryOp finalState AshrInst ii Nothing tt mds bb+ ValAndinst -> translateBinaryOp finalState AndInst ii Nothing tt mds bb+ ValOrinst -> translateBinaryOp finalState OrInst ii Nothing tt mds bb+ ValXorinst -> translateBinaryOp finalState XorInst ii Nothing tt mds bb+ ValGetelementptrinst -> translateGEPInst finalState ii Nothing tt mds bb+ ValTruncinst -> translateCastInst finalState TruncInst ii Nothing tt mds bb+ ValZextinst -> translateCastInst finalState ZExtInst ii Nothing tt mds bb+ ValSextinst -> translateCastInst finalState SExtInst ii Nothing tt mds bb+ ValFptruncinst -> translateCastInst finalState FPTruncInst ii Nothing tt mds bb+ ValFpextinst -> translateCastInst finalState FPExtInst ii Nothing tt mds bb+ ValFptouiinst -> translateCastInst finalState FPToUIInst ii Nothing tt mds bb+ ValFptosiinst -> translateCastInst finalState FPToSIInst ii Nothing tt mds bb+ ValUitofpinst -> translateCastInst finalState UIToFPInst ii Nothing tt mds bb+ ValSitofpinst -> translateCastInst finalState SIToFPInst ii Nothing tt mds bb+ ValPtrtointinst -> translateCastInst finalState PtrToIntInst ii Nothing tt mds bb+ ValInttoptrinst -> translateCastInst finalState IntToPtrInst ii Nothing tt mds bb+ ValBitcastinst -> translateCastInst finalState BitcastInst ii Nothing tt mds bb+ ValIcmpinst -> translateCmpInst finalState ICmpInst ii Nothing tt mds bb+ ValFcmpinst -> translateCmpInst finalState FCmpInst ii Nothing tt mds bb+ ValSelectinst -> translateSelectInst finalState ii Nothing tt mds bb+ ValVaarginst -> translateVarArgInst finalState ii Nothing tt mds bb+ ValExtractelementinst -> translateExtractElementInst finalState ii Nothing tt mds bb+ ValInsertelementinst -> translateInsertElementInst finalState ii Nothing tt mds bb+ ValShufflevectorinst -> translateShuffleVectorInst finalState ii Nothing tt mds bb+ ValExtractvalueinst -> translateExtractValueInst finalState ii Nothing tt mds bb+ ValInsertvalueinst -> translateInsertValueInst finalState ii Nothing tt mds bb+ _ -> throw (NonInstructionTag tag)++translateMetadata :: KnotState -> MetaPtr -> KnotMonad Metadata+translateMetadata finalState mp = do+ s <- get+ let ip = ptrToIntPtr mp+ key = fromIntegral ip+ put s { visitedMetadata = S.insert ip (visitedMetadata s) }++ existingVal <- liftIO $ HT.lookup (metaMap s) key+ case existingVal of+ Just m -> return m+ Nothing -> translateMetadata' finalState mp++translateMetadataRec :: KnotState -> MetaPtr -> KnotMonad Metadata+translateMetadataRec finalState mp = do+ s <- get+ let ip = ptrToIntPtr mp+ -- If we have already visited this metadata object, look it up in+ -- the final state. We record visits *before* making recursive+ -- calls, allowing us to tie the knot by looking already-visited+ -- nodes up in the final state.+ --+ -- If we haven't seen this node before, we can safely call the+ -- outermost 'translateMetadata', which will make an entry in the+ -- visited set and then do the translation.+ case S.member ip (visitedMetadata s) of+ False -> translateMetadata finalState mp+ True -> do+ let key = fromIntegral ip+ finalVal = unsafePerformIO (HT.lookup (metaMap finalState) key)+ return $ maybe (throw MetaKnotFailure) id finalVal++maybeTranslateMetadataRec :: KnotState -> Maybe MetaPtr -> KnotMonad (Maybe Metadata)+maybeTranslateMetadataRec _ Nothing = return Nothing+maybeTranslateMetadataRec finalState (Just mp) =+ Just <$> translateMetadataRec finalState mp++metadataArrayToList :: Maybe Metadata -> [Maybe Metadata]+metadataArrayToList (Just (MetadataList _ elts)) = elts+metadataArrayToList Nothing = []+metadataArrayToList _ = error "Unexpected non-array metadata"++translateMetadata' :: KnotState -> MetaPtr -> KnotMonad Metadata+translateMetadata' finalState mp = do+ let ip = ptrToIntPtr mp+ s <- get+ put s { visitedMetadata = S.insert ip (visitedMetadata s) }+ metaTag <- liftIO $ cMetaTypeTag mp++ uid <- nextMetaId++ md <- case metaTag of+ MetaLocation -> do+ line <- liftIO $ cMetaLocationLine mp+ col <- liftIO $ cMetaLocationColumn mp++ return MetaSourceLocation { metaValueUniqueId = uid+ , metaSourceRow = line+ , metaSourceCol = col+ , metaSourceScope = Nothing+ }+ MetaDerivedtype -> do+ ctxt <- liftIO $ cMetaTypeContext mp+ name <- cMetaTypeName mp+ line <- liftIO $ cMetaTypeLine mp+ size <- liftIO $ cMetaTypeSize mp+ align <- liftIO $ cMetaTypeAlign mp+ off <- liftIO $ cMetaTypeOffset mp+ parent <- liftIO $ cMetaTypeDerivedFrom mp++ isArtif <- liftIO $ cMetaTypeIsArtificial mp+ isVirt <- liftIO $ cMetaTypeIsVirtual mp+ isForward <- liftIO $ cMetaTypeIsForward mp+ isProt <- liftIO $ cMetaTypeIsProtected mp+ isPriv <- liftIO $ cMetaTypeIsPrivate mp+ dir <- cMetaTypeDirectory mp+ file <- cMetaTypeFilename mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt+ parent' <- maybeTranslateMetadataRec finalState parent++ tag <- liftIO $ cMetaTag mp++ return MetaDWDerivedType { metaValueUniqueId = uid+ , metaDerivedTypeContext = ctxt'+ , metaDerivedTypeName = name+ , metaDerivedTypeFilename = file+ , metaDerivedTypeDirectory = dir+ , metaDerivedTypeLine = line+ , metaDerivedTypeSize = size+ , metaDerivedTypeAlign = align+ , metaDerivedTypeOffset = off+ , metaDerivedTypeParent = parent'+ , metaDerivedTypeTag = tag+ , metaDerivedTypeIsArtificial = isArtif+ , metaDerivedTypeIsVirtual = isVirt+ , metaDerivedTypeIsForward = isForward+ , metaDerivedTypeIsProtected = isProt+ , metaDerivedTypeIsPrivate = isPriv+ }+ MetaCompositetype -> do+ ctxt <- liftIO $ cMetaTypeContext mp+ name <- cMetaTypeName mp+ line <- liftIO $ cMetaTypeLine mp+ size <- liftIO $ cMetaTypeSize mp+ align <- liftIO $ cMetaTypeAlign mp+ off <- liftIO $ cMetaTypeOffset mp+ parent <- liftIO $ cMetaTypeDerivedFrom mp+ flags <- liftIO $ cMetaTypeFlags mp+ members <- liftIO $ cMetaTypeCompositeComponents mp+ rlang <- liftIO $ cMetaTypeRuntimeLanguage mp+ ctype <- liftIO $ cMetaTypeContainingType mp+ tparams <- liftIO $ cMetaTypeTemplateParams mp+ isArtif <- liftIO $ cMetaTypeIsArtificial mp+ isVirtual <- liftIO $ cMetaTypeIsVirtual mp+ isForward <- liftIO $ cMetaTypeIsForward mp+ isProt <- liftIO $ cMetaTypeIsProtected mp+ isPriv <- liftIO $ cMetaTypeIsPrivate mp+ isByRef <- liftIO $ cMetaTypeIsByRefStruct mp+ dir <- cMetaTypeDirectory mp+ file <- cMetaTypeFilename mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt+ parent' <- maybeTranslateMetadataRec finalState parent+ members' <- maybeTranslateMetadataRec finalState members+ ctype' <- maybeTranslateMetadataRec finalState ctype+ tparams' <- maybeTranslateMetadataRec finalState tparams++ tag <- liftIO $ cMetaTag mp++ return MetaDWCompositeType { metaValueUniqueId = uid+ , metaCompositeTypeTag = tag+ , metaCompositeTypeContext = ctxt'+ , metaCompositeTypeName = name+ , metaCompositeTypeFilename = file+ , metaCompositeTypeDirectory = dir+ , metaCompositeTypeLine = line+ , metaCompositeTypeSize = size+ , metaCompositeTypeAlign = align+ , metaCompositeTypeOffset = off+ , metaCompositeTypeFlags = flags+ , metaCompositeTypeParent = parent'+ , metaCompositeTypeMembers = members'+ , metaCompositeTypeRuntime = rlang+ , metaCompositeTypeContainer = ctype'+ , metaCompositeTypeTemplateParams = tparams'+ , metaCompositeTypeIsArtificial = isArtif+ , metaCompositeTypeIsVirtual = isVirtual+ , metaCompositeTypeIsForward = isForward+ , metaCompositeTypeIsProtected = isProt+ , metaCompositeTypeIsPrivate = isPriv+ , metaCompositeTypeIsByRefStruct = isByRef+ }+ MetaBasictype -> do+ ctxt <- liftIO $ cMetaTypeContext mp+ name <- cMetaTypeName mp+ line <- liftIO $ cMetaTypeLine mp+ size <- liftIO $ cMetaTypeSize mp+ align <- liftIO $ cMetaTypeAlign mp+ off <- liftIO $ cMetaTypeOffset mp+ flags <- liftIO $ cMetaTypeFlags mp+ encoding <- liftIO $ cMetaTypeEncoding mp+ dir <- cMetaTypeDirectory mp+ file <- cMetaTypeFilename mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt++ return MetaDWBaseType { metaValueUniqueId = uid+ , metaBaseTypeContext = ctxt'+ , metaBaseTypeName = name+ , metaBaseTypeFilename = file+ , metaBaseTypeDirectory = dir+ , metaBaseTypeLine = line+ , metaBaseTypeSize = size+ , metaBaseTypeAlign = align+ , metaBaseTypeOffset = off+ , metaBaseTypeFlags = flags+ , metaBaseTypeEncoding = encoding+ }+ MetaVariable -> do+ ctxt <- liftIO $ cMetaVariableContext mp+ name <- cMetaVariableName mp+ line <- liftIO $ cMetaVariableLine mp+ argNo <- liftIO $ cMetaVariableArgNumber mp+ ty <- liftIO $ cMetaVariableType mp+ isArtif <- liftIO $ cMetaVariableIsArtificial mp+ cplxAddr <- liftIO $ cMetaVariableAddrElements mp+ byRef <- liftIO $ cMetaVariableIsBlockByRefVar mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt+ ty' <- maybeTranslateMetadataRec finalState ty++ tag <- liftIO $ cMetaTag mp++ return MetaDWLocal { metaValueUniqueId = uid+ , metaLocalTag = tag+ , metaLocalContext = ctxt'+ , metaLocalName = name+ , metaLocalLine = line+ , metaLocalArgNo = argNo+ , metaLocalType = ty'+ , metaLocalIsArtificial = isArtif+ , metaLocalIsBlockByRefVar = byRef+ , metaLocalAddrElements = cplxAddr+ }+ MetaSubprogram -> do+ ctxt <- liftIO $ cMetaSubprogramContext mp+ name <- cMetaSubprogramName mp+ displayName <- cMetaSubprogramDisplayName mp+ linkageName <- cMetaSubprogramLinkageName mp+ line <- liftIO $ cMetaSubprogramLine mp+ ty <- liftIO $ cMetaSubprogramType mp+ isLocal <- liftIO $ cMetaSubprogramIsLocal mp+ virt <- liftIO $ cMetaSubprogramVirtuality mp+ virtIdx <- liftIO $ cMetaSubprogramVirtualIndex mp+ baseType <- liftIO $ cMetaSubprogramContainingType mp+ isArtif <- liftIO $ cMetaSubprogramIsArtificial mp+ isOpt <- liftIO $ cMetaSubprogramIsOptimized mp+ isPrivate <- liftIO $ cMetaSubprogramIsPrivate mp+ isProtected <- liftIO $ cMetaSubprogramIsProtected mp+ isExplicit <- liftIO $ cMetaSubprogramIsExplicit mp+ isPrototyped <- liftIO $ cMetaSubprogramIsPrototyped mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt+ ty' <- maybeTranslateMetadataRec finalState ty+ baseType' <- maybeTranslateMetadataRec finalState baseType++ return MetaDWSubprogram { metaValueUniqueId = uid+ , metaSubprogramContext = ctxt'+ , metaSubprogramName = name+ , metaSubprogramDisplayName = displayName+ , metaSubprogramLinkageName = linkageName+ , metaSubprogramLine = line+ , metaSubprogramType = ty'+ , metaSubprogramStatic = isLocal+ , metaSubprogramNotExtern = not isPrivate && not isProtected+ , metaSubprogramVirtuality = virt+ , metaSubprogramVirtIndex = virtIdx+ , metaSubprogramBaseType = baseType'+ , metaSubprogramArtificial = isArtif+ , metaSubprogramOptimized = isOpt+ , metaSubprogramIsExplicit = isExplicit+ , metaSubprogramIsPrototyped = isPrototyped+ }+ MetaGlobalvariable -> do+ ctxt <- liftIO $ cMetaGlobalContext mp+ name <- cMetaGlobalName mp+ displayName <- cMetaGlobalDisplayName mp+ linkageName <- cMetaGlobalLinkageName mp+ line <- liftIO $ cMetaGlobalLine mp+ ty <- liftIO $ cMetaGlobalType mp+ isLocal <- liftIO $ cMetaGlobalIsLocal mp+ def <- liftIO $ cMetaGlobalIsDefinition mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt+ ty' <- maybeTranslateMetadataRec finalState ty++ return MetaDWVariable { metaValueUniqueId = uid+ , metaGlobalVarContext = ctxt'+ , metaGlobalVarName = name+ , metaGlobalVarDisplayName = displayName+ , metaGlobalVarLinkageName = linkageName+ , metaGlobalVarLine = line+ , metaGlobalVarType = ty'+ , metaGlobalVarStatic = isLocal+ , metaGlobalVarNotExtern = not def+ }+ MetaFile -> do+ file <- cMetaFileFilename mp+ dir <- cMetaFileDirectory mp++ return MetaDWFile { metaValueUniqueId = uid+ , metaFileSourceFile = file+ , metaFileSourceDir = dir+ }+ MetaCompileunit -> do+ lang <- liftIO $ cMetaCompileUnitLanguage mp+ fname <- cMetaCompileUnitFilename mp+ dir <- cMetaCompileUnitDirectory mp+ producer <- cMetaCompileUnitProducer mp+ isMain <- liftIO $ cMetaCompileUnitIsMain mp+ isOpt <- liftIO $ cMetaCompileUnitIsOptimized mp+ flags <- cMetaCompileUnitFlags mp+ rv <- liftIO $ cMetaCompileUnitRuntimeVersion mp+ ets <- liftIO $ cMetaCompileUnitEnumTypes mp+ rts <- liftIO $ cMetaCompileUnitRetainedTypes mp+ sps <- liftIO $ cMetaCompileUnitSubprograms mp+ gvs <- liftIO $ cMetaCompileUnitGlobalVariables mp++ ets' <- maybeTranslateMetadataRec finalState ets+ rts' <- maybeTranslateMetadataRec finalState rts+ sps' <- maybeTranslateMetadataRec finalState sps+ gvs' <- maybeTranslateMetadataRec finalState gvs++ return MetaDWCompileUnit { metaValueUniqueId = uid+ , metaCompileUnitLanguage = lang+ , metaCompileUnitSourceFile = fname+ , metaCompileUnitCompileDir = dir+ , metaCompileUnitProducer = producer+ , metaCompileUnitIsMain = isMain+ , metaCompileUnitIsOpt = isOpt+ , metaCompileUnitFlags = flags+ , metaCompileUnitVersion = rv+ , metaCompileUnitEnumTypes = metadataArrayToList ets'+ , metaCompileUnitRetainedTypes = metadataArrayToList rts'+ , metaCompileUnitSubprograms = metadataArrayToList sps'+ , metaCompileUnitGlobalVariables = metadataArrayToList gvs'+ }+ MetaNamespace -> do+ ctxt <- liftIO $ cMetaNamespaceContext mp+ name <- cMetaNamespaceName mp+ line <- liftIO $ cMetaNamespaceLine mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt++ return MetaDWNamespace { metaValueUniqueId = uid+ , metaNamespaceContext = ctxt'+ , metaNamespaceName = name+ , metaNamespaceLine = line+ }+ MetaLexicalblock -> do+ ctxt <- liftIO $ cMetaLexicalBlockContext mp+ line <- liftIO $ cMetaLexicalBlockLine mp+ col <- liftIO $ cMetaLexicalBlockColumn mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt++ return MetaDWLexicalBlock { metaValueUniqueId = uid+ , metaLexicalBlockRow = line+ , metaLexicalBlockCol = col+ , metaLexicalBlockContext = ctxt'+ }+ MetaSubrange -> do+ lo <- liftIO $ cMetaSubrangeLo mp+ hi <- liftIO $ cMetaSubrangeHi mp+ return MetaDWSubrange { metaValueUniqueId = uid+ , metaSubrangeLow = lo+ , metaSubrangeHigh = hi+ }+ MetaEnumerator -> do+ name <- cMetaEnumeratorName mp+ val <- liftIO $ cMetaEnumeratorValue mp+ return MetaDWEnumerator { metaValueUniqueId = uid+ , metaEnumeratorName = name+ , metaEnumeratorValue = val+ }+ MetaArray -> do+ elts <- liftIO $ cMetaArrayElts mp+ elts' <- mapM (maybeTranslateMetadataRec finalState) elts++ return $ MetadataList uid elts'++ MetaTemplatetypeparameter -> do+ ctxt <- liftIO $ cMetaTemplateTypeContext mp+ name <- cMetaTemplateTypeName mp+ ty <- liftIO $ cMetaTemplateTypeType mp+ line <- liftIO $ cMetaTemplateTypeLine mp+ col <- liftIO $ cMetaTemplateTypeColumn mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt+ ty' <- maybeTranslateMetadataRec finalState ty++ return MetaDWTemplateTypeParameter { metaValueUniqueId = uid+ , metaTemplateTypeParameterContext = ctxt'+ , metaTemplateTypeParameterType = ty'+ , metaTemplateTypeParameterLine = line+ , metaTemplateTypeParameterCol = col+ , metaTemplateTypeParameterName = name+ }+ MetaTemplatevalueparameter -> do+ ctxt <- liftIO $ cMetaTemplateValueContext mp+ name <- cMetaTemplateValueName mp+ ty <- liftIO $ cMetaTemplateValueType mp+ val <- liftIO $ cMetaTemplateValueValue mp+ line <- liftIO $ cMetaTemplateValueLine mp+ col <- liftIO $ cMetaTemplateValueColumn mp++ ctxt' <- maybeTranslateMetadataRec finalState ctxt+ ty' <- maybeTranslateMetadataRec finalState ty++ return MetaDWTemplateValueParameter { metaValueUniqueId = uid+ , metaTemplateValueParameterContext = ctxt'+ , metaTemplateValueParameterType = ty'+ , metaTemplateValueParameterLine = line+ , metaTemplateValueParameterCol = col+ , metaTemplateValueParameterValue = val+ , metaTemplateValueParameterName = name+ }+ MetaUnknown -> do+ repr <- cMetaUnknownRepr mp+ return $! MetadataUnknown uid repr++ st <- get+ liftIO $ HT.insert (metaMap st) (fromIntegral ip) md+ return md
+ src/c++/marshal.cpp view
@@ -0,0 +1,2673 @@+#define __STDC_LIMIT_MACROS+#define __STDC_CONSTANT_MACROS++#include "marshal.h"++#include <algorithm>+#include <cstdlib>+#include <cstring>+#include <cmath>+#include <set>+#include <sstream>+#include <string>+#include <vector>+#include <tr1/unordered_map>++#include <llvm/ADT/OwningPtr.h>+#include <llvm/ADT/SmallVector.h>+#include <llvm/Bitcode/ReaderWriter.h>+#include <llvm/Support/MemoryBuffer.h>+#include <llvm/Support/raw_ostream.h>+#include <llvm/Support/SourceMgr.h>+#include <llvm/Support/system_error.h>++#include <llvm/Config/llvm-config.h>++#if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR > 3+ #error "LLVM 4.0 and greater are not supported"+#endif++// LLVM 3.0 does not define LLVM_VERSION_MAJOR+#if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 2+ // LLVM 3.2 moved the debug info header and renamed TargetData+ // to DataLayout. LLVM 3.3 moved the DataLayout header.+ #include <llvm/DebugInfo.h>+ #if LLVM_VERSION_MINOR >= 3+ #include <llvm/IR/DataLayout.h>+ #else+ #include <llvm/DataLayout.h>+ #endif+#else+ // LLVM 3.0/3.1+ #include <llvm/Analysis/DebugInfo.h>+ #include <llvm/Target/TargetData.h>+ #define DataLayout TargetData+#endif++#if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 3+ // LLVM 3.3+ #include <llvm/IR/CallingConv.h>+ #include <llvm/IR/DerivedTypes.h>+ #include <llvm/IR/InlineAsm.h>+ #include <llvm/IR/IntrinsicInst.h>+ #include <llvm/IR/Instructions.h>+ #include <llvm/IR/LLVMContext.h>+ #include <llvm/IR/Module.h>+ #include <llvm/IR/Operator.h>+ #include <llvm/IR/Type.h>+ #include <llvm/IRReader/IRReader.h>+#else+ // LLVM 3.0-3.2+ #include <llvm/CallingConv.h>+ #include <llvm/DerivedTypes.h>+ #include <llvm/InlineAsm.h>+ #include <llvm/IntrinsicInst.h>+ #include <llvm/Instructions.h>+ #include <llvm/LLVMContext.h>+ #include <llvm/Module.h>+ #include <llvm/Operator.h>+ #include <llvm/Type.h>+ #include <llvm/Support/IRReader.h>+#endif++using namespace llvm;+using std::ostringstream;+using std::string;+using std::tr1::unordered_map;++// Utility functions to hide incompatibilities between LLVM API+// versions+static int64_t getHiDISubrange(llvm::DISubrange &subrange) {+#if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 3+ return subrange.getLo() + subrange.getCount();+#else+ return subrange.getHi();+#endif+}++static char* getCStrdup(StringRef str) {+ return strndup(str.data(), str.size());+}++static char* getCStrdup(std::string &str) {+ return strdup(str.c_str());+}++static char* getCStrdup(const char *str) {+ return strdup(str);+}++static char* getCStrdup(llvm::raw_string_ostream &os) {+ return getCStrdup(os.str());+}++struct PrivateData {+ LLVMContext ctxt;+ SMDiagnostic diags;+ OwningPtr<MemoryBuffer> buffer;+ // Foreign callers do not need to access below this point.+ Module* original;+ int includeLocs;+ DataLayout *dataLayout;++ // This map is actually state only for this translation code. Since+ // types have pointer equality in LLVM, every type will just be+ // translated once to a heap-allocated CType. On the Haskell side,+ // each CType needs to be translated once (mapping the address of+ // the CType to the translated version).+ unordered_map<const Type*, CType*> typeMap;+ unordered_map<const Value*, CValue*> valueMap;+ unordered_map<const MDNode*, CMeta*> metaMap;+ unordered_map<const DebugLoc*, CMeta*> srcLocMap;+};++static ValueTag decodeOpcode(unsigned opcode) {+ switch(opcode) {+ case Instruction::Ret: return VAL_RETINST;+ case Instruction::Br: return VAL_BRANCHINST;+ case Instruction::Switch: return VAL_SWITCHINST;+ case Instruction::IndirectBr: return VAL_INDIRECTBRINST;+ case Instruction::Invoke: return VAL_INVOKEINST;+ case Instruction::Resume: return VAL_RESUMEINST;+ case Instruction::Unreachable: return VAL_UNREACHABLEINST;+ case Instruction::Add: return VAL_ADDINST;+ case Instruction::FAdd: return VAL_FADDINST;+ case Instruction::Sub: return VAL_SUBINST;+ case Instruction::FSub: return VAL_FSUBINST;+ case Instruction::Mul: return VAL_MULINST;+ case Instruction::FMul: return VAL_FMULINST;+ case Instruction::UDiv: return VAL_UDIVINST;+ case Instruction::SDiv: return VAL_SDIVINST;+ case Instruction::FDiv: return VAL_FDIVINST;+ case Instruction::URem: return VAL_UREMINST;+ case Instruction::SRem: return VAL_SREMINST;+ case Instruction::FRem: return VAL_FREMINST;+ case Instruction::Shl: return VAL_SHLINST;+ case Instruction::LShr: return VAL_LSHRINST;+ case Instruction::AShr: return VAL_ASHRINST;+ case Instruction::And: return VAL_ANDINST;+ case Instruction::Or: return VAL_ORINST;+ case Instruction::Xor: return VAL_XORINST;+ case Instruction::Alloca: return VAL_ALLOCAINST;+ case Instruction::Load: return VAL_LOADINST;+ case Instruction::Store: return VAL_STOREINST;+ case Instruction::GetElementPtr: return VAL_GETELEMENTPTRINST;+ case Instruction::Fence: return VAL_FENCEINST;+ case Instruction::AtomicCmpXchg: return VAL_ATOMICCMPXCHGINST;+ case Instruction::AtomicRMW: return VAL_ATOMICRMWINST;+ case Instruction::Trunc: return VAL_TRUNCINST;+ case Instruction::ZExt: return VAL_ZEXTINST;+ case Instruction::SExt: return VAL_SEXTINST;+ case Instruction::FPToUI: return VAL_FPTOUIINST;+ case Instruction::FPToSI: return VAL_FPTOSIINST;+ case Instruction::UIToFP: return VAL_UITOFPINST;+ case Instruction::SIToFP: return VAL_SITOFPINST;+ case Instruction::FPTrunc: return VAL_FPTRUNCINST;+ case Instruction::FPExt: return VAL_FPEXTINST;+ case Instruction::PtrToInt: return VAL_PTRTOINTINST;+ case Instruction::IntToPtr: return VAL_INTTOPTRINST;+ case Instruction::BitCast: return VAL_BITCASTINST;+ case Instruction::ICmp: return VAL_ICMPINST;+ case Instruction::FCmp: return VAL_FCMPINST;+ case Instruction::PHI: return VAL_PHINODE;+ case Instruction::Call: return VAL_CALLINST;+ case Instruction::Select: return VAL_SELECTINST;+ case Instruction::VAArg: return VAL_VAARGINST;+ case Instruction::ExtractElement: return VAL_EXTRACTELEMENTINST;+ case Instruction::InsertElement: return VAL_INSERTELEMENTINST;+ case Instruction::ShuffleVector: return VAL_SHUFFLEVECTORINST;+ case Instruction::ExtractValue: return VAL_EXTRACTVALUEINST;+ case Instruction::InsertValue: return VAL_INSERTVALUEINST;+ case Instruction::LandingPad: return VAL_LANDINGPADINST;+ }++ ostringstream os;+ os << "Unhandled instruction type in opcode translator: " << opcode;+ throw os.str();+}++static CmpPredicate decodePredicate(CmpInst::Predicate p) {+ switch(p) {+ case CmpInst::FCMP_FALSE: return F_CMP_FALSE;+ case CmpInst::FCMP_OEQ: return F_CMP_OEQ;+ case CmpInst::FCMP_OGT: return F_CMP_OGT;+ case CmpInst::FCMP_OGE: return F_CMP_OGE;+ case CmpInst::FCMP_OLT: return F_CMP_OLT;+ case CmpInst::FCMP_OLE: return F_CMP_OLE;+ case CmpInst::FCMP_ONE: return F_CMP_ONE;+ case CmpInst::FCMP_ORD: return F_CMP_ORD;+ case CmpInst::FCMP_UNO: return F_CMP_UNO;+ case CmpInst::FCMP_UEQ: return F_CMP_UEQ;+ case CmpInst::FCMP_UGT: return F_CMP_UGT;+ case CmpInst::FCMP_UGE: return F_CMP_UGE;+ case CmpInst::FCMP_ULT: return F_CMP_ULT;+ case CmpInst::FCMP_ULE: return F_CMP_ULE;+ case CmpInst::FCMP_UNE: return F_CMP_UNE;+ case CmpInst::FCMP_TRUE: return F_CMP_TRUE;+ case CmpInst::ICMP_EQ: return I_CMP_EQ;+ case CmpInst::ICMP_NE: return I_CMP_NE;+ case CmpInst::ICMP_UGT: return I_CMP_UGT;+ case CmpInst::ICMP_UGE: return I_CMP_UGE;+ case CmpInst::ICMP_ULT: return I_CMP_ULT;+ case CmpInst::ICMP_ULE: return I_CMP_ULE;+ case CmpInst::ICMP_SGT: return I_CMP_SGT;+ case CmpInst::ICMP_SGE: return I_CMP_SGE;+ case CmpInst::ICMP_SLT: return I_CMP_SLT;+ case CmpInst::ICMP_SLE: return I_CMP_SLE;+ }++ ostringstream os;+ os << "Unhandled comparison predicate: " << p;+ throw os.str();+}++static TypeTag decodeTypeTag(Type::TypeID t) {+ switch(t) {+ case Type::VoidTyID: return TYPE_VOID;+ case Type::FloatTyID: return TYPE_FLOAT;+ case Type::DoubleTyID: return TYPE_DOUBLE;+ case Type::X86_FP80TyID: return TYPE_X86_FP80;+ case Type::FP128TyID: return TYPE_FP128;+ case Type::PPC_FP128TyID: return TYPE_PPC_FP128;+ case Type::LabelTyID: return TYPE_LABEL;+ case Type::MetadataTyID: return TYPE_METADATA;+ case Type::X86_MMXTyID: return TYPE_X86_MMX;+ case Type::IntegerTyID: return TYPE_INTEGER;+ case Type::FunctionTyID: return TYPE_FUNCTION;+ case Type::StructTyID: return TYPE_STRUCT;+ case Type::ArrayTyID: return TYPE_ARRAY;+ case Type::PointerTyID: return TYPE_POINTER;+ case Type::VectorTyID: return TYPE_VECTOR;+ }++ ostringstream os;+ os << "Unhandled type tag case: " << t;+ throw os.str();+}++static LinkageType decodeLinkage(const GlobalValue *gv) {+ switch(gv->getLinkage()) {+ case GlobalValue::ExternalLinkage: return LTExternal;+ case GlobalValue::AvailableExternallyLinkage: return LTAvailableExternally;+ case GlobalValue::LinkOnceAnyLinkage: return LTLinkOnceAny;+ case GlobalValue::LinkOnceODRLinkage: return LTLinkOnceODR;+ case GlobalValue::WeakAnyLinkage: return LTWeakAny;+ case GlobalValue::WeakODRLinkage: return LTWeakODR;+ case GlobalValue::AppendingLinkage: return LTAppending;+ case GlobalValue::InternalLinkage: return LTInternal;+ case GlobalValue::PrivateLinkage: return LTPrivate;+ case GlobalValue::LinkerPrivateLinkage: return LTLinkerPrivate;+ case GlobalValue::LinkerPrivateWeakLinkage: return LTLinkerPrivateWeak;+#if LLVM_VERSION_MINOR < 2+ case GlobalValue::LinkerPrivateWeakDefAutoLinkage: return LTLinkerPrivateWeakDefAuto;+#endif+ case GlobalValue::DLLImportLinkage: return LTDLLImport;+ case GlobalValue::DLLExportLinkage: return LTDLLExport;+ case GlobalValue::ExternalWeakLinkage: return LTExternalWeak;+ case GlobalValue::CommonLinkage: return LTCommon;+ }++ ostringstream os;+ os << "Unhandled linkage type: " << gv->getLinkage();+ throw os.str();+}++static VisibilityStyle decodeVisibility(const GlobalValue *gv) {+ switch(gv->getVisibility()) {+ case GlobalValue::DefaultVisibility: return VisibilityDefault;+ case GlobalValue::HiddenVisibility: return VisibilityHidden;+ case GlobalValue::ProtectedVisibility: return VisibilityProtected;+ }++ ostringstream os;+ os << "Unhandled visibility style: " << gv->getVisibility();+ throw os.str();+}++static CAtomicOrdering decodeOrdering(AtomicOrdering o) {+ switch(o) {+ case llvm::NotAtomic: return OrderNotAtomic;+ case llvm::Unordered: return OrderUnordered;+ case llvm::Monotonic: return OrderMonotonic;+ case llvm::Acquire: return OrderAcquire;+ case llvm::Release: return OrderRelease;+ case llvm::AcquireRelease: return OrderAcquireRelease;+ case llvm::SequentiallyConsistent: return OrderSequentiallyConsistent;+ }++ ostringstream os;+ os << "Unhandled atomic ordering: " << o;+ throw os.str();+}++static CSynchronizationScope decodeSynchScope(SynchronizationScope s) {+ switch(s) {+ case llvm::SingleThread: return SSSingleThread;+ case llvm::CrossThread: return SSCrossThread;+ }++ ostringstream os;+ os << "Unhandled synchronization scope: " << s;+ throw os.str();+}++static AtomicOperation decodeAtomicOp(AtomicRMWInst::BinOp o) {+ switch(o) {+ case AtomicRMWInst::Xchg: return AOXchg;+ case AtomicRMWInst::Add: return AOAdd;+ case AtomicRMWInst::Sub: return AOSub;+ case AtomicRMWInst::And: return AOAnd;+ case AtomicRMWInst::Nand: return AONand;+ case AtomicRMWInst::Or: return AOOr;+ case AtomicRMWInst::Xor: return AOXor;+ case AtomicRMWInst::Max: return AOMax;+ case AtomicRMWInst::Min: return AOMin;+ case AtomicRMWInst::UMax: return AOUMax;+ case AtomicRMWInst::UMin: return AOUMin;+ }++ ostringstream os;+ os << "Unhandled atomic operation: " << o;+ throw os.str();+}++static CallingConvention decodeCallingConvention(CallingConv::ID cc) {+ switch(cc) {+ case CallingConv::C: return CC_C;+ case CallingConv::Fast: return CC_FAST;+ case CallingConv::Cold: return CC_COLD;+ case CallingConv::GHC: return CC_GHC;+ case CallingConv::X86_StdCall: return CC_X86_STDCALL;+ case CallingConv::X86_FastCall: return CC_X86_FASTCALL;+ case CallingConv::ARM_APCS: return CC_ARM_APCS;+ case CallingConv::ARM_AAPCS: return CC_ARM_AAPCS;+ case CallingConv::ARM_AAPCS_VFP: return CC_ARM_AAPCS_VFP;+ case CallingConv::MSP430_INTR: return CC_MSP430_INTR;+ case CallingConv::X86_ThisCall: return CC_X86_THISCALL;+ case CallingConv::PTX_Kernel: return CC_PTX_KERNEL;+ case CallingConv::PTX_Device: return CC_PTX_DEVICE;+ case CallingConv::MBLAZE_INTR: return CC_MBLAZE_INTR;+ case CallingConv::MBLAZE_SVOL: return CC_MBLAZE_SVOL;+ }++ ostringstream os;+ os << "Unhandled calling convention: " << cc;+ throw os.str();+}++static void disposeCType(CType *ct) {+ free(ct->name);+ free(ct->typeList);+ free(ct);+}++static void disposeCMeta(CMeta *meta) {+ switch(meta->metaTag) {+ case META_LOCATION:+ free(meta->u.metaLocationInfo.filename);+ free(meta->u.metaLocationInfo.directory);+ break;++ case META_DERIVEDTYPE:+ case META_COMPOSITETYPE:+ case META_BASICTYPE:+ free(meta->u.metaTypeInfo.name);+ free(meta->u.metaTypeInfo.directory);+ free(meta->u.metaTypeInfo.filename);+ break;++ case META_VARIABLE:+ free(meta->u.metaVariableInfo.name);+ break;++ case META_SUBPROGRAM:+ free(meta->u.metaSubprogramInfo.name);+ free(meta->u.metaSubprogramInfo.displayName);+ free(meta->u.metaSubprogramInfo.linkageName);+ free(meta->u.metaSubprogramInfo.returnTypeName);+ free(meta->u.metaSubprogramInfo.filename);+ free(meta->u.metaSubprogramInfo.directory);+ break;++ case META_GLOBALVARIABLE:+ free(meta->u.metaGlobalInfo.name);+ free(meta->u.metaGlobalInfo.displayName);+ free(meta->u.metaGlobalInfo.linkageName);+ break;++ case META_FILE:+ free(meta->u.metaFileInfo.filename);+ free(meta->u.metaFileInfo.directory);+ break;++ case META_COMPILEUNIT:+ free(meta->u.metaCompileUnitInfo.filename);+ free(meta->u.metaCompileUnitInfo.directory);+ free(meta->u.metaCompileUnitInfo.producer);+ free(meta->u.metaCompileUnitInfo.flags);+ break;++ case META_NAMESPACE:+ free(meta->u.metaNamespaceInfo.name);+ free(meta->u.metaNamespaceInfo.directory);+ free(meta->u.metaNamespaceInfo.filename);+ break;++ case META_LEXICALBLOCK:+ free(meta->u.metaLexicalBlockInfo.directory);+ free(meta->u.metaLexicalBlockInfo.filename);+ break;++ case META_SUBRANGE:+ break;++ case META_ENUMERATOR:+ free(meta->u.metaEnumeratorInfo.enumName);+ break;++ case META_ARRAY:+ free(meta->u.metaArrayInfo.arrayElts);+ break;++ case META_TEMPLATETYPEPARAMETER:+ free(meta->u.metaTemplateTypeInfo.name);+ free(meta->u.metaTemplateTypeInfo.filename);+ free(meta->u.metaTemplateTypeInfo.directory);+ break;++ case META_TEMPLATEVALUEPARAMETER:+ free(meta->u.metaTemplateValueInfo.name);+ free(meta->u.metaTemplateValueInfo.filename);+ free(meta->u.metaTemplateValueInfo.directory);+ break;++ case META_UNKNOWN:+ free(meta->u.metaUnknownInfo.repr);+ break;+ }+++ free(meta);+}++// Have to do the delete in this function since the pointer must be+// cast to the correct type.+static void disposeData(ValueTag t, void* data) {+ switch(t) {+ case VAL_ARGUMENT:+ {+ CArgumentInfo *ai = (CArgumentInfo*)data;+ free(ai);+ return;+ }++ case VAL_BASICBLOCK:+ {+ CBasicBlockInfo *bbi = (CBasicBlockInfo*)data;++ // The actual values are deleted from the valueMap+ free(bbi->instructions);++ free(bbi);+ return;+ }++ case VAL_INLINEASM:+ {+ CInlineAsmInfo *ii = (CInlineAsmInfo*)data;+ free(ii->asmString);+ free(ii->constraintString);+ free(ii);+ return;+ }++ case VAL_ALIAS:+ case VAL_GLOBALVARIABLE:+ {+ CGlobalInfo *gi = (CGlobalInfo*)data;++ free(gi->section);++ free(gi);+ return;+ }++ case VAL_FUNCTION:+ {+ CFunctionInfo *fi = (CFunctionInfo*)data;++ free(fi->section);+ free(fi->gcName);++ free(fi->arguments);+ free(fi->body);++ free(fi);+ return;+ }++ case VAL_UNREACHABLEINST:+ {+ // No data+ return;+ }++ case VAL_INVOKEINST:+ case VAL_CALLINST:+ {+ CCallInfo *ci = (CCallInfo*)data;++ free(ci->arguments);+ free(ci);+ return;+ }++ case VAL_PHINODE:+ {+ CPHIInfo *pi = (CPHIInfo*)data;+ free(pi->incomingValues);+ free(pi->valueBlocks);+ free(pi);+ return;+ }++ case VAL_FENCEINST:+ case VAL_ATOMICCMPXCHGINST:+ case VAL_ATOMICRMWINST:+ {+ CAtomicInfo *ai = (CAtomicInfo*)data;+ free(ai);+ return;+ }++ case VAL_LANDINGPADINST:+ {+ CLandingPadInfo *li = (CLandingPadInfo*)data;+ free(li->clauses);+ free(li->clauseTypes);+ return;+ }++ case VAL_RESUMEINST:+ case VAL_RETINST:+ case VAL_BRANCHINST:+ case VAL_SWITCHINST:+ case VAL_INDIRECTBRINST:+ case VAL_GETELEMENTPTRINST:+ case VAL_STOREINST:+ case VAL_ALLOCAINST:+ case VAL_LOADINST:+ case VAL_ADDINST:+ case VAL_FADDINST:+ case VAL_SUBINST:+ case VAL_FSUBINST:+ case VAL_MULINST:+ case VAL_FMULINST:+ case VAL_UDIVINST:+ case VAL_SDIVINST:+ case VAL_FDIVINST:+ case VAL_UREMINST:+ case VAL_SREMINST:+ case VAL_FREMINST:+ case VAL_SHLINST:+ case VAL_LSHRINST:+ case VAL_ASHRINST:+ case VAL_ANDINST:+ case VAL_ORINST:+ case VAL_XORINST:+ case VAL_TRUNCINST:+ case VAL_ZEXTINST:+ case VAL_SEXTINST:+ case VAL_FPTOUIINST:+ case VAL_FPTOSIINST:+ case VAL_UITOFPINST:+ case VAL_SITOFPINST:+ case VAL_FPTRUNCINST:+ case VAL_FPEXTINST:+ case VAL_PTRTOINTINST:+ case VAL_INTTOPTRINST:+ case VAL_BITCASTINST:+ case VAL_ICMPINST:+ case VAL_FCMPINST:+ case VAL_VAARGINST:+ case VAL_SELECTINST:+ case VAL_EXTRACTELEMENTINST:+ case VAL_INSERTELEMENTINST:+ case VAL_SHUFFLEVECTORINST:+ case VAL_EXTRACTVALUEINST:+ case VAL_INSERTVALUEINST:+ {+ CInstructionInfo *ii = (CInstructionInfo*)data;+ free(ii->operands);+ free(ii->indices);+ free(ii);+ return;+ }++ case VAL_BLOCKADDRESS:+ {+ CBlockAddrInfo *bi = (CBlockAddrInfo*)data;+ free(bi);+ return;+ }++ case VAL_CONSTANTINT:+ {+ CConstInt *d = (CConstInt*)data;+ free(d->hugeVal);+ free(d);+ return;+ }++ case VAL_CONSTANTFP:+ {+ CConstFP *d = (CConstFP*)data;+ free(d);+ return;+ }++ case VAL_CONSTANTPOINTERNULL:+ case VAL_CONSTANTAGGREGATEZERO:+ case VAL_UNDEFVALUE:+ {+ // No data+ return;+ }++ case VAL_CONSTANTSTRUCT:+ case VAL_CONSTANTVECTOR:+ case VAL_CONSTANTARRAY:+ {+ CConstAggregate *c = (CConstAggregate*)data;+ free(c->constants);+ free(c);+ return;+ }++ case VAL_CONSTANTEXPR:+ {+ CConstExprInfo *ce = (CConstExprInfo*)data;+ free(ce->ii->operands);+ free(ce->ii->indices);+ free(ce->ii);+ free(ce);+ return;+ }++ }++ ostringstream os;+ os << "Unhandled cleanup case for value tag: " << t;+ throw os.str();+}++static void disposeCValue(CValue *v) {+ // Do not dispose the type - that is taken care of in bulk in the+ // CModule disposal. Same for MD.+ free(v->name);+ free(v->md);++ disposeData(v->valueTag, v->data);++ free(v);+}++static MetaTag extractMetaTag(const MDNode *md) {+ DIDescriptor desc(md);+ // Ranked roughly by frequency.+ if(desc.isLexicalBlock()) return META_LEXICALBLOCK;+ // This variant of lexical block has an extra file argument that is+ // not currently translated. This might be used for code inserted+ // by the preprocessor from headers?+ if(desc.isLexicalBlockFile()) return META_LEXICALBLOCK;+ if(desc.isVariable()) return META_VARIABLE;+ if(desc.isSubprogram()) return META_SUBPROGRAM;+ if(desc.isGlobalVariable()) return META_GLOBALVARIABLE;+ if(desc.isCompositeType()) return META_COMPOSITETYPE;+ if(desc.isDerivedType()) return META_DERIVEDTYPE;+ if(desc.isBasicType()) return META_BASICTYPE;+ if(desc.isFile()) return META_FILE;+ if(desc.isCompileUnit()) return META_COMPILEUNIT;+ if(desc.isNameSpace()) return META_NAMESPACE;+ if(desc.isSubrange()) return META_SUBRANGE;+ if(desc.isEnumerator()) return META_ENUMERATOR;+ if(desc.isTemplateTypeParameter()) return META_TEMPLATETYPEPARAMETER;+ if(desc.isTemplateValueParameter()) return META_TEMPLATEVALUEPARAMETER;++ DILocation loc(md);+ if(loc.Verify()) return META_LOCATION;++ // Otherwise we have no idea what to do with this. One type of odd+ // metadata is the inline assembly srcloc metadata, which has a+ // strange format. Right now we don't bother to translate this. It+ // could probably be done if required... we don't know what it+ // really is at this stage, though, so it might need to be+ // serialized generically as an MDNode+ return META_UNKNOWN;+}++static CValue* translateConstant(CModule *m, const Constant *c);+static CValue* translateValue(CModule *m, const Value *v);+static CValue* translateBasicBlock(CModule *m, const BasicBlock *bb);+static CMeta* translateMetadata(CModule *m, const MDNode *md);+static CMeta* translateMetadataArray(CModule *m, const MDNode *md);++static void makeMetaSrcLocation(CModule *m, const DebugLoc &loc, CMeta *meta) {+ meta->u.metaLocationInfo.lineNumber = loc.getLine();+ meta->u.metaLocationInfo.columnNumber = loc.getCol();+}++static void makeMetaLocation(CModule *m, const MDNode *md, CMeta *meta) {+ DILocation loc(md);+ meta->u.metaLocationInfo.lineNumber = loc.getLineNumber();+ meta->u.metaLocationInfo.columnNumber = loc.getColumnNumber();+}++static void makeMetaDerivedType(CModule *m, const MDNode *md, CMeta *meta) {+ DIDerivedType dt(md);+ meta->u.metaTypeInfo.context = translateMetadata(m, dt.getContext());+ meta->u.metaTypeInfo.name = getCStrdup(dt.getName());+ meta->u.metaTypeInfo.lineNumber = dt.getLineNumber();+ meta->u.metaTypeInfo.sizeInBits = dt.getSizeInBits();+ meta->u.metaTypeInfo.alignInBits = dt.getAlignInBits();+ meta->u.metaTypeInfo.offsetInBits = dt.getOffsetInBits();+ meta->u.metaTypeInfo.flags = dt.getFlags();+ meta->u.metaTypeInfo.isPrivate = dt.isPrivate();+ meta->u.metaTypeInfo.isProtected = dt.isProtected();+ meta->u.metaTypeInfo.isForward = dt.isForwardDecl();+ meta->u.metaTypeInfo.isByRefStruct = dt.isBlockByrefStruct();+ meta->u.metaTypeInfo.isVirtual = dt.isVirtual();+ meta->u.metaTypeInfo.isArtificial = dt.isArtificial();+ meta->u.metaTypeInfo.directory = getCStrdup(dt.getDirectory());+ meta->u.metaTypeInfo.filename = getCStrdup(dt.getFilename());++ meta->u.metaTypeInfo.typeDerivedFrom = translateMetadata(m, dt.getTypeDerivedFrom());+ meta->u.metaTypeInfo.originalTypeSize = dt.getOriginalTypeSize();+}++static void makeMetaCompositeType(CModule *m, const MDNode *md, CMeta *meta) {+ DICompositeType dt(md);+ meta->u.metaTypeInfo.context = translateMetadata(m, dt.getContext());+ meta->u.metaTypeInfo.name = getCStrdup(dt.getName());+ meta->u.metaTypeInfo.lineNumber = dt.getLineNumber();+ meta->u.metaTypeInfo.sizeInBits = dt.getSizeInBits();+ meta->u.metaTypeInfo.alignInBits = dt.getAlignInBits();+ meta->u.metaTypeInfo.offsetInBits = dt.getOffsetInBits();+ meta->u.metaTypeInfo.flags = dt.getFlags();+ meta->u.metaTypeInfo.isPrivate = dt.isPrivate();+ meta->u.metaTypeInfo.isProtected = dt.isProtected();+ meta->u.metaTypeInfo.isForward = dt.isForwardDecl();+ meta->u.metaTypeInfo.isByRefStruct = dt.isBlockByrefStruct();+ meta->u.metaTypeInfo.isVirtual = dt.isVirtual();+ meta->u.metaTypeInfo.isArtificial = dt.isArtificial();+ meta->u.metaTypeInfo.directory = getCStrdup(dt.getDirectory());+ meta->u.metaTypeInfo.filename = getCStrdup(dt.getFilename());++ meta->u.metaTypeInfo.typeDerivedFrom = translateMetadata(m, dt.getTypeDerivedFrom());+ meta->u.metaTypeInfo.originalTypeSize = dt.getOriginalTypeSize();++ meta->u.metaTypeInfo.typeArray = translateMetadataArray(m, dt.getTypeArray());+ meta->u.metaTypeInfo.runTimeLang = dt.getRunTimeLang();+ meta->u.metaTypeInfo.containingType = translateMetadata(m, dt.getContainingType());+ meta->u.metaTypeInfo.templateParams = translateMetadata(m, dt.getTemplateParams());+}++static void makeMetaBasicType(CModule *m, const MDNode *md, CMeta *meta) {+ DIBasicType dt(md);+ meta->u.metaTypeInfo.context = translateMetadata(m, dt.getContext());+ meta->u.metaTypeInfo.name = getCStrdup(dt.getName());+ meta->u.metaTypeInfo.lineNumber = dt.getLineNumber();+ meta->u.metaTypeInfo.sizeInBits = dt.getSizeInBits();+ meta->u.metaTypeInfo.alignInBits = dt.getAlignInBits();+ meta->u.metaTypeInfo.offsetInBits = dt.getOffsetInBits();+ meta->u.metaTypeInfo.flags = dt.getFlags();+ meta->u.metaTypeInfo.isPrivate = dt.isPrivate();+ meta->u.metaTypeInfo.isProtected = dt.isProtected();+ meta->u.metaTypeInfo.isForward = dt.isForwardDecl();+ meta->u.metaTypeInfo.isByRefStruct = dt.isBlockByrefStruct();+ meta->u.metaTypeInfo.isVirtual = dt.isVirtual();+ meta->u.metaTypeInfo.isArtificial = dt.isArtificial();+ meta->u.metaTypeInfo.directory = getCStrdup(dt.getDirectory());+ meta->u.metaTypeInfo.filename = getCStrdup(dt.getFilename());++ meta->u.metaTypeInfo.encoding = dt.getEncoding();+}++static void makeMetaVariable(CModule *m, const MDNode *md, CMeta *meta) {+ DIVariable dv(md);+ meta->u.metaVariableInfo.context = translateMetadata(m, dv.getContext());+ meta->u.metaVariableInfo.name = getCStrdup(dv.getName());+ meta->u.metaVariableInfo.lineNumber = dv.getLineNumber();+ meta->u.metaVariableInfo.argNumber = dv.getArgNumber();+ meta->u.metaVariableInfo.type = translateMetadata(m, dv.getType());+ meta->u.metaVariableInfo.isArtificial = dv.isArtificial();+ meta->u.metaVariableInfo.hasComplexAddress = dv.hasComplexAddress();+ meta->u.metaVariableInfo.numAddrElements = dv.getNumAddrElements();+ if(meta->u.metaVariableInfo.numAddrElements > 0) {+ meta->u.metaVariableInfo.addrElements =+ (uint64_t*)calloc(meta->u.metaVariableInfo.numAddrElements, sizeof(uint64_t));++ for(unsigned int i = 0; i < meta->u.metaVariableInfo.numAddrElements; ++i) {+ meta->u.metaVariableInfo.addrElements[i] = dv.getAddrElement(i);+ }+ }++ meta->u.metaVariableInfo.isBlockByRefVar = dv.isBlockByrefVariable();+}++static void makeMetaSubprogram(CModule *m, const MDNode *md, CMeta *meta) {+ DISubprogram ds(md);+ meta->u.metaSubprogramInfo.context = translateMetadata(m, ds.getContext());+ meta->u.metaSubprogramInfo.name = getCStrdup(ds.getName());+ meta->u.metaSubprogramInfo.displayName = getCStrdup(ds.getDisplayName());+ meta->u.metaSubprogramInfo.linkageName = getCStrdup(ds.getLinkageName());+ meta->u.metaSubprogramInfo.lineNumber = ds.getLineNumber();+ meta->u.metaSubprogramInfo.type = translateMetadata(m, ds.getType());+ meta->u.metaSubprogramInfo.returnTypeName = getCStrdup(ds.getReturnTypeName());+ meta->u.metaSubprogramInfo.isLocalToUnit = ds.isLocalToUnit();+ meta->u.metaSubprogramInfo.isDefinition = ds.isDefinition();+ meta->u.metaSubprogramInfo.virtuality = ds.getVirtuality();+ meta->u.metaSubprogramInfo.virtualIndex = ds.getVirtualIndex();+ meta->u.metaSubprogramInfo.containingType = translateMetadata(m, ds.getContainingType());+ meta->u.metaSubprogramInfo.isArtificial = ds.isArtificial();+ meta->u.metaSubprogramInfo.isPrivate = ds.isPrivate();+ meta->u.metaSubprogramInfo.isProtected = ds.isProtected();+ meta->u.metaSubprogramInfo.isExplicit = ds.isExplicit();+ meta->u.metaSubprogramInfo.isPrototyped = ds.isPrototyped();+ meta->u.metaSubprogramInfo.isOptimized = ds.isOptimized();+ meta->u.metaSubprogramInfo.filename = getCStrdup(ds.getFilename());+ meta->u.metaSubprogramInfo.directory = getCStrdup(ds.getDirectory());+ const Value *func = ds.getFunction();+ if(func)+ meta->u.metaSubprogramInfo.function = translateValue(m, func);+}++static void makeMetaGlobalVariable(CModule *m, const MDNode *md, CMeta *meta) {+ DIGlobalVariable dg(md);+ meta->u.metaGlobalInfo.context = translateMetadata(m, dg.getContext());+ meta->u.metaGlobalInfo.name = getCStrdup(dg.getName());+ meta->u.metaGlobalInfo.displayName = getCStrdup(dg.getDisplayName());+ meta->u.metaGlobalInfo.linkageName = getCStrdup(dg.getLinkageName());+ meta->u.metaGlobalInfo.lineNumber = dg.getLineNumber();+ meta->u.metaGlobalInfo.globalType = translateMetadata(m, dg.getType());+ meta->u.metaGlobalInfo.isLocalToUnit = dg.isLocalToUnit();+ meta->u.metaGlobalInfo.isDefinition = dg.isDefinition();+ const Value *global = dg.getConstant();+ if(global)+ meta->u.metaGlobalInfo.global = translateValue(m, global);+}++static void makeMetaFile(CModule *m, const MDNode *md, CMeta *meta) {+ DIFile df(md);+ meta->u.metaFileInfo.filename = getCStrdup(df.getFilename());+ meta->u.metaFileInfo.directory = getCStrdup(df.getDirectory());+}++static void makeMetaCompileUnit(CModule *m, const MDNode *md, CMeta *meta) {+ DICompileUnit dc(md);+ meta->u.metaCompileUnitInfo.language = dc.getLanguage();+ meta->u.metaCompileUnitInfo.filename = getCStrdup(dc.getFilename());+ meta->u.metaCompileUnitInfo.directory = getCStrdup(dc.getDirectory());+ meta->u.metaCompileUnitInfo.producer = getCStrdup(dc.getProducer());+#if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 3+#else+ meta->u.metaCompileUnitInfo.isMain = dc.isMain();+#endif+ meta->u.metaCompileUnitInfo.isOptimized = dc.isOptimized();+ meta->u.metaCompileUnitInfo.flags = getCStrdup(dc.getFlags());+ meta->u.metaCompileUnitInfo.runtimeVersion = dc.getRunTimeVersion();+ meta->u.metaCompileUnitInfo.enumTypes = translateMetadata(m, dc.getEnumTypes());+ meta->u.metaCompileUnitInfo.retainedTypes = translateMetadata(m, dc.getRetainedTypes());+ meta->u.metaCompileUnitInfo.subprograms = translateMetadata(m, dc.getSubprograms());+ meta->u.metaCompileUnitInfo.globalVariables = translateMetadata(m, dc.getGlobalVariables());+}++static void makeMetaNamespace(CModule *m, const MDNode *md, CMeta *meta) {+ DINameSpace dn(md);+ meta->u.metaNamespaceInfo.context = translateMetadata(m, dn.getContext());+ meta->u.metaNamespaceInfo.name = getCStrdup(dn.getName());+ meta->u.metaNamespaceInfo.directory = getCStrdup(dn.getDirectory());+ meta->u.metaNamespaceInfo.filename = getCStrdup(dn.getFilename());+ meta->u.metaNamespaceInfo.lineNumber = dn.getLineNumber();+}++static void makeMetaLexicalBlock(CModule *m, const MDNode *md, CMeta *meta) {+ DILexicalBlock dl(md);+ meta->u.metaLexicalBlockInfo.context = translateMetadata(m, dl.getContext());+ meta->u.metaLexicalBlockInfo.lineNumber = dl.getLineNumber();+ meta->u.metaLexicalBlockInfo.columnNumber = dl.getColumnNumber();+ meta->u.metaLexicalBlockInfo.directory = getCStrdup(dl.getDirectory());+ meta->u.metaLexicalBlockInfo.filename = getCStrdup(dl.getFilename());+}++static void makeMetaSubrange(CModule *, const MDNode *md, CMeta *meta) {+ DISubrange ds(md);+ meta->u.metaSubrangeInfo.lo = ds.getLo();+ meta->u.metaSubrangeInfo.hi = getHiDISubrange(ds);+}++static void makeMetaEnumerator(CModule *, const MDNode *md, CMeta *meta) {+ DIEnumerator de(md);+ meta->u.metaEnumeratorInfo.enumName = getCStrdup(de.getName());+ meta->u.metaEnumeratorInfo.enumValue = de.getEnumValue();+}++static void makeMetaArray(CModule *m, const MDNode *md, CMeta *meta) {+ DIArray da(md);+ meta->u.metaArrayInfo.arrayLen = da.getNumElements();+ if(meta->u.metaArrayInfo.arrayLen == 0) return;++ meta->u.metaArrayInfo.arrayElts =+ (CMeta**)calloc(meta->u.metaArrayInfo.arrayLen, sizeof(CMeta*));+ for(int i = 0; i < meta->u.metaArrayInfo.arrayLen; ++i) {+ meta->u.metaArrayInfo.arrayElts[i] = translateMetadata(m, da.getElement(i));+ }+}++static void makeMetaTemplateTypeParameter(CModule *m, const MDNode *md, CMeta *meta) {+ DITemplateTypeParameter dt(md);+ meta->u.metaTemplateTypeInfo.context = translateMetadata(m, dt.getContext());+ meta->u.metaTemplateTypeInfo.name = getCStrdup(dt.getName());+ meta->u.metaTemplateTypeInfo.type = translateMetadata(m, dt.getType());+ meta->u.metaTemplateTypeInfo.filename = getCStrdup(dt.getFilename());+ meta->u.metaTemplateTypeInfo.directory = getCStrdup(dt.getDirectory());+ meta->u.metaTemplateTypeInfo.lineNumber = dt.getLineNumber();+ meta->u.metaTemplateTypeInfo.columnNumber = dt.getColumnNumber();+}++static void makeMetaTemplateValueParameter(CModule *m, const MDNode *md, CMeta *meta) {+ DITemplateValueParameter dt(md);+ meta->u.metaTemplateValueInfo.context = translateMetadata(m, dt.getContext());+ meta->u.metaTemplateValueInfo.name = getCStrdup(dt.getName());+ meta->u.metaTemplateValueInfo.type = translateMetadata(m, dt.getType());+ meta->u.metaTemplateValueInfo.value = dt.getValue();+ meta->u.metaTemplateValueInfo.filename = getCStrdup(dt.getFilename());+ meta->u.metaTemplateValueInfo.directory = getCStrdup(dt.getDirectory());+ meta->u.metaTemplateValueInfo.lineNumber = dt.getLineNumber();+ meta->u.metaTemplateValueInfo.columnNumber = dt.getColumnNumber();+}++// Treat source locations specially; keeping them in the general case+// was causing crashes that I never managed to track down.+static CMeta* translateSrcLoc(CModule *m, const DebugLoc& loc) {+ if(loc.isUnknown()) return NULL;++ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const DebugLoc*,CMeta*>::const_iterator it = pd->srcLocMap.find(&loc);+ if(it != pd->srcLocMap.end()) {+ return it->second;+ }+ CMeta *meta = (CMeta*)calloc(1, sizeof(CMeta));+ pd->srcLocMap[&loc] = meta;+ meta->metaTag = META_LOCATION;+ // There is no DWARF tag for these source locations. Just use -1+ // and be sure not to try to convert it to a DWARF tag later.+ meta->tag = -1;++ makeMetaSrcLocation(m, loc, meta);++ return meta;+}++static CMeta* translateMetadata(CModule *m, const MDNode *md) {+ // I expect some metadata fields to be empty (e.g., templateParams).+ // Just propagate nulls.+ if(md == NULL) return NULL;++ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const MDNode*,CMeta*>::const_iterator it = pd->metaMap.find(md);+ if(it != pd->metaMap.end()) {+ return it->second;+ }+ CMeta *meta = (CMeta*)calloc(1, sizeof(CMeta));+ pd->metaMap[md] = meta;+ meta->metaTag = extractMetaTag(md);+ DIDescriptor desc(md);+ meta->tag = desc.getTag();++ switch(meta->metaTag) {+ case META_LOCATION: makeMetaLocation(m, md, meta); break;+ case META_DERIVEDTYPE: makeMetaDerivedType(m, md, meta); break;+ case META_COMPOSITETYPE: makeMetaCompositeType(m, md, meta); break;+ case META_BASICTYPE: makeMetaBasicType(m, md, meta); break;+ case META_VARIABLE: makeMetaVariable(m, md, meta); break;+ case META_SUBPROGRAM: makeMetaSubprogram(m, md, meta); break;+ case META_GLOBALVARIABLE: makeMetaGlobalVariable(m, md, meta); break;+ case META_COMPILEUNIT: makeMetaCompileUnit(m, md, meta); break;+ case META_NAMESPACE: makeMetaNamespace(m, md, meta); break;+ case META_LEXICALBLOCK: makeMetaLexicalBlock(m, md, meta); break;+ case META_SUBRANGE: makeMetaSubrange(m, md, meta); break;+ case META_ENUMERATOR: makeMetaEnumerator(m, md, meta); break;+// case META_ARRAY: makeMetaArray(m, md, meta); break;+ case META_TEMPLATETYPEPARAMETER: makeMetaTemplateTypeParameter(m, md, meta); break;+ case META_TEMPLATEVALUEPARAMETER: makeMetaTemplateValueParameter(m, md, meta); break;+ case META_UNKNOWN:+ {+ // Just dump unknown metadata to a string... it might be more+ // appropriate to make a generic MDNode, but that is low priority.+ string msg;+ raw_string_ostream os(msg);+ os << "Unhandled metadata node type: ";+ md->print(os);++ meta->u.metaUnknownInfo.repr = getCStrdup(os);+ break;+ }+ }+ return meta;+}++static CMeta* translateMetadataArray(CModule *m, const MDNode *md) {+ // I expect some metadata fields to be empty (e.g., templateParams).+ // Just propagate nulls.+ if(md == NULL) return NULL;++ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const MDNode*,CMeta*>::const_iterator it = pd->metaMap.find(md);+ if(it != pd->metaMap.end()) {+ return it->second;+ }+ CMeta *meta = (CMeta*)calloc(1, sizeof(CMeta));+ pd->metaMap[md] = meta;+ meta->metaTag = META_ARRAY;+ meta->tag = 0;++ makeMetaArray(m, md, meta);++ return meta;+}++// The Type parameter would be const, except+// DataLayout::getTypeSizeInBits() is not const for some reason.+static CType* translateType(CModule *m, Type *t) {+ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const Type*,CType*>::const_iterator it = pd->typeMap.find(t);+ if(it != pd->typeMap.end())+ return it->second;++ CType *ret = (CType*)calloc(1, sizeof(CType));+ ret->typeTag = decodeTypeTag(t->getTypeID());+ ret->sizeInBytes = 0;+ if(t->isSized())+ ret->sizeInBytes = std::ceil(pd->dataLayout->getTypeSizeInBits(t) / 8.0);++ // Need to put this in the table before making any recursive calls,+ // otherwise it might never terminate.+ pd->typeMap[t] = ret;++ switch(ret->typeTag) {+ // Primitives don't require any work+ case TYPE_VOID:+ case TYPE_FLOAT:+ case TYPE_DOUBLE:+ case TYPE_X86_FP80:+ case TYPE_FP128:+ case TYPE_PPC_FP128:+ case TYPE_LABEL:+ case TYPE_METADATA:+ case TYPE_X86_MMX:+ break;++ case TYPE_INTEGER:+ ret->size = t->getPrimitiveSizeInBits();+ break;++ case TYPE_FUNCTION:+ {+ const FunctionType *ft = dyn_cast<const FunctionType>(t);+ ret->isVarArg = ft->isVarArg();+ ret->innerType = translateType(m, ft->getReturnType());+ ret->typeListLen = ft->getNumParams();+ ret->typeList = (CType**)calloc(ret->typeListLen, sizeof(CType*));+ for(int i = 0; i < ret->typeListLen; ++i) {+ ret->typeList[i] = translateType(m, ft->getParamType(i));+ }++ break;+ }++ case TYPE_STRUCT:+ {+ const StructType *st = dyn_cast<const StructType>(t);+ if(st->hasName())+ ret->name = getCStrdup(st->getName());+ else+ ret->name = NULL;++ ret->isPacked = st->isPacked();+ ret->typeListLen = st->getNumElements();+ ret->typeList = (CType**)calloc(ret->typeListLen, sizeof(CType*));+ for(int i = 0; i < ret->typeListLen; ++i) {+ ret->typeList[i] = translateType(m, st->getElementType(i));+ }+ break;+ }++ case TYPE_ARRAY:+ {+ const ArrayType *at = dyn_cast<const ArrayType>(t);+ ret->size = at->getNumElements();+ ret->innerType = translateType(m, at->getElementType());+ break;+ }++ case TYPE_POINTER:+ {+ const PointerType *pt = dyn_cast<const PointerType>(t);+ ret->innerType = translateType(m, pt->getElementType());+ ret->addrSpace = pt->getAddressSpace();+ break;+ }++ case TYPE_VECTOR:+ {+ const VectorType *vt = dyn_cast<const VectorType>(t);+ ret->size = vt->getNumElements();+ ret->innerType = translateType(m, vt->getElementType());+ break;+ }+ }++ return ret;+}++static CValue* translateGlobalAlias(CModule *m, const GlobalAlias *ga) {+ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const Value*, CValue*>::iterator it = pd->valueMap.find(ga);+ if(it != pd->valueMap.end())+ return it->second;++ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[ga] = v;++ v->valueTag = VAL_ALIAS;+ v->valueType = translateType(m, ga->getType());+ v->name = getCStrdup(ga->getName());++ CGlobalInfo *gi = (CGlobalInfo*)calloc(1, sizeof(CGlobalInfo));+ v->data = (void*)gi;++ gi->isExternal = ga->isDeclaration();+ gi->alignment = ga->getAlignment();+ gi->visibility = decodeVisibility(ga);+ gi->linkage = decodeLinkage(ga);+ if(ga->hasSection())+ gi->section = getCStrdup(ga->getSection());++ gi->aliasee = translateConstant(m, ga->getAliasee());++ return v;+}++static CValue* translateArgument(CModule *m, const Argument *a) {+ PrivateData *pd = (PrivateData*)m->privateData;+ // Arguments are translated before instructions, so we don't really+ // need to check to see if the argument exists already (it won't).+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[a] = v;++ v->valueTag = VAL_ARGUMENT;+ v->valueType = translateType(m, a->getType());+ v->name = getCStrdup(a->getName());++ // Metadata will be attached as instructions are processed (calls to+ // the Debug intrinsics)++ CArgumentInfo *ai = (CArgumentInfo*)calloc(1, sizeof(CArgumentInfo));+ v->data = (void*)ai;++ ai->hasSRet = a->hasStructRetAttr();+ ai->hasByVal = a->hasByValAttr();+ ai->hasNest = a->hasNestAttr();+ ai->hasNoAlias = a->hasNoAliasAttr();+ ai->hasNoCapture = a->hasNoCaptureAttr();++ return v;+}++static void buildRetInst(CModule *m, CValue *v, const ReturnInst *ri) {+ v->valueTag = VAL_RETINST;+ v->valueType = translateType(m, ri->getType());+ // Never has a name++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;++ if(Value* rv = ri->getReturnValue())+ {+ ii->numOperands = 1;+ ii->operands = (CValue**)calloc(1, sizeof(CValue*));+ ii->operands[0] = translateValue(m, rv);+ }++ // Otherwise, the data fields default to 0 as intended+}++static void buildSimpleInst(CModule *m, CValue *v, ValueTag t, const Instruction *inst) {+ v->valueTag = t;+ v->valueType = translateType(m, inst->getType());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;++ ii->numOperands = inst->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));++ for(size_t i = 0; i < inst->getNumOperands(); ++i) {+ ii->operands[i] = translateValue(m, inst->getOperand(i));+ }+}++static void buildBinaryInst(CModule *m, CValue *v, ValueTag t, const Instruction *inst) {+ const BinaryOperator *bi = dyn_cast<const BinaryOperator>(inst);+ assert(bi);++ v->valueTag = t;+ v->valueType = translateType(m, bi->getType());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;++ ii->numOperands = inst->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, inst->getOperand(i));+ }++ ii->flags = ArithNone;+ // If the operator isn't *really* an overflowing binary operator,+ // calling hasNoUnsignedWrap causes an assertion failure. Guard+ // against leaky abstractions here.+ if(isa<const OverflowingBinaryOperator>(bi))+ {+ if(bi->hasNoUnsignedWrap() && bi->hasNoSignedWrap())+ ii->flags = ArithBoth;+ else if(bi->hasNoUnsignedWrap())+ ii->flags = ArithNUW;+ else if(bi->hasNoSignedWrap())+ ii->flags = ArithNSW;+ }+}++static void buildInvokeInst(CModule *m, CValue *v, const InvokeInst *ii) {+ v->valueTag = VAL_INVOKEINST;+ v->valueType = translateType(m, ii->getType());+ if(ii->hasName())+ v->name = getCStrdup(ii->getName());++ CCallInfo *ci = (CCallInfo*)calloc(1, sizeof(CCallInfo));+ v->data = (void*)ci;++ ci->calledValue = translateValue(m, ii->getCalledValue());+ ci->callingConvention = decodeCallingConvention(ii->getCallingConv());+ ci->hasSRet = ii->hasStructRetAttr();+ ci->normalDest = translateBasicBlock(m, ii->getNormalDest());+ ci->unwindDest = translateBasicBlock(m, ii->getUnwindDest());+ ci->argListLen = ii->getNumArgOperands();+ ci->arguments = (CValue**)calloc(ci->argListLen, sizeof(CValue*));++ for(unsigned i = 0; i < ii->getNumArgOperands(); ++i) {+ ci->arguments[i] = translateValue(m, ii->getArgOperand(i));+ }+}++static bool buildCallInst(CModule *m, CValue *v, const CallInst *ii) {++ /*+ I wanted to use the Intrinsics directly here, but it didn't seem+ to work. I didn't look into the matter too closely, but these+ instructions insisted that they were simply calls and I didn't+ know how to convert them to intrinsics.+ */++ if(ii->getCalledValue()->getName().str() == "llvm.dbg.declare") {+ CValue *addr = NULL;+ if(const MDNode *addrWrapper = dyn_cast<const MDNode>(ii->getArgOperand(0))) {+ const Value* realAddr = addrWrapper->getOperand(0);+ // If the alloca was completely eliminated, this debug+ // information can't be attached to anything as far as I can+ // tell.+ if(realAddr == NULL || dyn_cast<const ConstantPointerNull>(realAddr))+ return false;++ addr = translateValue(m, realAddr);+ }+ CMeta *md = NULL;+ if(const MDNode *variableVal = dyn_cast<const MDNode>(ii->getArgOperand(1))) {+ md = translateMetadata(m, variableVal);+ }++ if(!md) return false;++ // CValue *addr = translateValue(m, di->getAddress());+ // CMeta *md = translateMetadata(m, di->getVariable());++ // It should be the case that there should be exactly one of these+ // per alloca, and allocas should not have location info of their+ // own.+ if(addr->md) {+ return false;+ } // throw "Address of MD already has metadata";++ addr->numMetadata = 1;+ addr->md = (CMeta**)calloc(1, sizeof(CMeta*));+ addr->md[0] = md;++ return false;+ }++ if(ii->getCalledValue()->getName().str() == "llvm.dbg.value") {+ // In this case, we could see llvm.dbg.value "calls" for updates+ // to parameters. We should only attach the *first* one we+ // encounter, which will be the one describing parameters or+ // locals. This is an important case when the bitcode has been+ // run through the mem2reg optimization pass and most allocas are+ // eliminated. I don't care about when the value of a variable+ // changes (that is apparent from the instruction stream). I+ // could be convinced to change the behavior here if there is a+ // good use case.++ CValue *val = NULL;+ if(const MDNode *valWrapper = dyn_cast<const MDNode>(ii->getArgOperand(0))) {+ const Value *realAddr = valWrapper->getOperand(0);+ if(realAddr == NULL || dyn_cast<const ConstantPointerNull>(realAddr))+ return false;++ val = translateValue(m, realAddr);+ }++ if(val->numMetadata == 0) {+ CMeta *md = NULL;+ if(const MDNode *variable = dyn_cast<const MDNode>(ii->getArgOperand(2))) {+ md = translateMetadata(m, variable);+ }++ if(!md) return false;++ val->numMetadata = 1;+ val->md = (CMeta**)calloc(1, sizeof(CMeta*));+ val->md[0] = md;+ }++ return false;+ }++ v->valueTag = VAL_CALLINST;+ v->valueType = translateType(m, ii->getType());+ if(ii->hasName())+ v->name = getCStrdup(ii->getName());++ CCallInfo *ci = (CCallInfo*)calloc(1, sizeof(CCallInfo));+ v->data = (void*)ci;++ ci->calledValue = translateValue(m, ii->getCalledValue());+ ci->callingConvention = decodeCallingConvention(ii->getCallingConv());+ ci->hasSRet = ii->hasStructRetAttr();+ ci->isTail = ii->isTailCall();+ ci->argListLen = ii->getNumArgOperands();+ ci->arguments = (CValue**)calloc(ci->argListLen, sizeof(CValue*));++ for(unsigned i = 0; i < ii->getNumArgOperands(); ++i) {+ ci->arguments[i] = translateValue(m, ii->getArgOperand(i));+ }++ return true;+}++static void buildAllocaInst(CModule *m, CValue *v, const AllocaInst *ai) {+ v->valueTag = VAL_ALLOCAINST;+ v->valueType = translateType(m, ai->getType());+ if(ai->hasName())+ v->name = getCStrdup(ai->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;++ ii->numOperands = ai->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, ai->getOperand(i));+ }++ ii->align = ai->getAlignment();+}++static void buildLoadInst(CModule *m, CValue *v, const LoadInst *li) {+ v->valueTag = VAL_LOADINST;+ v->valueType = translateType(m, li->getType());+ if(li->hasName())+ v->name = getCStrdup(li->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;++ ii->numOperands = li->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, li->getOperand(i));+ }++ ii->isVolatile = li->isVolatile();+ ii->align = li->getAlignment();+ ii->addrSpace = li->getPointerAddressSpace();+}++static void buildStoreInst(CModule *m, CValue *v, const StoreInst *si) {+ v->valueTag = VAL_STOREINST;+ v->valueType = translateType(m, si->getType());+ if(si->hasName())+ v->name = getCStrdup(si->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;+++ ii->numOperands = si->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, si->getOperand(i));+ }++ ii->addrSpace = si->getPointerAddressSpace();+ ii->align = si->getAlignment();+ ii->isVolatile = si->isVolatile();+}++static void buildGEPInst(CModule *m, CValue *v, const GetElementPtrInst *gi) {+ v->valueTag = VAL_GETELEMENTPTRINST;+ v->valueType = translateType(m, gi->getType());+ if(gi->hasName())+ v->name = getCStrdup(gi->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;+++ ii->numOperands = gi->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, gi->getOperand(i));+ }++ ii->inBounds = gi->isInBounds();+ ii->addrSpace = gi->getPointerAddressSpace();+}++static void buildCastInst(CModule *m, CValue *v, ValueTag t, const Instruction *inst) {+ const CastInst *ci = dyn_cast<const CastInst>(inst);+ v->valueTag = t;+ v->valueType = translateType(m, ci->getType());+ if(ci->hasName())+ v->name = getCStrdup(ci->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;+++ ii->numOperands = ci->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, ci->getOperand(i));+ }+}++static void buildCmpInst(CModule *m, CValue *v, ValueTag t, const Instruction *inst) {+ const CmpInst *ci = dyn_cast<const CmpInst>(inst);+ v->valueTag = t;+ v->valueType = translateType(m, ci->getType());+ if(ci->hasName())+ v->name = getCStrdup(ci->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;++ ii->numOperands = ci->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, ci->getOperand(i));+ }++ ii->cmpPred = decodePredicate(ci->getPredicate());+}++static void buildPHINode(CModule *m, CValue *v, const PHINode* n) {+ v->valueTag = VAL_PHINODE;+ v->valueType = translateType(m, n->getType());+ if(n->hasName())+ v->name = getCStrdup(n->getName());++ CPHIInfo *pi = (CPHIInfo*)calloc(1, sizeof(CPHIInfo));+ v->data = (void*)pi;++ pi->numIncomingValues = n->getNumIncomingValues();+ pi->incomingValues = (CValue**)calloc(pi->numIncomingValues, sizeof(CValue*));+ pi->valueBlocks = (CValue**)calloc(pi->numIncomingValues, sizeof(CValue*));++ for(int i = 0; i < pi->numIncomingValues; ++i) {+ pi->incomingValues[i] = translateValue(m, n->getIncomingValue(i));+ pi->valueBlocks[i] = translateValue(m, n->getIncomingBlock(i));+ }+}++static void buildAtomicRMWInst(CModule *m, CValue *v, const AtomicRMWInst *I) {+ v->valueTag = VAL_ATOMICRMWINST;+ v->valueType = translateType(m, I->getType());+ // Should not have a name++ CAtomicInfo *ai = (CAtomicInfo*)calloc(1, sizeof(CAtomicInfo));+ v->data = (void*)ai;++ ai->ordering = decodeOrdering(I->getOrdering());+ ai->scope = decodeSynchScope(I->getSynchScope());+ ai->operation = decodeAtomicOp(I->getOperation());+ ai->isVolatile = I->isVolatile();+ ai->addrSpace = I->getPointerAddressSpace();+ ai->pointerOperand = translateValue(m, I->getPointerOperand());+ ai->valueOperand = translateValue(m, I->getValOperand());+}++static void buildAtomicCmpXchgInst(CModule *m, CValue *v, const AtomicCmpXchgInst *I) {+ v->valueTag = VAL_ATOMICCMPXCHGINST;+ v->valueType = translateType(m, I->getType());+ // Should not have a name++ CAtomicInfo *ai = (CAtomicInfo*)calloc(1, sizeof(CAtomicInfo));+ v->data = (void*)ai;++ ai->ordering = decodeOrdering(I->getOrdering());+ ai->scope = decodeSynchScope(I->getSynchScope());+ ai->isVolatile = I->isVolatile();+ ai->addrSpace = I->getPointerAddressSpace();+ ai->pointerOperand = translateValue(m, I->getPointerOperand());+ ai->compareOperand = translateValue(m, I->getCompareOperand());+ ai->valueOperand = translateValue(m, I->getNewValOperand());+}++static void buildFenceInst(CModule *m, CValue *v, const FenceInst *I) {+ v->valueTag = VAL_FENCEINST;+ v->valueType = translateType(m, I->getType());+ // Should not have a name++ CAtomicInfo *ai = (CAtomicInfo*)calloc(1, sizeof(CAtomicInfo));+ v->data = (void*)ai;++ ai->ordering = decodeOrdering(I->getOrdering());+ ai->scope = decodeSynchScope(I->getSynchScope());+}++static void buildVAArgInst(CModule *m, CValue *v, const VAArgInst *vi) {+ v->valueTag = VAL_VAARGINST;+ v->valueType = translateType(m, vi->getType());+ if(vi->hasName())+ v->name = getCStrdup(vi->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;++ ii->numOperands = vi->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, vi->getOperand(i));+ }+}++static void buildLandingPadInst(CModule *m, CValue *v, const LandingPadInst *li) {+ v->valueTag = VAL_LANDINGPADINST;+ v->valueType = translateType(m, li->getType());++ if(li->hasName())+ v->name = getCStrdup(li->getName());++ CLandingPadInfo *ii = (CLandingPadInfo*)calloc(1, sizeof(CLandingPadInfo));+ v->data = (void*)ii;++ ii->personality = translateValue(m, li->getPersonalityFn());+ ii->isCleanup = li->isCleanup();+ ii->numClauses = li->getNumClauses();+ ii->clauses = (CValue**)calloc(ii->numClauses, sizeof(CValue*));+ ii->clauseTypes = (LandingPadClause*)calloc(ii->numClauses, sizeof(LandingPadClause));++ for(int i = 0; i < ii->numClauses; ++i) {+ ii->clauses[i] = translateValue(m, li->getClause(i));+ ii->clauseTypes[i] = li->isCatch(i) ? LPCatch : LPFilter;+ }+}++static void buildExtractValueInst(CModule *m, CValue *v, const ExtractValueInst *ei) {+ v->valueTag = VAL_EXTRACTVALUEINST;+ v->valueType = translateType(m, ei->getType());+ if(ei->hasName())+ v->name = getCStrdup(ei->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;+++ ii->numOperands = ei->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, ei->getOperand(i));+ }++ ii->numIndices = ei->getNumIndices();+ ii->indices = (int*)calloc(ii->numIndices, sizeof(int));++ std::copy(ei->idx_begin(), ei->idx_end(), ii->indices);+}++static void buildInsertValueInst(CModule *m, CValue *v, const InsertValueInst *ei) {+ v->valueTag = VAL_INSERTVALUEINST;+ v->valueType = translateType(m, ei->getType());+ if(ei->hasName())+ v->name = getCStrdup(ei->getName());++ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ii;++ ii->numOperands = ei->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));+ for(int i = 0; i < ii->numOperands; ++i) {+ ii->operands[i] = translateValue(m, ei->getOperand(i));+ }++ ii->numIndices = ei->getNumIndices();+ ii->indices = (int*)calloc(ii->numIndices, sizeof(int));++ std::copy(ei->idx_begin(), ei->idx_end(), ii->indices);+}++namespace {+ class TinyVector : public SmallVectorImpl<std::pair<unsigned, MDNode*> > {+ public:+ TinyVector(unsigned int i)+ :SmallVectorImpl<std::pair<unsigned, MDNode*> >(i)+ {+ }+ };+}++static CValue* translateInstruction(CModule *m, const Instruction *i) {+ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const Value*, CValue*>::iterator it = pd->valueMap.find(i);+ if(it != pd->valueMap.end())+ return it->second;++ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[i] = v;++ TinyVector md(0);+ i->getAllMetadataOtherThanDebugLoc(md);++ v->numMetadata = md.size();+ v->md = (CMeta**)calloc(v->numMetadata, sizeof(CMeta*));+ for(int ix = 0; ix < v->numMetadata; ++ix) {+ v->md[ix] = translateMetadata(m, md[ix].second);+ }+ if(pd->includeLocs)+ v->srcLoc = translateSrcLoc(m, i->getDebugLoc());++ switch(i->getOpcode()) {+ // Terminator instructions+ case Instruction::Ret:+ buildRetInst(m, v, dyn_cast<const ReturnInst>(i));+ break;+ case Instruction::Br:+ buildSimpleInst(m, v, VAL_BRANCHINST, i);+ break;+ case Instruction::Switch:+ buildSimpleInst(m, v, VAL_SWITCHINST, i);+ break;+ case Instruction::IndirectBr:+ buildSimpleInst(m, v, VAL_INDIRECTBRINST, i);+ break;+ case Instruction::Invoke:+ buildInvokeInst(m, v, dyn_cast<const InvokeInst>(i));+ break;+ case Instruction::Unreachable:+ buildSimpleInst(m, v, VAL_UNREACHABLEINST, i);+ break;++ // Binary instructions+ case Instruction::Add:+ buildBinaryInst(m, v, VAL_ADDINST, i);+ break;+ case Instruction::FAdd:+ buildBinaryInst(m, v, VAL_FADDINST, i);+ break;+ case Instruction::Sub:+ buildBinaryInst(m, v, VAL_SUBINST, i);+ break;+ case Instruction::FSub:+ buildBinaryInst(m, v, VAL_FSUBINST, i);+ break;+ case Instruction::Mul:+ buildBinaryInst(m, v, VAL_MULINST, i);+ break;+ case Instruction::FMul:+ buildBinaryInst(m, v, VAL_FMULINST, i);+ break;+ case Instruction::UDiv:+ buildBinaryInst(m, v, VAL_UDIVINST, i);+ break;+ case Instruction::SDiv:+ buildBinaryInst(m, v, VAL_SDIVINST, i);+ break;+ case Instruction::FDiv:+ buildBinaryInst(m, v, VAL_FDIVINST, i);+ break;+ case Instruction::URem:+ buildBinaryInst(m, v, VAL_UREMINST, i);+ break;+ case Instruction::SRem:+ buildBinaryInst(m, v, VAL_SREMINST, i);+ break;+ case Instruction::FRem:+ buildBinaryInst(m, v, VAL_FREMINST, i);+ break;+ case Instruction::Shl:+ buildBinaryInst(m, v, VAL_SHLINST, i);+ break;+ case Instruction::LShr:+ buildBinaryInst(m, v, VAL_LSHRINST, i);+ break;+ case Instruction::AShr:+ buildBinaryInst(m, v, VAL_ASHRINST, i);+ break;+ case Instruction::And:+ buildBinaryInst(m, v, VAL_ANDINST, i);+ break;+ case Instruction::Or:+ buildBinaryInst(m, v, VAL_ORINST, i);+ break;+ case Instruction::Xor:+ buildBinaryInst(m, v, VAL_XORINST, i);+ break;++ // Memory operations+ case Instruction::Alloca:+ buildAllocaInst(m, v, dyn_cast<const AllocaInst>(i));+ break;++ case Instruction::Load:+ buildLoadInst(m, v, dyn_cast<const LoadInst>(i));+ break;++ case Instruction::Store:+ buildStoreInst(m, v, dyn_cast<const StoreInst>(i));+ break;++ case Instruction::GetElementPtr:+ buildGEPInst(m, v, dyn_cast<const GetElementPtrInst>(i));+ break;++ case Instruction::Fence:+ buildFenceInst(m, v, dyn_cast<const FenceInst>(i));+ break;++ case Instruction::AtomicRMW:+ buildAtomicRMWInst(m, v, dyn_cast<const AtomicRMWInst>(i));+ break;++ case Instruction::AtomicCmpXchg:+ buildAtomicCmpXchgInst(m, v, dyn_cast<const AtomicCmpXchgInst>(i));+ break;++ // Casts+ case Instruction::Trunc:+ buildCastInst(m, v, VAL_TRUNCINST, i);+ break;++ case Instruction::ZExt:+ buildCastInst(m, v, VAL_ZEXTINST, i);+ break;++ case Instruction::SExt:+ buildCastInst(m, v, VAL_SEXTINST, i);+ break;++ case Instruction::FPToUI:+ buildCastInst(m, v, VAL_FPTOUIINST, i);+ break;++ case Instruction::FPToSI:+ buildCastInst(m, v, VAL_FPTOSIINST, i);+ break;++ case Instruction::UIToFP:+ buildCastInst(m, v, VAL_UITOFPINST, i);+ break;++ case Instruction::SIToFP:+ buildCastInst(m, v, VAL_SITOFPINST, i);+ break;++ case Instruction::FPTrunc:+ buildCastInst(m, v, VAL_FPTRUNCINST, i);+ break;++ case Instruction::FPExt:+ buildCastInst(m, v, VAL_FPEXTINST, i);+ break;++ case Instruction::PtrToInt:+ buildCastInst(m, v, VAL_PTRTOINTINST, i);+ break;++ case Instruction::IntToPtr:+ buildCastInst(m, v, VAL_INTTOPTRINST, i);+ break;++ case Instruction::BitCast:+ buildCastInst(m, v, VAL_BITCASTINST, i);+ break;++ // Other instructions+ case Instruction::ICmp:+ buildCmpInst(m, v, VAL_ICMPINST, i);+ break;++ case Instruction::FCmp:+ buildCmpInst(m, v, VAL_FCMPINST, i);+ break;++ case Instruction::PHI:+ buildPHINode(m, v, dyn_cast<const PHINode>(i));+ break;++ case Instruction::Call:+ // If this is a call to llvm.dbg.*, return NULL and delete what we+ // made so far. We don't want these in the instruction stream+ // (the builder will attach the debug information to the relevant+ // entities)+ if(!buildCallInst(m, v, dyn_cast<const CallInst>(i))) {+ pd->valueMap.erase(i);+ free(v);+ return NULL;+ }+ break;++ case Instruction::Select:+ buildSimpleInst(m, v, VAL_SELECTINST, i);+ break;++ case Instruction::Resume:+ buildSimpleInst(m, v, VAL_RESUMEINST, i);+ break;++ case Instruction::VAArg:+ buildVAArgInst(m, v, dyn_cast<const VAArgInst>(i));+ break;++ case Instruction::ExtractElement:+ buildSimpleInst(m, v, VAL_EXTRACTELEMENTINST, i);+ break;++ case Instruction::InsertElement:+ buildSimpleInst(m, v, VAL_INSERTELEMENTINST, i);+ break;++ case Instruction::ShuffleVector:+ buildSimpleInst(m, v, VAL_SHUFFLEVECTORINST, i);+ break;++ case Instruction::ExtractValue:+ buildExtractValueInst(m, v, dyn_cast<const ExtractValueInst>(i));+ break;++ case Instruction::InsertValue:+ buildInsertValueInst(m, v, dyn_cast<const InsertValueInst>(i));+ break;++ case Instruction::LandingPad:+ buildLandingPadInst(m, v, dyn_cast<const LandingPadInst>(i));+ break;++ default:+ {+ ostringstream os;+ os << "Unhandled instruction type: " << i->getOpcode();+ throw os.str();+ }+ }++ return v;+}++static CValue* translateBasicBlock(CModule *m, const BasicBlock *bb) {+ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const Value*, CValue*>::iterator it = pd->valueMap.find(bb);+ if(it != pd->valueMap.end())+ return it->second;++ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[bb] = v;++ v->valueTag = VAL_BASICBLOCK;+ v->valueType = translateType(m, bb->getType());+ if(bb->hasName())+ v->name = getCStrdup(bb->getName());++ // No metadata for these++ CBasicBlockInfo* bbi = (CBasicBlockInfo*)calloc(1, sizeof(CBasicBlockInfo));+ v->data = (void*)bbi;++ bbi->blockLen = bb->size();+ bbi->instructions = (CValue**)calloc(bbi->blockLen, sizeof(CValue*));++ int idx = 0;+ for(BasicBlock::const_iterator it = bb->begin(),+ ed = bb->end(); it != ed; ++it)+ {+ CValue *tr = translateInstruction(m, &*it);+ if(!tr) {+ // This was a metadata call, so do not insert it into the+ // instruction stream+ --bbi->blockLen;+ continue;+ }++ bbi->instructions[idx++] = tr;+ }++ return v;+}++static CValue* translateFunction(CModule *m, const Function *f) {+ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const Value*, CValue*>::iterator it = pd->valueMap.find(f);+ if(it != pd->valueMap.end())+ return it->second;++ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[f] = v;++ v->valueTag = VAL_FUNCTION;+ v->valueType = translateType(m, f->getFunctionType());+ v->name = getCStrdup(f->getName());++ CFunctionInfo *fi = (CFunctionInfo*)calloc(1, sizeof(CFunctionInfo));+ v->data = (void*)fi;++ if(f->hasSection())+ fi->section = getCStrdup(f->getSection());++ fi->visibility = decodeVisibility(f);+ fi->linkage = decodeLinkage(f);+ fi->isExternal = f->isDeclaration();+ fi->callingConvention = decodeCallingConvention(f->getCallingConv());+ fi->isVarArg = f->isVarArg();+ if(f->hasGC())+ fi->gcName = getCStrdup(f->getGC());++ fi->argListLen = f->arg_size();+ fi->arguments = (CValue**)calloc(fi->argListLen, sizeof(CValue*));+ int idx = 0;+ for(Function::const_arg_iterator it = f->arg_begin(),+ ed = f->arg_end(); it != ed; ++it)+ {+ fi->arguments[idx++] = translateArgument(m, &*it);+ }++ fi->blockListLen = f->size();+ fi->body = (CValue**)calloc(fi->blockListLen, sizeof(CValue*));+ idx = 0;+ for(Function::const_iterator it = f->begin(),+ ed = f->end(); it != ed; ++it)+ {+ fi->body[idx++] = translateBasicBlock(m, &*it);+ }++ return v;+}++static CValue* translateGlobalVariable(CModule *m, const GlobalVariable *gv) {+ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const Value*, CValue*>::iterator it = pd->valueMap.find(gv);+ if(it != pd->valueMap.end())+ return it->second;++ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[gv] = v;++ v->valueTag = VAL_GLOBALVARIABLE;+ v->valueType = translateType(m, gv->getType());+ if(gv->hasName())+ v->name = getCStrdup(gv->getName());++ CGlobalInfo *gi = (CGlobalInfo*)calloc(1, sizeof(CGlobalInfo));+ v->data = (void*)gi;++ if(gv->hasSection())+ gi->section = getCStrdup(gv->getSection());++ gi->visibility = decodeVisibility(gv);+ gi->linkage = decodeLinkage(gv);+ gi->isExternal = gv->isDeclaration();+ gi->isThreadLocal = gv->isThreadLocal();+ gi->isConstant = gv->isConstant();++ if(gv->hasInitializer())+ gi->initializer = translateConstant(m, gv->getInitializer());++ return v;+}++static CValue* translateInlineAsm(CModule *m, const InlineAsm* a) {+ PrivateData *pd = (PrivateData*)m->privateData;+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[a] = v;++ v->valueTag = VAL_INLINEASM;+ v->valueType = translateType(m, a->getType());+ if(a->hasName())+ v->name = getCStrdup(a->getName());++ CInlineAsmInfo *ii = (CInlineAsmInfo*)calloc(1, sizeof(CInlineAsmInfo));+ v->data = (void*)ii;++ ii->asmString = getCStrdup(a->getAsmString());+ ii->constraintString = getCStrdup(a->getConstraintString());++ return v;+}++static CValue* translateGlobalValue(CModule *m, const GlobalValue *gv) {+ if(const Function *f = dyn_cast<const Function>(gv)) {+ return translateFunction(m, f);+ }++ if(const GlobalVariable *v = dyn_cast<const GlobalVariable>(gv)) {+ return translateGlobalVariable(m, v);+ }++ if(const GlobalAlias *a = dyn_cast<const GlobalAlias>(gv)) {+ return translateGlobalAlias(m, a);+ }++ string msg;+ raw_string_ostream os(msg);+ os << "Non-global constant: ";+ gv->print(os);+ throw os.str();+}++static CValue* translateEmptyConstant(CModule *m, ValueTag t, const Constant *p) {+ PrivateData *pd = (PrivateData*)m->privateData;+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[p] = v;++ v->valueTag = t;+ v->valueType = translateType(m, p->getType());++ // No data or metadata++ return v;+}++static CValue* translateConstantInt(CModule *m, const ConstantInt* i) {+ PrivateData *pd = (PrivateData*)m->privateData;+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[i] = v;++ v->valueTag = VAL_CONSTANTINT;+ v->valueType = translateType(m, i->getType());++ // No name++ CConstInt *d = (CConstInt*)calloc(1, sizeof(CConstInt));+ v->data = (void*)d;++ const APInt& apint = i->getValue();+ d->hugeVal = NULL;+ if(apint.getMinSignedBits() <= 64)+ d->val = i->getSExtValue();+ else+ d->hugeVal = getCStrdup(apint.toString(10, true));+ return v;+}++static CValue* translateConstantFP(CModule *m, const ConstantFP *fp) {+ PrivateData *pd = (PrivateData*)m->privateData;+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[fp] = v;++ v->valueTag = VAL_CONSTANTFP;+ v->valueType = translateType(m, fp->getType());++ // No name++ CConstFP *d = (CConstFP*)calloc(1, sizeof(CConstFP));+ v->data = (void*)d;++ APFloat apf = fp->getValueAPF();+ bool b;+ apf.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &b);+ d->val = apf.convertToDouble();++ return v;+}++static CValue* translateBlockAddress(CModule *m, const BlockAddress *ba) {+ PrivateData *pd = (PrivateData*)m->privateData;+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[ba] = v;++ v->valueTag = VAL_BLOCKADDRESS;+ v->valueType = translateType(m, ba->getType());+ if(ba->hasName())+ v->name = getCStrdup(ba->getName());++ CBlockAddrInfo *i = (CBlockAddrInfo*)calloc(1, sizeof(CBlockAddrInfo));+ v->data = (void*)i;++ i->func = translateValue(m, ba->getFunction());+ i->block = translateValue(m, ba->getBasicBlock());++ return v;+}++static CValue* translateConstantAggregate(CModule *m, ValueTag t, const Constant *ca) {+ PrivateData *pd = (PrivateData*)m->privateData;+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[ca] = v;++ v->valueTag = t;+ v->valueType = translateType(m, ca->getType());+ if(ca->hasName())+ v->name = getCStrdup(ca->getName());++ CConstAggregate *a = (CConstAggregate*)calloc(1, sizeof(CConstAggregate));+ v->data = (void*)a;++ a->numElements = ca->getNumOperands();+ a->constants = (CValue**)calloc(a->numElements, sizeof(CValue*));++ int idx = 0;+ for(User::const_op_iterator it = ca->op_begin(),+ ed = ca->op_end(); it != ed; ++it)+ {+ a->constants[idx++] = translateValue(m, it->get());+ }++ return v;+}++#if defined(LLVM_VERSION_MAJOR)+static CValue* translateConstantData(CModule *m, const ConstantDataSequential *cd) {+ PrivateData *pd = (PrivateData*)m->privateData;+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[cd] = v;++ v->valueTag = VAL_CONSTANTARRAY;+ v->valueType = translateType(m, cd->getType());+ if(cd->hasName())+ v->name = getCStrdup(cd->getName());++ CConstAggregate *a = (CConstAggregate*)calloc(1, sizeof(CConstAggregate));+ v->data = (void*)a;++ a->numElements = cd->getNumElements();+ a->constants = (CValue**)calloc(a->numElements, sizeof(CValue*));++ for(int idx = 0; idx < a->numElements; ++idx) {+ a->constants[idx] = translateConstant(m, cd->getElementAsConstant(idx));+ }++ return v;+}+#endif // LLVM_VERSION_MAJOR++static CValue* translateConstantExpr(CModule *m, const ConstantExpr *ce) {+ PrivateData *pd = (PrivateData*)m->privateData;+ CValue *v = (CValue*)calloc(1, sizeof(CValue));+ pd->valueMap[ce] = v;++ v->valueTag = VAL_CONSTANTEXPR;+ v->valueType = translateType(m, ce->getType());+ if(ce->hasName())+ v->name = getCStrdup(ce->getName());++ CConstExprInfo *ci = (CConstExprInfo*)calloc(1, sizeof(CConstExprInfo));+ CInstructionInfo *ii = (CInstructionInfo*)calloc(1, sizeof(CInstructionInfo));+ v->data = (void*)ci;+ ci->ii = ii;++ ci->instrType = decodeOpcode(ce->getOpcode());+ ii->numOperands = ce->getNumOperands();+ ii->operands = (CValue**)calloc(ii->numOperands, sizeof(CValue*));++ int idx = 0;+ for(User::const_op_iterator it = ce->op_begin(),+ ed = ce->op_end(); it != ed; ++it)+ {+ ii->operands[idx++] = translateValue(m, it->get());+ }++ if(ce->isCompare()) {+ ii->cmpPred = decodePredicate((CmpInst::Predicate)ce->getPredicate());+ }+ else if(ce->hasIndices()) {+ ii->numIndices = ce->getIndices().size();+ ii->indices = (int*)calloc(ii->numIndices, sizeof(int));+ std::copy(ce->getIndices().begin(), ce->getIndices().end(), ii->indices);+ }++ return v;+}++static CValue* translateConstant(CModule *m, const Constant *c) {+ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const Value*, CValue*>::iterator it = pd->valueMap.find(c);+ if(it != pd->valueMap.end())+ return it->second;++ // Order these in order of frequency+ if(const ConstantInt *ci = dyn_cast<const ConstantInt>(c)) {+ return translateConstantInt(m, ci);+ }++ if(const ConstantPointerNull *pn = dyn_cast<const ConstantPointerNull>(c)) {+ return translateEmptyConstant(m, VAL_CONSTANTPOINTERNULL, pn);+ }++ if(const ConstantExpr *ce = dyn_cast<const ConstantExpr>(c)) {+ return translateConstantExpr(m, ce);+ }++ if(const GlobalValue *gv = dyn_cast<const GlobalValue>(c)) {+ return translateGlobalValue(m, gv);+ }++ if(const ConstantArray *ca = dyn_cast<const ConstantArray>(c)) {+ return translateConstantAggregate(m, VAL_CONSTANTARRAY, ca);+ }+#if defined(LLVM_VERSION_MAJOR)+ // The ConstantDataSequential type was introduced with LLVM 3.1 (3.0+ // did not define LLVM_VERSION_*)+ if(const ConstantDataSequential *cd = dyn_cast<const ConstantDataSequential>(c)) {+ return translateConstantData(m, cd);+ }+#endif+ if(const ConstantVector *cv = dyn_cast<const ConstantVector>(c)) {+ return translateConstantAggregate(m, VAL_CONSTANTVECTOR, cv);+ }++ if(const ConstantStruct *cs = dyn_cast<const ConstantStruct>(c)) {+ return translateConstantAggregate(m, VAL_CONSTANTSTRUCT, cs);+ }++ if(const ConstantFP *fp = dyn_cast<const ConstantFP>(c)) {+ return translateConstantFP(m, fp);+ }++ if(const ConstantAggregateZero *az = dyn_cast<const ConstantAggregateZero>(c)) {+ return translateEmptyConstant(m, VAL_CONSTANTAGGREGATEZERO, az);+ }++ if(const UndefValue *uv = dyn_cast<const UndefValue>(c)) {+ return translateEmptyConstant(m, VAL_UNDEFVALUE, uv);+ }++ if(const BlockAddress *ba = dyn_cast<const BlockAddress>(c)) {+ return translateBlockAddress(m, ba);+ }+++ string msg;+ raw_string_ostream os(msg);+ os << "Unhandled constant type: ";+ c->print(os);+ throw os.str();+}++static CValue* translateValue(CModule *m, const Value *v) {+ PrivateData *pd = (PrivateData*)m->privateData;+ unordered_map<const Value*, CValue*>::iterator it = pd->valueMap.find(v);+ if(it != pd->valueMap.end())+ return it->second;++ // This order is pretty reasonable since constants will be the most+ // frequent un-cached values.+ if(const Constant *c = dyn_cast<const Constant>(v)) {+ return translateConstant(m, c);+ }++ if(const Instruction *i = dyn_cast<const Instruction>(v)) {+ return translateInstruction(m, i);+ }++ if(const BasicBlock *bb = dyn_cast<const BasicBlock>(v)) {+ return translateBasicBlock(m, bb);+ }++ if(const InlineAsm *a = dyn_cast<const InlineAsm>(v)) {+ return translateInlineAsm(m, a);+ }++ if(dyn_cast<const Argument>(v)) {+ string msg = "Un-cached Argument passed to translateValue";+ throw msg;+ }++ string msg;+ raw_string_ostream os(msg);+ os << "Unhandled value type: ";+ v->print(os);+ throw os.str();+}++static void decodeAndAttachSubprogram(CModule *m, DISubprogram sp) {+ if(sp.getFunction() == NULL)+ return;++ CMeta *md = translateMetadata(m, sp);+ if(!md)+ throw "No translation for subprogram metadata";++ int currentCapacity = md->u.metaSubprogramInfo.function->metaCapacity;+ int metaCount = md->u.metaSubprogramInfo.function->numMetadata;+ if(metaCount == 0) {+ currentCapacity = 10;+ md->u.metaSubprogramInfo.function->metaCapacity = currentCapacity;+ md->u.metaSubprogramInfo.function->md =+ (CMeta**)calloc(currentCapacity, sizeof(CMeta*));+ }+ else if(metaCount == currentCapacity - 1) {+ int newCapacity = 2 * currentCapacity;+ CMeta **newMeta = (CMeta**)calloc(newCapacity, sizeof(CMeta*));+ memcpy(newMeta, md->u.metaSubprogramInfo.function->md, currentCapacity * sizeof(CMeta*));+ free(md->u.metaSubprogramInfo.function->md);+ md->u.metaSubprogramInfo.function->md = newMeta;+ md->u.metaSubprogramInfo.function->metaCapacity = newCapacity;+ }++ md->u.metaSubprogramInfo.function->md[metaCount] = md;+ md->u.metaSubprogramInfo.function->numMetadata++;+}++static void attachFunctionMetadata(CModule *m, Module *M) {+ // dragonegg format+ if(NamedMDNode *sp = M->getNamedMetadata("llvm.dbg.sp")) {+ for(unsigned int i = 0; i < sp->getNumOperands(); ++i) {+ DISubprogram dsp(sp->getOperand(i));+ decodeAndAttachSubprogram(m, dsp);+ }+ }+ // clang format+ else if(NamedMDNode *cu = M->getNamedMetadata("llvm.dbg.cu")) {+ for(unsigned int i = 0; i < cu->getNumOperands(); ++i) {+ DIDescriptor cudesc(cu->getOperand(i));+ if(!cudesc.isCompileUnit())+ throw "llvm.dbg.cu contains a something that isn't a CompileUnit";+ DICompileUnit dicu(cu->getOperand(i));+ DIArray sps = dicu.getSubprograms();+ for(unsigned int j = 0; j < sps.getNumElements(); ++j) {+ DIDescriptor spdesc = sps.getElement(j);+ // It looks like there can be NULL entries in subprogram+ // lists. Just ignore them. Debug info is best-effort so+ // this should be fine.+ if(!spdesc.isSubprogram()) {+ continue;+ }++ DISubprogram dsp(spdesc);+ decodeAndAttachSubprogram(m, dsp);+ }+ }+ }+}++static void attachGlobalMetadata(CModule *m, Module *M) {+ NamedMDNode *gv = M->getNamedMetadata("llvm.dbg.gv");+ // No debug information+ if(!gv) return;++ for(unsigned int i = 0; i < gv->getNumOperands(); ++i) {+ CMeta *md = translateMetadata(m, gv->getOperand(i));+ if(md->metaTag != META_GLOBALVARIABLE) {+ throw "Non-global in llvm.dbg.gv";+ }++ if(md->u.metaGlobalInfo.global == NULL)+ continue;++ int currentCapacity = md->u.metaGlobalInfo.global->metaCapacity;+ int metaCount = md->u.metaGlobalInfo.global->numMetadata;+ if(metaCount == 0) {+ currentCapacity = 10;+ md->u.metaGlobalInfo.global->metaCapacity = currentCapacity;+ md->u.metaGlobalInfo.global->md = (CMeta**)calloc(currentCapacity, sizeof(CMeta*));+ }+ else if(metaCount == currentCapacity - 1) {+ int newCapacity = 2 * currentCapacity;+ CMeta **newMeta = (CMeta**)calloc(newCapacity, sizeof(CMeta*));+ memcpy(newMeta, md->u.metaGlobalInfo.global->md, currentCapacity * sizeof(CMeta*));+ free(md->u.metaGlobalInfo.global->md);+ md->u.metaGlobalInfo.global->md = newMeta;+ md->u.metaGlobalInfo.global->metaCapacity = newCapacity;+ }++ md->u.metaGlobalInfo.global->md[metaCount] = md;+ md->u.metaGlobalInfo.global->numMetadata++;+ }+}++static void attachEnumMetadata(CModule *m, Module *M) {+ // First, try to deal with the old method used by dragonegg 3.0+ NamedMDNode *enums = M->getNamedMetadata("llvm.dbg.enum");+ std::set<CMeta*> enumMeta;++ if(enums) {+ for(unsigned int i = 0; i < enums->getNumOperands(); ++i) {+ CMeta *md = translateMetadata(m, enums->getOperand(i));+ if(md)+ enumMeta.insert(md);+ }++ m->enumMetadata = (CMeta**)calloc(enumMeta.size(), sizeof(CMeta*));+ m->numEnumMetadata = enumMeta.size();+ std::copy(enumMeta.begin(), enumMeta.end(), m->enumMetadata);+ return;+ }++ // Otherwise, try the newer format used by clang (and hopefully+ // newer dragoneggs).+ NamedMDNode *compUnits = M->getNamedMetadata("llvm.dbg.cu");+ if(compUnits) {+ for(unsigned int i = 0; i < compUnits->getNumOperands(); ++i) {+ DICompileUnit CU(compUnits->getOperand(i));+ DIArray unitEnums(CU.getEnumTypes());+ for(unsigned int e = 0; e < unitEnums.getNumElements(); ++e) {+ CMeta *md = translateMetadata(m, unitEnums.getElement(e));+ if(md)+ enumMeta.insert(md);+ }+ }++ m->enumMetadata = (CMeta**)calloc(enumMeta.size(), sizeof(CMeta*));+ m->numEnumMetadata = enumMeta.size();+ std::copy(enumMeta.begin(), enumMeta.end(), m->enumMetadata);+ return;+ }+}++static void attachRetainedTypeMetadata(CModule *m, Module *M) {+ // This information is not present in dragonegg, so we just use the+ // new clang style.+ NamedMDNode *compUnits = M->getNamedMetadata("llvm.dbg.cu");+ if(!compUnits) return;+ std::set<CMeta*> typeMeta;++ for(unsigned int i = 0; i < compUnits->getNumOperands(); ++i) {+ DICompileUnit CU(compUnits->getOperand(i));+ DIArray unitTypes(CU.getRetainedTypes());+ for(unsigned int t = 0; t < unitTypes.getNumElements(); ++t) {+ CMeta *md = translateMetadata(m, unitTypes.getElement(t));+ if(md)+ typeMeta.insert(md);+ }+ }++ m->retainedTypeMetadata = (CMeta**)calloc(typeMeta.size(), sizeof(CMeta*));+ m->numRetainedTypes = typeMeta.size();+ std::copy(typeMeta.begin(), typeMeta.end(), m->retainedTypeMetadata);+}++static CModule* marshal(CModule * module) {+ PrivateData *pd = (PrivateData*)module->privateData;+ Module *m = pd->original;++ module->moduleIdentifier = getCStrdup(m->getModuleIdentifier());+ module->moduleDataLayout = getCStrdup(m->getDataLayout());+ module->targetTriple = getCStrdup(m->getTargetTriple());+ module->moduleInlineAsm = getCStrdup(m->getModuleInlineAsm());+++ try+ {+ std::vector<CValue*> globalVariables;+ for(Module::const_global_iterator it = m->global_begin(),+ ed = m->global_end(); it != ed; ++it)+ {+ const GlobalVariable *globalVar = dyn_cast<const GlobalVariable>(&*it);+ if(!globalVar) throw "Not a global";++ CValue *gv = translateGlobalVariable(module, globalVar);+ globalVariables.push_back(gv);+ }++ module->numGlobalVariables = globalVariables.size();+ module->globalVariables = (CValue**)calloc(module->numGlobalVariables, sizeof(CValue*));+ std::copy(globalVariables.begin(), globalVariables.end(), module->globalVariables);+++ std::vector<CValue*> functions;+ for(Module::const_iterator it = m->begin(),+ ed = m->end(); it != ed; ++it)+ {+ const Function *func = dyn_cast<const Function>(&*it);+ if(!func) throw "Not a function";++ CValue *f = translateFunction(module, func);+ functions.push_back(f);+ }++ module->numFunctions = functions.size();+ module->functions = (CValue**)calloc(module->numFunctions, sizeof(CValue*));+ std::copy(functions.begin(), functions.end(), module->functions);+++ std::vector<CValue*> globalAliases;+ for(Module::const_alias_iterator it = m->alias_begin(),+ ed = m->alias_end(); it != ed; ++it)+ {+ const GlobalAlias *globalAlias = dyn_cast<const GlobalAlias>(&*it);+ if(!globalAlias) throw "Not a global alias";++ CValue *ga = translateGlobalAlias(module, globalAlias);+ globalAliases.push_back(ga);+ }++ module->numGlobalAliases = globalAliases.size();+ module->globalAliases = (CValue**)calloc(module->numGlobalAliases, sizeof(CValue*));+ std::copy(globalAliases.begin(), globalAliases.end(), module->globalAliases);++ std::vector<CType*> typeVec;+ for(unordered_map<const Type*, CType*>::const_iterator it = pd->typeMap.begin(),+ ed = pd->typeMap.end(); it != ed; ++it)+ {+ typeVec.push_back(it->second);+ }+ module->numTypes = typeVec.size();+ module->types = (CType**)calloc(module->numTypes, sizeof(CType*));++ std::copy(typeVec.begin(), typeVec.end(), module->types);++ // Now process the global metadata to attach metadata to global+ // variables and functions.+ attachFunctionMetadata(module, m);+ attachGlobalMetadata(module, m);+ attachEnumMetadata(module, m);+ attachRetainedTypeMetadata(module, m);+ }+ catch(const string &msg) {+ module->hasError = 1;+ module->errMsg = getCStrdup(msg);+ }+ catch(const char *msg) {+ module->hasError = 1;+ module->errMsg = getCStrdup(msg);+ }+ catch(...) {+ module->hasError = 1;+ module->errMsg = getCStrdup("Unknown error");+ }++ return module;+}++extern "C" {++ /*!+ Free all of the resources allocated by the exposed module,+ including the underlying C++ LLVM Module.+ */+ void disposeCModule(CModule *m) {+ free(m->errMsg);+ free(m->moduleIdentifier);+ free(m->moduleDataLayout);+ free(m->targetTriple);+ free(m->moduleInlineAsm);++ // The actual variables are deleted with disposeCValue from the+ // valueMap.+ free(m->globalVariables);+ free(m->globalAliases);+ free(m->functions);+ free(m->enumMetadata);+ free(m->retainedTypeMetadata);++ PrivateData *pd = (PrivateData*)m->privateData;++ for(unordered_map<const Type*,CType*>::iterator it = pd->typeMap.begin(),+ ed = pd->typeMap.end(); it != ed; ++it)+ {+ disposeCType(it->second);+ }++ for(unordered_map<const Value*,CValue*>::iterator it = pd->valueMap.begin(),+ ed = pd->valueMap.end(); it != ed; ++it)+ {+ disposeCValue(it->second);+ }++ for(unordered_map<const MDNode*,CMeta*>::iterator it = pd->metaMap.begin(),+ ed = pd->metaMap.end(); it != ed; ++it)+ {+ disposeCMeta(it->second);+ }++ for(unordered_map<const DebugLoc*,CMeta*>::iterator it = pd->srcLocMap.begin(),+ ed = pd->srcLocMap.end(); it != ed; ++it)+ {+ disposeCMeta(it->second);+ }+++ // These are actually allocated with new+ delete pd->dataLayout;+ delete pd->original;+ delete pd;++ free(m);+ }++ CModule* marshalLLVMFile(const char * filename, int includeLocs) {+ CModule *module = (CModule*)calloc(1, sizeof(CModule));+ PrivateData *pd = new PrivateData;+ module->privateData = (void*)pd;++ Module *m = ParseIRFile(filename, pd->diags, pd->ctxt);+ pd->dataLayout = new DataLayout(m);++ if(m == NULL) {+ module->hasError = 1;+ module->errMsg = getCStrdup(pd->diags.getMessage());+ return module;+ }++ pd->original = m;+ pd->includeLocs = includeLocs;++ return marshal(module);+ }++ CModule* marshalLLVM(const char * buffer, int bufLen, int includeLocs) {+ CModule *module = (CModule*)calloc(1, sizeof(CModule));+ PrivateData *pd = new PrivateData;+ module->privateData = (void*)pd;++ StringRef bref(buffer, bufLen);+ pd->buffer.reset(MemoryBuffer::getMemBuffer(bref, "", false));++ if(pd->buffer.get() == NULL){+ module->hasError = 1;+ module->errMsg = getCStrdup("Could not create memory buffer");+ return module;+ }++ Module *m = ParseIR(pd->buffer.get(), pd->diags, pd->ctxt);++ if(m == NULL) {+ module->hasError = 1;+ module->errMsg = getCStrdup(pd->diags.getMessage());+ return module;+ }++ pd->original = m;+ pd->includeLocs = includeLocs;++ return marshal(module);+ }+}
+ src/c++/marshal.h view
@@ -0,0 +1,441 @@+#include <stdint.h>+#include <llvm-base-enums.h>++typedef struct CValue_t CValue;+typedef struct CMeta_t CMeta;+typedef struct CType_t CType;++struct CType_t {+ TypeTag typeTag;+ // For TypeInt, lengths of TypeArray and TypeVector+ unsigned long long size;++ // For TypeFunction+ int isVarArg;++ // For structs+ int isPacked;++ // For TypeFunction, TypeStruct+ CType** typeList;+ int typeListLen;++ // For FunctionType returnType, TypePointer, TypeNamed, and+ // TypeArray and TypeVector+ CType* innerType;++ // Only for TypeNamed+ char *name;++ // For TypePointer+ int addrSpace;++ // For all types+ int sizeInBytes;+};++typedef struct {+ int arrayLen;+ CMeta **arrayElts;+} MetaArrayInfo;++typedef struct {+ char *enumName;+ uint64_t enumValue;+} MetaEnumeratorInfo;++typedef struct {+ CMeta *context;+ char *name;+ char *displayName;+ char *linkageName;+ // CMeta *compileUnit;+ unsigned lineNumber;+ CMeta *globalType;+ int isLocalToUnit;+ int isDefinition;+ CValue *global;+} MetaGlobalInfo;++typedef struct {+ unsigned lineNumber;+ unsigned columnNumber;+ CMeta *scope;+ CMeta *origLocation;+ char *filename;+ char *directory;+} MetaLocationInfo;++typedef struct {+ int64_t lo;+ int64_t hi;+} MetaSubrangeInfo;++typedef struct {+ CMeta *context;+ char *name;+ CMeta *type;+ char *filename;+ char *directory;+ unsigned lineNumber;+ unsigned columnNumber;+} MetaTemplateTypeInfo;++typedef struct {+ CMeta *context;+ char *name;+ CMeta *type;+ uint64_t value;+ char *filename;+ char *directory;+ unsigned lineNumber;+ unsigned columnNumber;+} MetaTemplateValueInfo;++typedef struct {+ CMeta *context;+ char *name;+ // CMeta *compileUnit;+ unsigned lineNumber;+ unsigned argNumber;+ CMeta *type;+ int isArtificial;+ int hasComplexAddress;+ unsigned numAddrElements;+ uint64_t *addrElements;+ int isBlockByRefVar;+} MetaVariableInfo;++typedef struct {+ unsigned language;+ char *filename;+ char *directory;+ char *producer;+ int isMain;+ int isOptimized;+ char *flags;+ unsigned runtimeVersion;+ CMeta *enumTypes;+ CMeta *retainedTypes;+ CMeta *subprograms;+ CMeta *globalVariables;+} MetaCompileUnitInfo;++typedef struct {+ char *filename;+ char *directory;+ // CMeta *compileUnit;+} MetaFileInfo;++typedef struct {+ CMeta *context;+ unsigned lineNumber;+ unsigned columnNumber;+ char *directory;+ char *filename;+} MetaLexicalBlockInfo;++typedef struct {+ CMeta *context;+ char *name;+ char *directory;+ char *filename;+ // CMeta *compileUnit;+ unsigned lineNumber;+} MetaNamespaceInfo;++typedef struct {+ CMeta *context;+ char *name;+ char *displayName;+ char *linkageName;+ // CMeta *compileUnit;+ unsigned lineNumber;+ CMeta *type;+ char *returnTypeName;+ int isLocalToUnit;+ int isDefinition;+ unsigned virtuality;+ unsigned virtualIndex;+ CMeta *containingType;+ int isArtificial;+ int isPrivate;+ int isProtected;+ int isExplicit;+ int isPrototyped;+ int isOptimized;+ char *filename;+ char *directory;+ CValue *function;+ // This is only available in LLVM 3.0++ // CMeta *templateParams;+} MetaSubprogramInfo;++typedef struct {+ CMeta *context;+ char *name;+ // CMeta *compileUnit;+ // CMeta *file;+ unsigned lineNumber;+ uint64_t sizeInBits;+ uint64_t alignInBits;+ uint64_t offsetInBits;+ unsigned flags;+ int isPrivate;+ int isProtected;+ int isForward;+ int isByRefStruct;+ int isVirtual;+ int isArtificial;+ char *directory;+ char *filename;++ // Basic type+ unsigned encoding;++ // Derived and Composite Types+ CMeta *typeDerivedFrom;+ uint64_t originalTypeSize;++ // Composite Type+ CMeta *typeArray;+ unsigned runTimeLang;+ CMeta *containingType;+ CMeta *templateParams;+} MetaTypeInfo;++typedef struct {+ char *repr;+} MetaUnknownInfo;++struct CMeta_t {+ MetaTag metaTag;+ unsigned int tag;+ union {+ MetaArrayInfo metaArrayInfo;+ MetaEnumeratorInfo metaEnumeratorInfo;+ MetaGlobalInfo metaGlobalInfo;+ MetaLocationInfo metaLocationInfo;+ MetaSubrangeInfo metaSubrangeInfo;+ MetaTemplateTypeInfo metaTemplateTypeInfo;+ MetaTemplateValueInfo metaTemplateValueInfo;+ MetaVariableInfo metaVariableInfo;+ MetaCompileUnitInfo metaCompileUnitInfo;+ MetaFileInfo metaFileInfo;+ MetaLexicalBlockInfo metaLexicalBlockInfo;+ MetaNamespaceInfo metaNamespaceInfo;+ MetaSubprogramInfo metaSubprogramInfo;+ MetaTypeInfo metaTypeInfo;+ MetaUnknownInfo metaUnknownInfo;+ } u;+};++typedef struct {+ int hasSRet;+ int hasByVal;+ int hasNest;+ int hasNoAlias;+ int hasNoCapture;+} CArgumentInfo;++typedef struct {+ CValue **instructions;+ int blockLen;+} CBasicBlockInfo;++typedef struct {+ int isExternal; // Declaration+ int alignment;+ VisibilityStyle visibility;+ LinkageType linkage;+ char *section;++ CallingConvention callingConvention;+ int isVarArg;+ char *gcName;+ CValue **arguments;+ int argListLen;+ CValue **body;+ int blockListLen;+ // FIXME: Add attributes+} CFunctionInfo;++typedef struct {+ int isExternal; // Declaration+ int alignment;+ VisibilityStyle visibility;+ LinkageType linkage;+ char *section;++ // Only for global vars+ CValue *initializer;+ int isThreadLocal;+ int isConstant;++ // Only for global aliases+ CValue *aliasee;+} CGlobalInfo;++typedef struct {+ CValue **operands;+ int numOperands;++ // Value insts+ int *indices;+ int numIndices;++ // Comparisons+ CmpPredicate cmpPred;++ // Binary operators+ ArithFlags flags;++ // Misc+ int align;+ int addrSpace;++ // Load/Store+ int isVolatile;++ // GEP+ int inBounds;+} CInstructionInfo;++typedef struct {+ CAtomicOrdering ordering;+ CSynchronizationScope scope;+ AtomicOperation operation;+ int isVolatile;+ int addrSpace;++ // cmpxchg, atomicrwm+ CValue *pointerOperand;+ // cmpxchg, atomicrwm+ CValue *valueOperand;+ // cmpxchg+ CValue *compareOperand;+} CAtomicInfo;++typedef struct {+ CValue **incomingValues;+ CValue **valueBlocks;+ int numIncomingValues;+} CPHIInfo;++typedef struct {+ CValue *personality;+ int isCleanup;+ int numClauses;+ CValue **clauses;+ LandingPadClause *clauseTypes;+} CLandingPadInfo;++// Also for invoke+typedef struct {+ CValue *calledValue;+ CValue **arguments;+ int argListLen;+ CallingConvention callingConvention;+ int hasSRet;+ int isTail;++ // FIXME: Add attributes++ // Invoke only+ CValue *normalDest;+ CValue *unwindDest;+} CCallInfo;++typedef struct {+ char *asmString;+ char *constraintString;+} CInlineAsmInfo;++typedef struct {+ CValue *func;+ CValue *block;+} CBlockAddrInfo;++// This is lossy but good enough for all practical purposes.+typedef struct {+ long long int val;+ char* hugeVal;+} CConstInt;++typedef struct {+ double val;+} CConstFP;++typedef struct {+ CValue **constants;+ int numElements;+} CConstAggregate;++typedef struct {+ CInstructionInfo *ii;+ ValueTag instrType;+} CConstExprInfo;++struct CValue_t {+ ValueTag valueTag;+ CType *valueType;+ char *name;+ CMeta **md;+ CMeta *srcLoc;+ int numMetadata;+ int metaCapacity;++ void *data;+};++typedef struct {+ char *moduleIdentifier;+ char *moduleDataLayout;+ char *targetTriple;+ int littleEndian;+ int pointerSize;+ char *moduleInlineAsm;++ CValue **globalVariables;+ int numGlobalVariables;+ CValue **globalAliases;+ int numGlobalAliases;+ CValue **functions;+ int numFunctions;++ CType **types;+ int numTypes;++ CMeta **enumMetadata;+ int numEnumMetadata;++ CMeta **retainedTypeMetadata;+ int numRetainedTypes;++ int hasError;+ char *errMsg;++ void *privateData;+} CModule;++#if defined(_WIN32) || defined(__CYGWIN__)+ #if defined(__GNUC__)+ #define DLL_PUBLIC __attribute__((dllexport))+ #else+ #define DLL_PUBLIC __declspec(dllexport)+ #endif+#else+ #if __GNUC__ >= 4+ #define DLL_PUBLIC __attribute__((visibility("default")))+ #endif+#endif++#if defined(__cplusplus)+extern "C" {+#endif+ DLL_PUBLIC void disposeCModule(CModule *m);+ DLL_PUBLIC CModule* marshalLLVM(const char *buffer, int bufLen, int includeLocs);+ DLL_PUBLIC CModule* marshalLLVMFile(const char *filename, int includeLocs);+#if defined(__cplusplus)+}+#endif