]> git.lizzy.rs Git - rust.git/commitdiff
Merge branch 'master' into issue-30961
authorCameron Hart <cameron.hart@gmail.com>
Sat, 6 Aug 2016 05:50:48 +0000 (15:50 +1000)
committerCameron Hart <cameron.hart@gmail.com>
Sat, 6 Aug 2016 05:50:48 +0000 (15:50 +1000)
1  2 
mk/rustllvm.mk
src/bootstrap/compile.rs
src/librustc/session/config.rs
src/librustc_driver/lib.rs
src/librustc_llvm/build.rs
src/librustc_llvm/ffi.rs
src/librustc_trans/back/write.rs
src/librustc_trans/context.rs
src/llvm
src/rustllvm/PassWrapper.cpp

diff --combined mk/rustllvm.mk
index 26b593c8c47b68cbaf8e9afc56c5fb93345152ab,b50dbd01ad0cc0071bcf20cf8b5ba366ca724dc2..2d63f69960f78a949b952d4fdf8e916c1559c398
@@@ -24,7 -24,7 +24,7 @@@ LLVM_EXTRA_INCDIRS_$(1)= $$(call CFG_CC
  endif
  
  RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
-       ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp \
+       RustWrapper.cpp PassWrapper.cpp \
        ArchiveWrapper.cpp)
  
  RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
                       $$(call CFG_CC_INCLUDE_$(1),$$(S)src/rustllvm/include)
  RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=$(1)/rustllvm/%.o)
  
 +# Flag that we are building with Rust's llvm fork
 +ifeq ($(CFG_LLVM_ROOT),)
 +RUSTLLVM_CXXFLAGS_$(1) := -DLLVM_RUSTLLVM
 +endif
 +
  # Note that we appease `cl.exe` and its need for some sort of exception
  # handling flag with the `EHsc` argument here as well.
  ifeq ($$(findstring msvc,$(1)),msvc)
@@@ -60,7 -55,6 +60,7 @@@ $(1)/rustllvm/%.o: $(S)src/rustllvm/%.c
        $$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@,) \
                $$(subst  /,//,$$(LLVM_CXXFLAGS_$(1))) \
                $$(RUSTLLVM_COMPONENTS_$(1)) \
 +              $$(RUSTLLVM_CXXFLAGS_$(1)) \
                $$(EXTRA_RUSTLLVM_CXXFLAGS_$(1)) \
                $$(RUSTLLVM_INCS_$(1)) \
                $$<
diff --combined src/bootstrap/compile.rs
index 31915b11691989bfcc3c9aaba68e43b8bf394eed,061192ebd1340b318aedbea2441339eebb4282fe..9e1ee7ccd1e19bc99f471b2c5845aae4a2a125be
@@@ -92,8 -92,7 +92,7 @@@ pub fn std_link(build: &Build
      }
      add_to_sysroot(&out_dir, &libdir);
  
-     if target.contains("musl") &&
-        (target.contains("x86_64") || target.contains("i686")) {
+     if target.contains("musl") && !target.contains("mips") {
          copy_third_party_objects(build, target, &libdir);
      }
  }
@@@ -199,10 -198,6 +198,10 @@@ pub fn rustc<'a>(build: &'a Build, targ
      if !build.unstable_features {
          cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
      }
 +    // Flag that rust llvm is in use
 +    if build.config.target_config.get(target).is_none() {
 +        cargo.env("LLVM_RUSTLLVM", "1");
 +    }
      cargo.env("LLVM_CONFIG", build.llvm_config(target));
      if build.config.llvm_static_stdcpp {
          cargo.env("LLVM_STATIC_STDCPP",
index ed14c1e641723d886c96aab700e3fefc83563ff0,6ed91cdbe18bc3c2551c7dbee48803ba11eabb61..f32db9207fc6f261bf1750c712d396150a0104a1
@@@ -30,7 -30,7 +30,7 @@@ use syntax::parse
  use syntax::parse::token::InternedString;
  use syntax::feature_gate::UnstableFeatures;
  
- use errors::{ColorConfig, Handler};
+ use errors::{ColorConfig, FatalError, Handler};
  
  use getopts;
  use std::collections::HashMap;
@@@ -61,7 -61,7 +61,7 @@@ pub enum DebugInfoLevel 
      FullDebugInfo,
  }
  
- #[derive(Clone, Copy, PartialEq, Eq, Hash)]
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
  pub enum OutputType {
      Bitcode,
      Assembly,
@@@ -105,6 -105,17 +105,17 @@@ impl OutputType 
              OutputType::DepInfo => "dep-info",
          }
      }
+     pub fn extension(&self) -> &'static str {
+         match *self {
+             OutputType::Bitcode => "bc",
+             OutputType::Assembly => "s",
+             OutputType::LlvmAssembly => "ll",
+             OutputType::Object => "o",
+             OutputType::DepInfo => "d",
+             OutputType::Exe => "",
+         }
+     }
  }
  
  #[derive(Clone)]
@@@ -165,10 -176,6 +176,10 @@@ pub enum PrintRequest 
      CrateName,
      Cfg,
      TargetList,
 +    TargetCPUs,
 +    TargetFeatures,
 +    RelocationModels,
 +    CodeModels,
  }
  
  pub enum Input {
@@@ -219,15 -226,7 +230,7 @@@ impl OutputFilenames 
                       flavor: OutputType,
                       codegen_unit_name: Option<&str>)
                       -> PathBuf {
-         let extension = match flavor {
-             OutputType::Bitcode => "bc",
-             OutputType::Assembly => "s",
-             OutputType::LlvmAssembly => "ll",
-             OutputType::Object => "o",
-             OutputType::DepInfo => "d",
-             OutputType::Exe => "",
-         };
+         let extension = flavor.extension();
          self.temp_path_ext(extension, codegen_unit_name)
      }
  
@@@ -331,6 -330,11 +334,11 @@@ impl Options 
              self.debugging_opts.dump_dep_graph ||
              self.debugging_opts.query_dep_graph
      }
+     pub fn single_codegen_unit(&self) -> bool {
+         self.incremental.is_none() ||
+         self.cg.codegen_units == 1
+     }
  }
  
  // The type of entry function, so
@@@ -459,6 -463,8 +467,8 @@@ macro_rules! options 
          pub const parse_bool: Option<&'static str> = None;
          pub const parse_opt_bool: Option<&'static str> =
              Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
+         pub const parse_all_bool: Option<&'static str> =
+             Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
          pub const parse_string: Option<&'static str> = Some("a string");
          pub const parse_opt_string: Option<&'static str> = Some("a string");
          pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
              }
          }
  
+         fn parse_all_bool(slot: &mut bool, v: Option<&str>) -> bool {
+             match v {
+                 Some(s) => {
+                     match s {
+                         "n" | "no" | "off" => {
+                             *slot = false;
+                         }
+                         "y" | "yes" | "on" => {
+                             *slot = true;
+                         }
+                         _ => { return false; }
+                     }
+                     true
+                 },
+                 None => { *slot = true; true }
+             }
+         }
          fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
              match v {
                  Some(s) => { *slot = Some(s.to_string()); true },
@@@ -604,9 -629,9 +633,9 @@@ options! {CodegenOptions, CodegenSetter
      lto: bool = (false, parse_bool,
          "perform LLVM link-time optimizations"),
      target_cpu: Option<String> = (None, parse_opt_string,
 -        "select target processor (llc -mcpu=help for details)"),
 +        "select target processor (rustc --print target-cpus for details)"),
      target_feature: String = ("".to_string(), parse_string,
 -        "target specific attributes (llc -mattr=help for details)"),
 +        "target specific attributes (rustc --print target-features for details)"),
      passes: Vec<String> = (Vec::new(), parse_list,
          "a list of extra LLVM passes to run (space separated)"),
      llvm_args: Vec<String> = (Vec::new(), parse_list,
      no_redzone: Option<bool> = (None, parse_opt_bool,
          "disable the use of the redzone"),
      relocation_model: Option<String> = (None, parse_opt_string,
 -         "choose the relocation model to use (llc -relocation-model for details)"),
 +         "choose the relocation model to use (rustc --print relocation-models for details)"),
      code_model: Option<String> = (None, parse_opt_string,
 -         "choose the code model to use (llc -code-model for details)"),
 +         "choose the code model to use (rustc --print code-models for details)"),
      metadata: Vec<String> = (Vec::new(), parse_list,
           "metadata to mangle symbol names with"),
      extra_filename: String = ("".to_string(), parse_string,
          "panic strategy to compile crate with"),
  }
  
  options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           build_debugging_options, "Z", "debugging",
           DB_OPTIONS, db_type_desc, dbsetters,
            "set the MIR optimization level (0-3)"),
      dump_mir: Option<String> = (None, parse_opt_string,
            "dump MIR state at various points in translation"),
-     orbit: bool = (false, parse_bool,
+     dump_mir_dir: Option<String> = (None, parse_opt_string,
+           "the directory the MIR is dumped into"),
+     orbit: bool = (true, parse_all_bool,
            "get MIR where it belongs - everywhere; most importantly, in orbit"),
  }
  
@@@ -835,7 -861,10 +865,10 @@@ pub fn build_target_config(opts: &Optio
      let target = match Target::search(&opts.target_triple) {
          Ok(t) => t,
          Err(e) => {
-             panic!(sp.fatal(&format!("Error loading target specification: {}", e)));
+             sp.struct_fatal(&format!("Error loading target specification: {}", e))
+                 .help("Use `--print target-list` for a list of built-in targets")
+                 .emit();
+             panic!(FatalError);
          }
      };
  
@@@ -993,8 -1022,7 +1026,8 @@@ pub fn rustc_short_optgroups() -> Vec<R
                   "[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
          opt::multi_s("", "print", "Comma separated list of compiler information to \
                                 print on stdout",
 -                 "[crate-name|file-names|sysroot|cfg|target-list]"),
 +                 "[crate-name|file-names|sysroot|cfg|target-list|target-cpus|\
 +                   target-features|relocation-models|code-models]"),
          opt::flagmulti_s("g",  "",  "Equivalent to -C debuginfo=2"),
          opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
          opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
@@@ -1140,7 -1168,15 +1173,15 @@@ pub fn build_session_options(matches: &
          })
      });
  
-     let debugging_opts = build_debugging_options(matches, error_format);
+     let mut debugging_opts = build_debugging_options(matches, error_format);
+     // Incremental compilation only works reliably when translation is done via
+     // MIR, so let's enable -Z orbit if necessary (see #34973).
+     if debugging_opts.incremental.is_some() && !debugging_opts.orbit {
+         early_warn(error_format, "Automatically enabling `-Z orbit` because \
+                                   `-Z incremental` was specified");
+         debugging_opts.orbit = true;
+     }
  
      let parse_only = debugging_opts.parse_only;
      let no_trans = debugging_opts.no_trans;
          early_error(error_format, "Value for codegen units must be a positive nonzero integer");
      }
  
 +    let mut prints = Vec::<PrintRequest>::new();
 +    if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
 +        prints.push(PrintRequest::TargetCPUs);
 +        cg.target_cpu = None;
 +    };
 +    if cg.target_feature == "help" {
 +        prints.push(PrintRequest::TargetFeatures);
 +        cg.target_feature = "".to_string();
 +    }
 +    if cg.relocation_model.as_ref().map_or(false, |s| s == "help") {
 +        prints.push(PrintRequest::RelocationModels);
 +        cg.relocation_model = None;
 +    }
 +    if cg.code_model.as_ref().map_or(false, |s| s == "help") {
 +        prints.push(PrintRequest::CodeModels);
 +        cg.code_model = None;
 +    }
 +
      let cg = cg;
  
      let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
      let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
      let test = matches.opt_present("test");
  
 -    let prints = matches.opt_strs("print").into_iter().map(|s| {
 +    prints.extend(matches.opt_strs("print").into_iter().map(|s| {
          match &*s {
              "crate-name" => PrintRequest::CrateName,
              "file-names" => PrintRequest::FileNames,
              "sysroot" => PrintRequest::Sysroot,
              "cfg" => PrintRequest::Cfg,
              "target-list" => PrintRequest::TargetList,
 +            "target-cpus" => PrintRequest::TargetCPUs,
 +            "target-features" => PrintRequest::TargetFeatures,
 +            "relocation-models" => PrintRequest::RelocationModels,
 +            "code-models" => PrintRequest::CodeModels,
              req => {
                  early_error(error_format, &format!("unknown print request `{}`", req))
              }
          }
 -    }).collect::<Vec<_>>();
 +    }));
  
      if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
          early_warn(error_format, "-C remark will not show source locations without \
index f50ea9af493e500a29576eeb7e2a145780f8fb4f,772c59b34dd02725897eca4d397c6d5bac309aa8..d92ecfaec32865c7ab1b739ebf73a06631fb437a
@@@ -31,7 -31,6 +31,6 @@@
  #![feature(set_stdio)]
  #![feature(staged_api)]
  #![feature(question_mark)]
- #![feature(unboxed_closures)]
  
  extern crate arena;
  extern crate flate;
@@@ -69,7 -68,6 +68,7 @@@ use pretty::{PpMode, UserIdentifiedItem
  use rustc_resolve as resolve;
  use rustc_save_analysis as save;
  use rustc_trans::back::link;
 +use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
  use rustc::dep_graph::DepGraph;
  use rustc::session::{self, config, Session, build_session, CompileResult};
  use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
@@@ -96,6 -94,7 +95,7 @@@ use std::thread
  use rustc::session::early_error;
  
  use syntax::{ast, json};
+ use syntax::attr::AttrMetaMethods;
  use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
  use syntax::feature_gate::{GatedCfg, UnstableFeatures};
  use syntax::parse::{self, PResult};
@@@ -187,7 -186,7 +187,7 @@@ pub fn run_compiler_with_file_loader<'a
      let sopts = config::build_session_options(&matches);
  
      if sopts.debugging_opts.debug_llvm {
-         unsafe { llvm::LLVMSetDebug(1); }
+         unsafe { llvm::LLVMRustSetDebug(1); }
      }
  
      let descriptions = diagnostics_registry();
@@@ -393,15 -392,12 +393,12 @@@ fn check_cfg(sopts: &config::Options
  
      let mut saw_invalid_predicate = false;
      for item in sopts.cfg.iter() {
-         match item.node {
-             ast::MetaItemKind::List(ref pred, _) => {
-                 saw_invalid_predicate = true;
-                 handler.emit(&MultiSpan::new(),
-                              &format!("invalid predicate in --cfg command line argument: `{}`",
-                                       pred),
-                                 errors::Level::Fatal);
-             }
-             _ => {},
+         if item.is_meta_item_list() {
+             saw_invalid_predicate = true;
+             handler.emit(&MultiSpan::new(),
+                          &format!("invalid predicate in --cfg command line argument: `{}`",
+                                   item.name()),
+                             errors::Level::Fatal);
          }
      }
  
@@@ -610,7 -606,7 +607,7 @@@ impl RustcDefaultCalls 
          for req in &sess.opts.prints {
              match *req {
                  PrintRequest::TargetList => {
-                     let mut targets = rustc_back::target::TARGETS.to_vec();
+                     let mut targets = rustc_back::target::get_targets().collect::<Vec<String>>();
                      targets.sort();
                      println!("{}", targets.join("\n"));
                  },
                          if !allow_unstable_cfg && GatedCfg::gate(&*cfg).is_some() {
                              continue;
                          }
-                         match cfg.node {
-                             ast::MetaItemKind::Word(ref word) => println!("{}", word),
-                             ast::MetaItemKind::NameValue(ref name, ref value) => {
-                                 println!("{}=\"{}\"", name, match value.node {
-                                     ast::LitKind::Str(ref s, _) => s,
-                                     _ => continue,
-                                 });
+                         if cfg.is_word() {
+                             println!("{}", cfg.name());
+                         } else if cfg.is_value_str() {
+                             if let Some(s) = cfg.value_str() {
+                                 println!("{}=\"{}\"", cfg.name(), s);
                              }
+                         } else if cfg.is_meta_item_list() {
                              // Right now there are not and should not be any
                              // MetaItemKind::List items in the configuration returned by
                              // `build_configuration`.
-                             ast::MetaItemKind::List(..) => {
-                                 panic!("MetaItemKind::List encountered in default cfg")
-                             }
+                             panic!("MetaItemKind::List encountered in default cfg")
                          }
                      }
                  }
 +                PrintRequest::TargetCPUs => {
 +                    let tm = create_target_machine(sess);
 +                    unsafe { llvm::LLVMRustPrintTargetCPUs(tm); }
 +                }
 +                PrintRequest::TargetFeatures => {
 +                    let tm = create_target_machine(sess);
 +                    unsafe { llvm::LLVMRustPrintTargetFeatures(tm); }
 +                }
 +                PrintRequest::RelocationModels => {
 +                    println!("Available relocation models:");
 +                    for &(name, _) in RELOC_MODEL_ARGS.iter() {
 +                        println!("    {}", name);
 +                    }
 +                    println!("");
 +                }
 +                PrintRequest::CodeModels => {
 +                    println!("Available code models:");
 +                    for &(name, _) in CODE_GEN_MODEL_ARGS.iter(){
 +                        println!("    {}", name);
 +                    }
 +                    println!("");
 +                }
              }
          }
          return Compilation::Stop;
index 96b419d647ee32038afb34a100fb8fec264d7f79,b8548aaec5bd74d023d99016d3042f1c220913aa..5f7a0f788ca1289e8da69b9e001289622041af8b
@@@ -13,7 -13,7 +13,7 @@@ extern crate build_helper
  
  use std::process::Command;
  use std::env;
- use std::path::PathBuf;
+ use std::path::{PathBuf, Path};
  
  use build_helper::output;
  
@@@ -112,12 -112,7 +112,11 @@@ fn main() 
          cfg.flag(&flag);
      }
  
-     cfg.file("../rustllvm/ExecutionEngineWrapper.cpp")
-        .file("../rustllvm/PassWrapper.cpp")
 +    if env::var_os("LLVM_RUSTLLVM").is_some() {
 +        cfg.flag("-DLLVM_RUSTLLVM");
 +    }
 +
+     cfg.file("../rustllvm/PassWrapper.cpp")
         .file("../rustllvm/RustWrapper.cpp")
         .file("../rustllvm/ArchiveWrapper.cpp")
         .cpp(true)
              &lib[2..]
          } else if lib.starts_with("-") {
              &lib[1..]
+         } else if Path::new(lib).exists() {
+             // On MSVC llvm-config will print the full name to libraries, but
+             // we're only interested in the name part
+             let name = Path::new(lib).file_name().unwrap().to_str().unwrap();
+             name.trim_right_matches(".lib")
+         } else if lib.ends_with(".lib") {
+             // Some MSVC libraries just come up with `.lib` tacked on, so chop
+             // that off
+             lib.trim_right_matches(".lib")
          } else {
-             continue;
+             continue
          };
  
          // Don't need or want this library, but LLVM's CMake build system
          // library and it otherwise may just pull in extra dependencies on
          // libedit which we don't want
          if name == "LLVMLineEditor" {
-             continue;
+             continue
          }
  
          let kind = if name.starts_with("LLVM") {
      let mut cmd = Command::new(&llvm_config);
      cmd.arg("--ldflags");
      for lib in output(&mut cmd).split_whitespace() {
-         if is_crossed {
+         if lib.starts_with("-LIBPATH:") {
+                 println!("cargo:rustc-link-search=native={}", &lib[9..]);
+         } else if is_crossed {
              if lib.starts_with("-L") {
                  println!("cargo:rustc-link-search=native={}",
                           lib[2..].replace(&host, &target));
diff --combined src/librustc_llvm/ffi.rs
index 0000000000000000000000000000000000000000,6301c57c55540ebe7fe260db96eb82055f33114e..b2ffcac365bad34760351052003f8411d7265fb0
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,2068 +1,2071 @@@
+ // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+ // file at the top-level directory of this distribution and at
+ // http://rust-lang.org/COPYRIGHT.
+ //
+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+ // option. This file may not be copied, modified, or distributed
+ // except according to those terms.
+ use debuginfo::{DIBuilderRef, DIDescriptor,
+                 DIFile, DILexicalBlock, DISubprogram, DIType,
+                 DIBasicType, DIDerivedType, DICompositeType, DIScope,
+                 DIVariable, DIGlobalVariable, DIArray, DISubrange,
+                 DITemplateTypeParameter, DIEnumerator, DINameSpace};
+ use libc::{c_uint, c_int, size_t, c_char};
+ use libc::{c_longlong, c_ulonglong, c_void};
+ use RustStringRef;
+ pub type Opcode = u32;
+ pub type Bool = c_uint;
+ pub const True: Bool = 1 as Bool;
+ pub const False: Bool = 0 as Bool;
+ #[derive(Copy, Clone, PartialEq)]
+ #[repr(C)]
+ pub enum LLVMRustResult {
+     Success,
+     Failure,
+ }
+ // Consts for the LLVM CallConv type, pre-cast to usize.
+ /// LLVM CallingConv::ID. Should we wrap this?
+ #[derive(Copy, Clone, PartialEq)]
+ #[repr(C)]
+ pub enum CallConv {
+     CCallConv = 0,
+     FastCallConv = 8,
+     ColdCallConv = 9,
+     X86StdcallCallConv = 64,
+     X86FastcallCallConv = 65,
+     X86_64_Win64 = 79,
+     X86_VectorCall = 80
+ }
+ /// LLVMLinkage
+ ///
+ /// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
+ /// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
+ /// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
+ /// they've been removed in upstream LLVM commit r203866.
+ #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+ #[repr(C)]
+ pub enum Linkage {
+     ExternalLinkage = 0,
+     AvailableExternallyLinkage = 1,
+     LinkOnceAnyLinkage = 2,
+     LinkOnceODRLinkage = 3,
+     WeakAnyLinkage = 5,
+     WeakODRLinkage = 6,
+     AppendingLinkage = 7,
+     InternalLinkage = 8,
+     PrivateLinkage = 9,
+     ExternalWeakLinkage = 12,
+     CommonLinkage = 14,
+ }
+ /// LLVMDiagnosticSeverity
+ #[derive(Copy, Clone, Debug)]
+ #[repr(C)]
+ pub enum DiagnosticSeverity {
+     Error = 0,
+     Warning = 1,
+     Remark = 2,
+     Note = 3,
+ }
+ /// LLVMDLLStorageClass
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum DLLStorageClass {
+   Default   = 0,
+   DllImport = 1, /* Function to be imported from DLL. */
+   DllExport = 2, /* Function to be accessible from DLL. */
+ }
+ bitflags! {
+     #[derive(Default, Debug)]
+     flags Attribute : u64 {
+         const ZExt            = 1 << 0,
+         const SExt            = 1 << 1,
+         const NoReturn        = 1 << 2,
+         const InReg           = 1 << 3,
+         const StructRet       = 1 << 4,
+         const NoUnwind        = 1 << 5,
+         const NoAlias         = 1 << 6,
+         const ByVal           = 1 << 7,
+         const Nest            = 1 << 8,
+         const ReadNone        = 1 << 9,
+         const ReadOnly        = 1 << 10,
+         const NoInline        = 1 << 11,
+         const AlwaysInline    = 1 << 12,
+         const OptimizeForSize = 1 << 13,
+         const StackProtect    = 1 << 14,
+         const StackProtectReq = 1 << 15,
+         const NoCapture       = 1 << 21,
+         const NoRedZone       = 1 << 22,
+         const NoImplicitFloat = 1 << 23,
+         const Naked           = 1 << 24,
+         const InlineHint      = 1 << 25,
+         const ReturnsTwice    = 1 << 29,
+         const UWTable         = 1 << 30,
+         const NonLazyBind     = 1 << 31,
+         // Some of these are missing from the LLVM C API, the rest are
+         // present, but commented out, and preceded by the following warning:
+         // FIXME: These attributes are currently not included in the C API as
+         // a temporary measure until the API/ABI impact to the C API is understood
+         // and the path forward agreed upon.
+         const SanitizeAddress = 1 << 32,
+         const MinSize         = 1 << 33,
+         const NoDuplicate     = 1 << 34,
+         const StackProtectStrong = 1 << 35,
+         const SanitizeThread  = 1 << 36,
+         const SanitizeMemory  = 1 << 37,
+         const NoBuiltin       = 1 << 38,
+         const Returned        = 1 << 39,
+         const Cold            = 1 << 40,
+         const Builtin         = 1 << 41,
+         const OptimizeNone    = 1 << 42,
+         const InAlloca        = 1 << 43,
+         const NonNull         = 1 << 44,
+         const JumpTable       = 1 << 45,
+         const Convergent      = 1 << 46,
+         const SafeStack       = 1 << 47,
+         const NoRecurse       = 1 << 48,
+         const InaccessibleMemOnly         = 1 << 49,
+         const InaccessibleMemOrArgMemOnly = 1 << 50,
+     }
+ }
+ /// LLVMIntPredicate
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum IntPredicate {
+     IntEQ = 32,
+     IntNE = 33,
+     IntUGT = 34,
+     IntUGE = 35,
+     IntULT = 36,
+     IntULE = 37,
+     IntSGT = 38,
+     IntSGE = 39,
+     IntSLT = 40,
+     IntSLE = 41,
+ }
+ /// LLVMRealPredicate
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum RealPredicate {
+     RealPredicateFalse = 0,
+     RealOEQ = 1,
+     RealOGT = 2,
+     RealOGE = 3,
+     RealOLT = 4,
+     RealOLE = 5,
+     RealONE = 6,
+     RealORD = 7,
+     RealUNO = 8,
+     RealUEQ = 9,
+     RealUGT = 10,
+     RealUGE = 11,
+     RealULT = 12,
+     RealULE = 13,
+     RealUNE = 14,
+     RealPredicateTrue = 15,
+ }
+ /// LLVMTypeKind
+ #[derive(Copy, Clone, PartialEq, Debug)]
+ #[repr(C)]
+ pub enum TypeKind {
+     Void      = 0,
+     Half      = 1,
+     Float     = 2,
+     Double    = 3,
+     X86_FP80  = 4,
+     FP128     = 5,
+     PPC_FP128 = 6,
+     Label     = 7,
+     Integer   = 8,
+     Function  = 9,
+     Struct    = 10,
+     Array     = 11,
+     Pointer   = 12,
+     Vector    = 13,
+     Metadata  = 14,
+     X86_MMX   = 15,
+     Token     = 16,
+ }
+ /// LLVMAtomicRmwBinOp
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum AtomicRmwBinOp {
+     AtomicXchg = 0,
+     AtomicAdd  = 1,
+     AtomicSub  = 2,
+     AtomicAnd  = 3,
+     AtomicNand = 4,
+     AtomicOr   = 5,
+     AtomicXor  = 6,
+     AtomicMax  = 7,
+     AtomicMin  = 8,
+     AtomicUMax = 9,
+     AtomicUMin = 10,
+ }
+ /// LLVMAtomicOrdering
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum AtomicOrdering {
+     NotAtomic = 0,
+     Unordered = 1,
+     Monotonic = 2,
+     // Consume = 3,  // Not specified yet.
+     Acquire = 4,
+     Release = 5,
+     AcquireRelease = 6,
+     SequentiallyConsistent = 7
+ }
+ /// LLVMRustSynchronizationScope
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum SynchronizationScope {
+     Other,
+     SingleThread,
+     CrossThread,
+ }
+ /// LLVMRustFileType
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum FileType {
+     Other,
+     AssemblyFile,
+     ObjectFile,
+ }
+ /// Enum pinned in LLVMContext, used in
+ /// LLVMSetMetadata so ABI-stable.
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum MetadataType {
+     MD_dbg = 0,
+     MD_tbaa = 1,
+     MD_prof = 2,
+     MD_fpmath = 3,
+     MD_range = 4,
+     MD_tbaa_struct = 5,
+     MD_invariant_load = 6,
+     MD_alias_scope = 7,
+     MD_noalias = 8,
+     MD_nontemporal = 9,
+     MD_mem_parallel_loop_access = 10,
+     MD_nonnull = 11,
+ }
+ /// LLVMRustAsmDialect
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum AsmDialect {
+     Other,
+     Att,
+     Intel,
+ }
+ /// LLVMRustCodeGenOptLevel
+ #[derive(Copy, Clone, PartialEq)]
+ #[repr(C)]
+ pub enum CodeGenOptLevel {
+     Other,
+     None,
+     Less,
+     Default,
+     Aggressive,
+ }
+ /// LLVMRelocMode
+ #[derive(Copy, Clone, PartialEq)]
+ #[repr(C)]
+ pub enum RelocMode {
+     Default = 0,
+     Static = 1,
+     PIC = 2,
+     DynamicNoPic = 3,
+ }
+ /// LLVMRustCodeModel
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum CodeModel {
+     Other,
+     Default,
+     JITDefault,
+     Small,
+     Kernel,
+     Medium,
+     Large,
+ }
+ /// LLVMRustDiagnosticKind
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum DiagnosticKind {
+     Other,
+     InlineAsm,
+     StackSize,
+     DebugMetadataVersion,
+     SampleProfile,
+     OptimizationRemark,
+     OptimizationRemarkMissed,
+     OptimizationRemarkAnalysis,
+     OptimizationRemarkAnalysisFPCommute,
+     OptimizationRemarkAnalysisAliasing,
+     OptimizationRemarkOther,
+     OptimizationFailure,
+ }
+ /// LLVMRustArchiveKind
+ #[derive(Copy, Clone)]
+ #[repr(C)]
+ pub enum ArchiveKind {
+     Other,
+     K_GNU,
+     K_MIPS64,
+     K_BSD,
+     K_COFF,
+ }
+ /// LLVMRustPassKind
+ #[derive(Copy, Clone, PartialEq, Debug)]
+ #[repr(C)]
+ pub enum PassKind {
+     Other,
+     Function,
+     Module,
+ }
+ // Opaque pointer types
+ #[allow(missing_copy_implementations)]
+ pub enum Module_opaque {}
+ pub type ModuleRef = *mut Module_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum Context_opaque {}
+ pub type ContextRef = *mut Context_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum Type_opaque {}
+ pub type TypeRef = *mut Type_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum Value_opaque {}
+ pub type ValueRef = *mut Value_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum Metadata_opaque {}
+ pub type MetadataRef = *mut Metadata_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum BasicBlock_opaque {}
+ pub type BasicBlockRef = *mut BasicBlock_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum Builder_opaque {}
+ pub type BuilderRef = *mut Builder_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum ExecutionEngine_opaque {}
+ pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum MemoryBuffer_opaque {}
+ pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum PassManager_opaque {}
+ pub type PassManagerRef = *mut PassManager_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum PassManagerBuilder_opaque {}
+ pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum Use_opaque {}
+ pub type UseRef = *mut Use_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum TargetData_opaque {}
+ pub type TargetDataRef = *mut TargetData_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum ObjectFile_opaque {}
+ pub type ObjectFileRef = *mut ObjectFile_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum SectionIterator_opaque {}
+ pub type SectionIteratorRef = *mut SectionIterator_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum Pass_opaque {}
+ pub type PassRef = *mut Pass_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum TargetMachine_opaque {}
+ pub type TargetMachineRef = *mut TargetMachine_opaque;
+ pub enum Archive_opaque {}
+ pub type ArchiveRef = *mut Archive_opaque;
+ pub enum ArchiveIterator_opaque {}
+ pub type ArchiveIteratorRef = *mut ArchiveIterator_opaque;
+ pub enum ArchiveChild_opaque {}
+ pub type ArchiveChildRef = *mut ArchiveChild_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum Twine_opaque {}
+ pub type TwineRef = *mut Twine_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum DiagnosticInfo_opaque {}
+ pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum DebugLoc_opaque {}
+ pub type DebugLocRef = *mut DebugLoc_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum SMDiagnostic_opaque {}
+ pub type SMDiagnosticRef = *mut SMDiagnostic_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum RustArchiveMember_opaque {}
+ pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque;
+ #[allow(missing_copy_implementations)]
+ pub enum OperandBundleDef_opaque {}
+ pub type OperandBundleDefRef = *mut OperandBundleDef_opaque;
+ pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void);
+ pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint);
+ pub mod debuginfo {
+     pub use self::DIDescriptorFlags::*;
+     use super::{MetadataRef};
+     #[allow(missing_copy_implementations)]
+     pub enum DIBuilder_opaque {}
+     pub type DIBuilderRef = *mut DIBuilder_opaque;
+     pub type DIDescriptor = MetadataRef;
+     pub type DIScope = DIDescriptor;
+     pub type DILocation = DIDescriptor;
+     pub type DIFile = DIScope;
+     pub type DILexicalBlock = DIScope;
+     pub type DISubprogram = DIScope;
+     pub type DINameSpace = DIScope;
+     pub type DIType = DIDescriptor;
+     pub type DIBasicType = DIType;
+     pub type DIDerivedType = DIType;
+     pub type DICompositeType = DIDerivedType;
+     pub type DIVariable = DIDescriptor;
+     pub type DIGlobalVariable = DIDescriptor;
+     pub type DIArray = DIDescriptor;
+     pub type DISubrange = DIDescriptor;
+     pub type DIEnumerator = DIDescriptor;
+     pub type DITemplateTypeParameter = DIDescriptor;
+     #[derive(Copy, Clone)]
+     pub enum DIDescriptorFlags {
+       FlagPrivate            = 1 << 0,
+       FlagProtected          = 1 << 1,
+       FlagFwdDecl            = 1 << 2,
+       FlagAppleBlock         = 1 << 3,
+       FlagBlockByrefStruct   = 1 << 4,
+       FlagVirtual            = 1 << 5,
+       FlagArtificial         = 1 << 6,
+       FlagExplicit           = 1 << 7,
+       FlagPrototyped         = 1 << 8,
+       FlagObjcClassComplete  = 1 << 9,
+       FlagObjectPointer      = 1 << 10,
+       FlagVector             = 1 << 11,
+       FlagStaticMember       = 1 << 12,
+       FlagIndirectVariable   = 1 << 13,
+       FlagLValueReference    = 1 << 14,
+       FlagRValueReference    = 1 << 15
+     }
+ }
+ // Link to our native llvm bindings (things that we need to use the C++ api
+ // for) and because llvm is written in C++ we need to link against libstdc++
+ //
+ // You'll probably notice that there is an omission of all LLVM libraries
+ // from this location. This is because the set of LLVM libraries that we
+ // link to is mostly defined by LLVM, and the `llvm-config` tool is used to
+ // figure out the exact set of libraries. To do this, the build system
+ // generates an llvmdeps.rs file next to this one which will be
+ // automatically updated whenever LLVM is updated to include an up-to-date
+ // set of the libraries we need to link to LLVM for.
+ #[link(name = "rustllvm", kind = "static")]
+ #[cfg(not(cargobuild))]
+ extern {}
+ #[linked_from = "rustllvm"] // not quite true but good enough
+ extern {
+     /* Create and destroy contexts. */
+     pub fn LLVMContextCreate() -> ContextRef;
+     pub fn LLVMContextDispose(C: ContextRef);
+     pub fn LLVMGetMDKindIDInContext(C: ContextRef,
+                                     Name: *const c_char,
+                                     SLen: c_uint)
+                                     -> c_uint;
+     /* Create and destroy modules. */
+     pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char,
+                                              C: ContextRef)
+                                              -> ModuleRef;
+     pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
+     pub fn LLVMCloneModule(M: ModuleRef) -> ModuleRef;
+     pub fn LLVMDisposeModule(M: ModuleRef);
+     /// Data layout. See Module::getDataLayout.
+     pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
+     pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char);
+     /// Target triple. See Module::getTargetTriple.
+     pub fn LLVMGetTarget(M: ModuleRef) -> *const c_char;
+     pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
+     /// See Module::dump.
+     pub fn LLVMDumpModule(M: ModuleRef);
+     /// See Module::setModuleInlineAsm.
+     pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
+     /// See llvm::LLVMTypeKind::getTypeID.
+     pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind;
+     /// See llvm::LLVMType::getContext.
+     pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
+     /* Operations on integer types */
+     pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint)
+                                 -> TypeRef;
+     pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
+     /* Operations on real types */
+     pub fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
+     /* Operations on function types */
+     pub fn LLVMFunctionType(ReturnType: TypeRef,
+                             ParamTypes: *const TypeRef,
+                             ParamCount: c_uint,
+                             IsVarArg: Bool)
+                             -> TypeRef;
+     pub fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
+     pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
+     pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
+     pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef);
+     /* Operations on struct types */
+     pub fn LLVMStructTypeInContext(C: ContextRef,
+                                    ElementTypes: *const TypeRef,
+                                    ElementCount: c_uint,
+                                    Packed: Bool)
+                                    -> TypeRef;
+     pub fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
+     pub fn LLVMGetStructElementTypes(StructTy: TypeRef,
+                                      Dest: *mut TypeRef);
+     pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
+     /* Operations on array, pointer, and vector types (sequence types) */
+     pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
+     pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint)
+                            -> TypeRef;
+     pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint)
+                           -> TypeRef;
+     pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
+     pub fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
+     pub fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
+     pub fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef, V: ValueRef)
+                                   -> *const c_void;
+     pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
+     /* Operations on other types */
+     pub fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
+     pub fn LLVMRustMetadataTypeInContext(C: ContextRef) -> TypeRef;
+     /* Operations on all values */
+     pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
+     pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
+     pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
+     pub fn LLVMDumpValue(Val: ValueRef);
+     pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
+     pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
+     /* Operations on Uses */
+     pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
+     pub fn LLVMGetNextUse(U: UseRef) -> UseRef;
+     pub fn LLVMGetUser(U: UseRef) -> ValueRef;
+     pub fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
+     /* Operations on Users */
+     pub fn LLVMGetNumOperands(Val: ValueRef) -> c_int;
+     pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
+     pub fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
+     /* Operations on constants of any type */
+     pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
+     /* all zeroes */
+     pub fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
+     pub fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef)
+                          -> ValueRef;
+     /* only for isize/vector */
+     pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
+     pub fn LLVMIsConstant(Val: ValueRef) -> Bool;
+     pub fn LLVMIsNull(Val: ValueRef) -> Bool;
+     pub fn LLVMIsUndef(Val: ValueRef) -> Bool;
+     pub fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
+     /* Operations on metadata */
+     pub fn LLVMMDStringInContext(C: ContextRef,
+                                  Str: *const c_char,
+                                  SLen: c_uint)
+                                  -> ValueRef;
+     pub fn LLVMMDNodeInContext(C: ContextRef,
+                                Vals: *const ValueRef,
+                                Count: c_uint)
+                                -> ValueRef;
+     pub fn LLVMAddNamedMetadataOperand(M: ModuleRef,
+                                        Str: *const c_char,
+                                        Val: ValueRef);
+     /* Operations on scalar constants */
+     pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool)
+                         -> ValueRef;
+     pub fn LLVMConstIntOfString(IntTy: TypeRef, Text: *const c_char, Radix: u8)
+                                 -> ValueRef;
+     pub fn LLVMConstIntOfStringAndSize(IntTy: TypeRef,
+                                        Text: *const c_char,
+                                        SLen: c_uint,
+                                        Radix: u8)
+                                        -> ValueRef;
+     pub fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
+     pub fn LLVMConstRealOfString(RealTy: TypeRef, Text: *const c_char)
+                                  -> ValueRef;
+     pub fn LLVMConstRealOfStringAndSize(RealTy: TypeRef,
+                                         Text: *const c_char,
+                                         SLen: c_uint)
+                                         -> ValueRef;
+     pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
+     pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
+     /* Operations on composite constants */
+     pub fn LLVMConstStringInContext(C: ContextRef,
+                                     Str: *const c_char,
+                                     Length: c_uint,
+                                     DontNullTerminate: Bool)
+                                     -> ValueRef;
+     pub fn LLVMConstStructInContext(C: ContextRef,
+                                     ConstantVals: *const ValueRef,
+                                     Count: c_uint,
+                                     Packed: Bool)
+                                     -> ValueRef;
+     pub fn LLVMConstArray(ElementTy: TypeRef,
+                           ConstantVals: *const ValueRef,
+                           Length: c_uint)
+                           -> ValueRef;
+     pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint)
+                            -> ValueRef;
+     /* Constant expressions */
+     pub fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
+     pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
+     pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
+     pub fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
+     pub fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
+     pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
+     pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
+     pub fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+     pub fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                            -> ValueRef;
+     pub fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                            -> ValueRef;
+     pub fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+     pub fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                            -> ValueRef;
+     pub fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                            -> ValueRef;
+     pub fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+     pub fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                            -> ValueRef;
+     pub fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                            -> ValueRef;
+     pub fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstExactSDiv(LHSConstant: ValueRef,
+                               RHSConstant: ValueRef)
+                               -> ValueRef;
+     pub fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+     pub fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                        -> ValueRef;
+     pub fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+     pub fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                         -> ValueRef;
+     pub fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+                          -> ValueRef;
+     pub fn LLVMConstGEP(ConstantVal: ValueRef,
+                         ConstantIndices: *const ValueRef,
+                         NumIndices: c_uint)
+                         -> ValueRef;
+     pub fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
+                                 ConstantIndices: *const ValueRef,
+                                 NumIndices: c_uint)
+                                 -> ValueRef;
+     pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+     pub fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef)
+                          -> ValueRef;
+     pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef)
+                          -> ValueRef;
+     pub fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef)
+                             -> ValueRef;
+     pub fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef)
+                           -> ValueRef;
+     pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+     pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+     pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+     pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+     pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef)
+                              -> ValueRef;
+     pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef)
+                              -> ValueRef;
+     pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                             -> ValueRef;
+     pub fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                   -> ValueRef;
+     pub fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                   -> ValueRef;
+     pub fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                    -> ValueRef;
+     pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef)
+                                 -> ValueRef;
+     pub fn LLVMConstIntCast(ConstantVal: ValueRef,
+                             ToType: TypeRef,
+                             isSigned: Bool)
+                             -> ValueRef;
+     pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef)
+                            -> ValueRef;
+     pub fn LLVMConstSelect(ConstantCondition: ValueRef,
+                            ConstantIfTrue: ValueRef,
+                            ConstantIfFalse: ValueRef)
+                            -> ValueRef;
+     pub fn LLVMConstExtractElement(VectorConstant: ValueRef,
+                                    IndexConstant: ValueRef)
+                                    -> ValueRef;
+     pub fn LLVMConstInsertElement(VectorConstant: ValueRef,
+                                   ElementValueConstant: ValueRef,
+                                   IndexConstant: ValueRef)
+                                   -> ValueRef;
+     pub fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
+                                   VectorBConstant: ValueRef,
+                                   MaskConstant: ValueRef)
+                                   -> ValueRef;
+     pub fn LLVMConstExtractValue(AggConstant: ValueRef,
+                                  IdxList: *const c_uint,
+                                  NumIdx: c_uint)
+                                  -> ValueRef;
+     pub fn LLVMConstInsertValue(AggConstant: ValueRef,
+                                 ElementValueConstant: ValueRef,
+                                 IdxList: *const c_uint,
+                                 NumIdx: c_uint)
+                                 -> ValueRef;
+     pub fn LLVMConstInlineAsm(Ty: TypeRef,
+                               AsmString: *const c_char,
+                               Constraints: *const c_char,
+                               HasSideEffects: Bool,
+                               IsAlignStack: Bool)
+                               -> ValueRef;
+     pub fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
+     /* Operations on global variables, functions, and aliases (globals) */
+     pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
+     pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
+     pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
+     pub fn LLVMSetLinkage(Global: ValueRef, Link: Linkage);
+     pub fn LLVMGetSection(Global: ValueRef) -> *const c_char;
+     pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char);
+     pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
+     pub fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
+     pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
+     pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
+     pub fn LLVMSetDLLStorageClass(V: ValueRef,
+                                   C: DLLStorageClass);
+     /* Operations on global variables */
+     pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef;
+     pub fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
+                                        Ty: TypeRef,
+                                        Name: *const c_char,
+                                        AddressSpace: c_uint)
+                                        -> ValueRef;
+     pub fn LLVMGetNamedGlobal(M: ModuleRef,
+                               Name: *const c_char)
+                               -> ValueRef;
+     pub fn LLVMRustGetOrInsertGlobal(M: ModuleRef,
+                                      Name: *const c_char,
+                                      T: TypeRef)
+                                      -> ValueRef;
+     pub fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
+     pub fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
+     pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
+     pub fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
+     pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
+     pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
+     pub fn LLVMSetInitializer(GlobalVar: ValueRef,
+                               ConstantVal: ValueRef);
+     pub fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
+     pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
+     pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
+     pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
+     pub fn LLVMRustGetNamedValue(M: ModuleRef, Name: *const c_char) -> ValueRef;
+     /* Operations on aliases */
+     pub fn LLVMAddAlias(M: ModuleRef,
+                         Ty: TypeRef,
+                         Aliasee: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+     /* Operations on functions */
+     pub fn LLVMAddFunction(M: ModuleRef,
+                            Name: *const c_char,
+                            FunctionTy: TypeRef)
+                            -> ValueRef;
+     pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
+     pub fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
+     pub fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
+     pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
+     pub fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
+     pub fn LLVMDeleteFunction(Fn: ValueRef);
+     pub fn LLVMRustGetOrInsertFunction(M: ModuleRef,
+                                        Name: *const c_char,
+                                        FunctionTy: TypeRef)
+                                        -> ValueRef;
+     pub fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
+     pub fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
+     pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
+     pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
+     pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
+     pub fn LLVMRustAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: u64);
+     pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: u64);
+     pub fn LLVMRustAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
+     pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef, index: c_uint,
+                                               Name: *const c_char,
+                                               Value: *const c_char);
+     pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef,
+                                             index: c_uint,
+                                             attr: u64);
+     pub fn LLVMRustRemoveFunctionAttrString(Fn: ValueRef,
+                                             index: c_uint,
+                                             Name: *const c_char);
+     pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_uint;
+     pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_uint);
+     /* Operations on parameters */
+     pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
+     pub fn LLVMGetParams(Fn: ValueRef, Params: *const ValueRef);
+     pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
+     pub fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
+     pub fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
+     pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
+     pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
+     pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
+     pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
+     pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
+     pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
+     pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
+     /* Operations on basic blocks */
+     pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
+     pub fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
+     pub fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
+     pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
+     pub fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
+     pub fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *const ValueRef);
+     pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+     pub fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+     pub fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+     pub fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+     pub fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+     pub fn LLVMAppendBasicBlockInContext(C: ContextRef,
+                                          Fn: ValueRef,
+                                          Name: *const c_char)
+                                          -> BasicBlockRef;
+     pub fn LLVMInsertBasicBlockInContext(C: ContextRef,
+                                          BB: BasicBlockRef,
+                                          Name: *const c_char)
+                                          -> BasicBlockRef;
+     pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
+     pub fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef,
+                                    MoveAfter: BasicBlockRef);
+     pub fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef,
+                                     MoveBefore: BasicBlockRef);
+     /* Operations on instructions */
+     pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
+     pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
+     pub fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
+     pub fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
+     pub fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
+     pub fn LLVMInstructionEraseFromParent(Inst: ValueRef);
+     /* Operations on call sites */
+     pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
+     pub fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
+     pub fn LLVMAddInstrAttribute(Instr: ValueRef,
+                                  index: c_uint,
+                                  IA: c_uint);
+     pub fn LLVMRemoveInstrAttribute(Instr: ValueRef,
+                                     index: c_uint,
+                                     IA: c_uint);
+     pub fn LLVMSetInstrParamAlignment(Instr: ValueRef,
+                                       index: c_uint,
+                                       align: c_uint);
+     pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef,
+                                     index: c_uint,
+                                     Val: u64);
+     pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: ValueRef,
+                                                   index: c_uint,
+                                                   bytes: u64);
+     /* Operations on call instructions (only) */
+     pub fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
+     pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
+     /* Operations on load/store instructions (only) */
+     pub fn LLVMGetVolatile(MemoryAccessInst: ValueRef) -> Bool;
+     pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool);
+     /* Operations on phi nodes */
+     pub fn LLVMAddIncoming(PhiNode: ValueRef,
+                            IncomingValues: *const ValueRef,
+                            IncomingBlocks: *const BasicBlockRef,
+                            Count: c_uint);
+     pub fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
+     pub fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint)
+                                 -> ValueRef;
+     pub fn LLVMGetIncomingBlock(PhiNode: ValueRef, Index: c_uint)
+                                 -> BasicBlockRef;
+     /* Instruction builders */
+     pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
+     pub fn LLVMPositionBuilder(Builder: BuilderRef,
+                                Block: BasicBlockRef,
+                                Instr: ValueRef);
+     pub fn LLVMPositionBuilderBefore(Builder: BuilderRef,
+                                      Instr: ValueRef);
+     pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
+                                     Block: BasicBlockRef);
+     pub fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
+     pub fn LLVMClearInsertionPosition(Builder: BuilderRef);
+     pub fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
+     pub fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
+                                          Instr: ValueRef,
+                                          Name: *const c_char);
+     pub fn LLVMDisposeBuilder(Builder: BuilderRef);
+     /* Metadata */
+     pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
+     pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
+     pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
+     /* Terminators */
+     pub fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
+     pub fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
+     pub fn LLVMBuildAggregateRet(B: BuilderRef,
+                                  RetVals: *const ValueRef,
+                                  N: c_uint)
+                                  -> ValueRef;
+     pub fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
+     pub fn LLVMBuildCondBr(B: BuilderRef,
+                            If: ValueRef,
+                            Then: BasicBlockRef,
+                            Else: BasicBlockRef)
+                            -> ValueRef;
+     pub fn LLVMBuildSwitch(B: BuilderRef,
+                            V: ValueRef,
+                            Else: BasicBlockRef,
+                            NumCases: c_uint)
+                            -> ValueRef;
+     pub fn LLVMBuildIndirectBr(B: BuilderRef,
+                                Addr: ValueRef,
+                                NumDests: c_uint)
+                                -> ValueRef;
+     pub fn LLVMRustBuildInvoke(B: BuilderRef,
+                                Fn: ValueRef,
+                                Args: *const ValueRef,
+                                NumArgs: c_uint,
+                                Then: BasicBlockRef,
+                                Catch: BasicBlockRef,
+                                Bundle: OperandBundleDefRef,
+                                Name: *const c_char)
+                                -> ValueRef;
+     pub fn LLVMRustBuildLandingPad(B: BuilderRef,
+                                    Ty: TypeRef,
+                                    PersFn: ValueRef,
+                                    NumClauses: c_uint,
+                                    Name: *const c_char,
+                                    F: ValueRef)
+                                    -> ValueRef;
+     pub fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
+     pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
+     pub fn LLVMRustBuildCleanupPad(B: BuilderRef,
+                                    ParentPad: ValueRef,
+                                    ArgCnt: c_uint,
+                                    Args: *const ValueRef,
+                                    Name: *const c_char) -> ValueRef;
+     pub fn LLVMRustBuildCleanupRet(B: BuilderRef,
+                                    CleanupPad: ValueRef,
+                                    UnwindBB: BasicBlockRef) -> ValueRef;
+     pub fn LLVMRustBuildCatchPad(B: BuilderRef,
+                                  ParentPad: ValueRef,
+                                  ArgCnt: c_uint,
+                                  Args: *const ValueRef,
+                                  Name: *const c_char) -> ValueRef;
+     pub fn LLVMRustBuildCatchRet(B: BuilderRef,
+                                  Pad: ValueRef,
+                                  BB: BasicBlockRef) -> ValueRef;
+     pub fn LLVMRustBuildCatchSwitch(Builder: BuilderRef,
+                                     ParentPad: ValueRef,
+                                     BB: BasicBlockRef,
+                                     NumHandlers: c_uint,
+                                     Name: *const c_char) -> ValueRef;
+     pub fn LLVMRustAddHandler(CatchSwitch: ValueRef,
+                               Handler: BasicBlockRef);
+     pub fn LLVMRustSetPersonalityFn(B: BuilderRef, Pers: ValueRef);
+     /* Add a case to the switch instruction */
+     pub fn LLVMAddCase(Switch: ValueRef,
+                        OnVal: ValueRef,
+                        Dest: BasicBlockRef);
+     /* Add a destination to the indirectbr instruction */
+     pub fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
+     /* Add a clause to the landing pad instruction */
+     pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
+     /* Set the cleanup on a landing pad instruction */
+     pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
+     /* Arithmetic */
+     pub fn LLVMBuildAdd(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMBuildNSWAdd(B: BuilderRef,
+                            LHS: ValueRef,
+                            RHS: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildNUWAdd(B: BuilderRef,
+                            LHS: ValueRef,
+                            RHS: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildFAdd(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildSub(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMBuildNSWSub(B: BuilderRef,
+                            LHS: ValueRef,
+                            RHS: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildNUWSub(B: BuilderRef,
+                            LHS: ValueRef,
+                            RHS: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildFSub(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildMul(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMBuildNSWMul(B: BuilderRef,
+                            LHS: ValueRef,
+                            RHS: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildNUWMul(B: BuilderRef,
+                            LHS: ValueRef,
+                            RHS: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildFMul(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildUDiv(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildSDiv(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildExactSDiv(B: BuilderRef,
+                               LHS: ValueRef,
+                               RHS: ValueRef,
+                               Name: *const c_char)
+                               -> ValueRef;
+     pub fn LLVMBuildFDiv(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildURem(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildSRem(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildFRem(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildShl(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMBuildLShr(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildAShr(B: BuilderRef,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildAnd(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMBuildOr(B: BuilderRef,
+                        LHS: ValueRef,
+                        RHS: ValueRef,
+                        Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildXor(B: BuilderRef,
+                         LHS: ValueRef,
+                         RHS: ValueRef,
+                         Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMBuildBinOp(B: BuilderRef,
+                           Op: Opcode,
+                           LHS: ValueRef,
+                           RHS: ValueRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+     pub fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef);
+     /* Memory */
+     pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
+     pub fn LLVMBuildLoad(B: BuilderRef,
+                          PointerVal: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef)
+                           -> ValueRef;
+     pub fn LLVMBuildGEP(B: BuilderRef,
+                         Pointer: ValueRef,
+                         Indices: *const ValueRef,
+                         NumIndices: c_uint,
+                         Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMBuildInBoundsGEP(B: BuilderRef,
+                                 Pointer: ValueRef,
+                                 Indices: *const ValueRef,
+                                 NumIndices: c_uint,
+                                 Name: *const c_char)
+                                 -> ValueRef;
+     pub fn LLVMBuildStructGEP(B: BuilderRef,
+                               Pointer: ValueRef,
+                               Idx: c_uint,
+                               Name: *const c_char)
+                               -> ValueRef;
+     pub fn LLVMBuildGlobalString(B: BuilderRef,
+                                  Str: *const c_char,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+     pub fn LLVMBuildGlobalStringPtr(B: BuilderRef,
+                                     Str: *const c_char,
+                                     Name: *const c_char)
+                                     -> ValueRef;
+     /* Casts */
+     pub fn LLVMBuildTrunc(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+     pub fn LLVMBuildZExt(B: BuilderRef,
+                          Val: ValueRef,
+                          DestTy: TypeRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildSExt(B: BuilderRef,
+                          Val: ValueRef,
+                          DestTy: TypeRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildFPToUI(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildFPToSI(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildUIToFP(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildSIToFP(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildFPTrunc(B: BuilderRef,
+                             Val: ValueRef,
+                             DestTy: TypeRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+     pub fn LLVMBuildFPExt(B: BuilderRef,
+                           Val: ValueRef,
+                           DestTy: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+     pub fn LLVMBuildPtrToInt(B: BuilderRef,
+                              Val: ValueRef,
+                              DestTy: TypeRef,
+                              Name: *const c_char)
+                              -> ValueRef;
+     pub fn LLVMBuildIntToPtr(B: BuilderRef,
+                              Val: ValueRef,
+                              DestTy: TypeRef,
+                              Name: *const c_char)
+                              -> ValueRef;
+     pub fn LLVMBuildBitCast(B: BuilderRef,
+                             Val: ValueRef,
+                             DestTy: TypeRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+     pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
+                                   Val: ValueRef,
+                                   DestTy: TypeRef,
+                                   Name: *const c_char)
+                                   -> ValueRef;
+     pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
+                                   Val: ValueRef,
+                                   DestTy: TypeRef,
+                                   Name: *const c_char)
+                                   -> ValueRef;
+     pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
+                                    Val: ValueRef,
+                                    DestTy: TypeRef,
+                                    Name: *const c_char)
+                                    -> ValueRef;
+     pub fn LLVMBuildCast(B: BuilderRef,
+                          Op: Opcode,
+                          Val: ValueRef,
+                          DestTy: TypeRef,
+                          Name: *const c_char) -> ValueRef;
+     pub fn LLVMBuildPointerCast(B: BuilderRef,
+                                 Val: ValueRef,
+                                 DestTy: TypeRef,
+                                 Name: *const c_char)
+                                 -> ValueRef;
+     pub fn LLVMBuildIntCast(B: BuilderRef,
+                             Val: ValueRef,
+                             DestTy: TypeRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+     pub fn LLVMBuildFPCast(B: BuilderRef,
+                            Val: ValueRef,
+                            DestTy: TypeRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     /* Comparisons */
+     pub fn LLVMBuildICmp(B: BuilderRef,
+                          Op: c_uint,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     pub fn LLVMBuildFCmp(B: BuilderRef,
+                          Op: c_uint,
+                          LHS: ValueRef,
+                          RHS: ValueRef,
+                          Name: *const c_char)
+                          -> ValueRef;
+     /* Miscellaneous instructions */
+     pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+                         -> ValueRef;
+     pub fn LLVMRustBuildCall(B: BuilderRef,
+                              Fn: ValueRef,
+                              Args: *const ValueRef,
+                              NumArgs: c_uint,
+                              Bundle: OperandBundleDefRef,
+                              Name: *const c_char)
+                              -> ValueRef;
+     pub fn LLVMBuildSelect(B: BuilderRef,
+                            If: ValueRef,
+                            Then: ValueRef,
+                            Else: ValueRef,
+                            Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildVAArg(B: BuilderRef,
+                           list: ValueRef,
+                           Ty: TypeRef,
+                           Name: *const c_char)
+                           -> ValueRef;
+     pub fn LLVMBuildExtractElement(B: BuilderRef,
+                                    VecVal: ValueRef,
+                                    Index: ValueRef,
+                                    Name: *const c_char)
+                                    -> ValueRef;
+     pub fn LLVMBuildInsertElement(B: BuilderRef,
+                                   VecVal: ValueRef,
+                                   EltVal: ValueRef,
+                                   Index: ValueRef,
+                                   Name: *const c_char)
+                                   -> ValueRef;
+     pub fn LLVMBuildShuffleVector(B: BuilderRef,
+                                   V1: ValueRef,
+                                   V2: ValueRef,
+                                   Mask: ValueRef,
+                                   Name: *const c_char)
+                                   -> ValueRef;
+     pub fn LLVMBuildExtractValue(B: BuilderRef,
+                                  AggVal: ValueRef,
+                                  Index: c_uint,
+                                  Name: *const c_char)
+                                  -> ValueRef;
+     pub fn LLVMBuildInsertValue(B: BuilderRef,
+                                 AggVal: ValueRef,
+                                 EltVal: ValueRef,
+                                 Index: c_uint,
+                                 Name: *const c_char)
+                                 -> ValueRef;
+     pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
+                            -> ValueRef;
+     pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
+                               -> ValueRef;
+     pub fn LLVMBuildPtrDiff(B: BuilderRef,
+                             LHS: ValueRef,
+                             RHS: ValueRef,
+                             Name: *const c_char)
+                             -> ValueRef;
+     /* Atomic Operations */
+     pub fn LLVMRustBuildAtomicLoad(B: BuilderRef,
+                                    PointerVal: ValueRef,
+                                    Name: *const c_char,
+                                    Order: AtomicOrdering,
+                                    Alignment: c_uint)
+                                    -> ValueRef;
+     pub fn LLVMRustBuildAtomicStore(B: BuilderRef,
+                                     Val: ValueRef,
+                                     Ptr: ValueRef,
+                                     Order: AtomicOrdering,
+                                     Alignment: c_uint)
+                                     -> ValueRef;
+     pub fn LLVMRustBuildAtomicCmpXchg(B: BuilderRef,
+                                       LHS: ValueRef,
+                                       CMP: ValueRef,
+                                       RHS: ValueRef,
+                                       Order: AtomicOrdering,
+                                       FailureOrder: AtomicOrdering,
+                                       Weak: Bool)
+                                       -> ValueRef;
+     pub fn LLVMBuildAtomicRMW(B: BuilderRef,
+                               Op: AtomicRmwBinOp,
+                               LHS: ValueRef,
+                               RHS: ValueRef,
+                               Order: AtomicOrdering,
+                               SingleThreaded: Bool)
+                               -> ValueRef;
+     pub fn LLVMRustBuildAtomicFence(B: BuilderRef,
+                                     Order: AtomicOrdering,
+                                     Scope: SynchronizationScope);
+     /* Selected entries from the downcasts. */
+     pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
+     pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef;
+     /// Writes a module to the specified path. Returns 0 on success.
+     pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int;
+     /// Creates target data from a target layout string.
+     pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
+     /// Number of bytes clobbered when doing a Store to *T.
+     pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
+                                -> c_ulonglong;
+     /// Number of bytes clobbered when doing a Store to *T.
+     pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
+                                 -> c_ulonglong;
+     /// Distance between successive elements in an array of T. Includes ABI padding.
+     pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_ulonglong;
+     /// Returns the preferred alignment of a type.
+     pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                         -> c_uint;
+     /// Returns the minimum alignment of a type.
+     pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                   -> c_uint;
+     /// Computes the byte offset of the indexed struct element for a
+     /// target.
+     pub fn LLVMOffsetOfElement(TD: TargetDataRef,
+                                StructTy: TypeRef,
+                                Element: c_uint)
+                                -> c_ulonglong;
+     /// Returns the minimum alignment of a type when part of a call frame.
+     pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+                                         -> c_uint;
+     /// Disposes target data.
+     pub fn LLVMDisposeTargetData(TD: TargetDataRef);
+     /// Creates a pass manager.
+     pub fn LLVMCreatePassManager() -> PassManagerRef;
+     /// Creates a function-by-function pass manager
+     pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
+                                                   -> PassManagerRef;
+     /// Disposes a pass manager.
+     pub fn LLVMDisposePassManager(PM: PassManagerRef);
+     /// Runs a pass manager on a module.
+     pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
+     /// Runs the function passes on the provided function.
+     pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
+                                       -> Bool;
+     /// Initializes all the function passes scheduled in the manager
+     pub fn LLVMInitializeFunctionPassManager(FPM: PassManagerRef) -> Bool;
+     /// Finalizes all the function passes scheduled in the manager
+     pub fn LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
+     pub fn LLVMInitializePasses();
+     /// Adds a verification pass.
+     pub fn LLVMAddVerifierPass(PM: PassManagerRef);
+     pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
+     pub fn LLVMAddIPSCCPPass(PM: PassManagerRef);
+     pub fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
+     pub fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
+     pub fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
+     pub fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
+     pub fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
+     pub fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
+     pub fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
+     pub fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
+     pub fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
+     pub fn LLVMAddReassociatePass(PM: PassManagerRef);
+     pub fn LLVMAddLoopRotatePass(PM: PassManagerRef);
+     pub fn LLVMAddLICMPass(PM: PassManagerRef);
+     pub fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
+     pub fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
+     pub fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
+     pub fn LLVMAddGVNPass(PM: PassManagerRef);
+     pub fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
+     pub fn LLVMAddSCCPPass(PM: PassManagerRef);
+     pub fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
+     pub fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
+     pub fn LLVMAddConstantMergePass(PM: PassManagerRef);
+     pub fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
+     pub fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
+     pub fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
+     pub fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
+     pub fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
+     pub fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
+     pub fn LLVMAddPruneEHPass(PM: PassManagerRef);
+     pub fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
+     pub fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
+     pub fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
+     pub fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
+     pub fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
+     pub fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
+     pub fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
+     pub fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
+                                              OptimizationLevel: c_uint);
+     pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
+                                               Value: Bool);
+     pub fn LLVMPassManagerBuilderSetDisableUnitAtATime(
+         PMB: PassManagerBuilderRef,
+         Value: Bool);
+     pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(
+         PMB: PassManagerBuilderRef,
+         Value: Bool);
+     pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(
+         PMB: PassManagerBuilderRef,
+         Value: Bool);
+     pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(
+         PMB: PassManagerBuilderRef,
+         threshold: c_uint);
+     pub fn LLVMPassManagerBuilderPopulateModulePassManager(
+         PMB: PassManagerBuilderRef,
+         PM: PassManagerRef);
+     pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(
+         PMB: PassManagerBuilderRef,
+         PM: PassManagerRef);
+     pub fn LLVMPassManagerBuilderPopulateLTOPassManager(
+         PMB: PassManagerBuilderRef,
+         PM: PassManagerRef,
+         Internalize: Bool,
+         RunInliner: Bool);
+     /// Destroys a memory buffer.
+     pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
+     /* Stuff that's in rustllvm/ because it's not upstream yet. */
+     /// Opens an object file.
+     pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
+     /// Closes an object file.
+     pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
+     /// Enumerates the sections in an object file.
+     pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
+     /// Destroys a section iterator.
+     pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
+     /// Returns true if the section iterator is at the end of the section
+     /// list:
+     pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
+                                       SI: SectionIteratorRef)
+                                       -> Bool;
+     /// Moves the section iterator to point to the next section.
+     pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
+     /// Returns the current section size.
+     pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
+     /// Returns the current section contents as a string buffer.
+     pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
+     /// Reads the given file and returns it as a memory buffer. Use
+     /// LLVMDisposeMemoryBuffer() to get rid of it.
+     pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
+                                                         -> MemoryBufferRef;
+     /// Borrows the contents of the memory buffer (doesn't copy it)
+     pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
+                                                  InputDataLength: size_t,
+                                                  BufferName: *const c_char,
+                                                  RequiresNull: Bool)
+                                                  -> MemoryBufferRef;
+     pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy(InputData: *const c_char,
+                                                      InputDataLength: size_t,
+                                                      BufferName: *const c_char)
+                                                      -> MemoryBufferRef;
+     pub fn LLVMIsMultithreaded() -> Bool;
+     pub fn LLVMStartMultithreaded() -> Bool;
+     /// Returns a string describing the last error caused by an LLVMRust* call.
+     pub fn LLVMRustGetLastError() -> *const c_char;
+     /// Print the pass timings since static dtors aren't picking them up.
+     pub fn LLVMRustPrintPassTimings();
+     pub fn LLVMStructCreateNamed(C: ContextRef, Name: *const c_char) -> TypeRef;
+     pub fn LLVMStructSetBody(StructTy: TypeRef,
+                              ElementTypes: *const TypeRef,
+                              ElementCount: c_uint,
+                              Packed: Bool);
+     pub fn LLVMConstNamedStruct(S: TypeRef,
+                                 ConstantVals: *const ValueRef,
+                                 Count: c_uint)
+                                 -> ValueRef;
+     /// Enables LLVM debug output.
+     pub fn LLVMRustSetDebug(Enabled: c_int);
+     /// Prepares inline assembly.
+     pub fn LLVMRustInlineAsm(Ty: TypeRef,
+                              AsmString: *const c_char,
+                              Constraints: *const c_char,
+                              SideEffects: Bool,
+                              AlignStack: Bool,
+                              Dialect: AsmDialect)
+                              -> ValueRef;
+     pub fn LLVMRustDebugMetadataVersion() -> u32;
+     pub fn LLVMRustVersionMajor() -> u32;
+     pub fn LLVMRustVersionMinor() -> u32;
+     pub fn LLVMRustAddModuleFlag(M: ModuleRef,
+                                  name: *const c_char,
+                                  value: u32);
+     pub fn LLVMRustDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
+     pub fn LLVMRustDIBuilderDispose(Builder: DIBuilderRef);
+     pub fn LLVMRustDIBuilderFinalize(Builder: DIBuilderRef);
+     pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: DIBuilderRef,
+                                               Lang: c_uint,
+                                               File: *const c_char,
+                                               Dir: *const c_char,
+                                               Producer: *const c_char,
+                                               isOptimized: bool,
+                                               Flags: *const c_char,
+                                               RuntimeVer: c_uint,
+                                               SplitName: *const c_char)
+                                               -> DIDescriptor;
+     pub fn LLVMRustDIBuilderCreateFile(Builder: DIBuilderRef,
+                                        Filename: *const c_char,
+                                        Directory: *const c_char)
+                                        -> DIFile;
+     pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: DIBuilderRef,
+                                                  File: DIFile,
+                                                  ParameterTypes: DIArray)
+                                                  -> DICompositeType;
+     pub fn LLVMRustDIBuilderCreateFunction(Builder: DIBuilderRef,
+                                            Scope: DIDescriptor,
+                                            Name: *const c_char,
+                                            LinkageName: *const c_char,
+                                            File: DIFile,
+                                            LineNo: c_uint,
+                                            Ty: DIType,
+                                            isLocalToUnit: bool,
+                                            isDefinition: bool,
+                                            ScopeLine: c_uint,
+                                            Flags: c_uint,
+                                            isOptimized: bool,
+                                            Fn: ValueRef,
+                                            TParam: DIArray,
+                                            Decl: DIDescriptor)
+                                            -> DISubprogram;
+     pub fn LLVMRustDIBuilderCreateBasicType(Builder: DIBuilderRef,
+                                             Name: *const c_char,
+                                             SizeInBits: u64,
+                                             AlignInBits: u64,
+                                             Encoding: c_uint)
+                                             -> DIBasicType;
+     pub fn LLVMRustDIBuilderCreatePointerType(Builder: DIBuilderRef,
+                                           PointeeTy: DIType,
+                                           SizeInBits: u64,
+                                           AlignInBits: u64,
+                                           Name: *const c_char)
+                                           -> DIDerivedType;
+     pub fn LLVMRustDIBuilderCreateStructType(Builder: DIBuilderRef,
+                                              Scope: DIDescriptor,
+                                              Name: *const c_char,
+                                              File: DIFile,
+                                              LineNumber: c_uint,
+                                              SizeInBits: u64,
+                                              AlignInBits: u64,
+                                              Flags: c_uint,
+                                              DerivedFrom: DIType,
+                                              Elements: DIArray,
+                                              RunTimeLang: c_uint,
+                                              VTableHolder: DIType,
+                                              UniqueId: *const c_char)
+                                              -> DICompositeType;
+     pub fn LLVMRustDIBuilderCreateMemberType(Builder: DIBuilderRef,
+                                              Scope: DIDescriptor,
+                                              Name: *const c_char,
+                                              File: DIFile,
+                                              LineNo: c_uint,
+                                              SizeInBits: u64,
+                                              AlignInBits: u64,
+                                              OffsetInBits: u64,
+                                              Flags: c_uint,
+                                              Ty: DIType)
+                                              -> DIDerivedType;
+     pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: DIBuilderRef,
+                                                Scope: DIScope,
+                                                File: DIFile,
+                                                Line: c_uint,
+                                                Col: c_uint)
+                                                -> DILexicalBlock;
+     pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
+                                                  Context: DIScope,
+                                                  Name: *const c_char,
+                                                  LinkageName: *const c_char,
+                                                  File: DIFile,
+                                                  LineNo: c_uint,
+                                                  Ty: DIType,
+                                                  isLocalToUnit: bool,
+                                                  Val: ValueRef,
+                                                  Decl: DIDescriptor)
+                                                  -> DIGlobalVariable;
+     pub fn LLVMRustDIBuilderCreateVariable(Builder: DIBuilderRef,
+                                            Tag: c_uint,
+                                            Scope: DIDescriptor,
+                                            Name: *const c_char,
+                                            File: DIFile,
+                                            LineNo: c_uint,
+                                            Ty: DIType,
+                                            AlwaysPreserve: bool,
+                                            Flags: c_uint,
+                                            AddrOps: *const i64,
+                                            AddrOpsCount: c_uint,
+                                            ArgNo: c_uint)
+                                            -> DIVariable;
+     pub fn LLVMRustDIBuilderCreateArrayType(Builder: DIBuilderRef,
+                                             Size: u64,
+                                             AlignInBits: u64,
+                                             Ty: DIType,
+                                             Subscripts: DIArray)
+                                             -> DIType;
+     pub fn LLVMRustDIBuilderCreateVectorType(Builder: DIBuilderRef,
+                                              Size: u64,
+                                              AlignInBits: u64,
+                                              Ty: DIType,
+                                              Subscripts: DIArray)
+                                              -> DIType;
+     pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef,
+                                                 Lo: i64,
+                                                 Count: i64)
+                                                 -> DISubrange;
+     pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: DIBuilderRef,
+                                              Ptr: *const DIDescriptor,
+                                              Count: c_uint)
+                                              -> DIArray;
+     pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef,
+                                                Val: ValueRef,
+                                                VarInfo: DIVariable,
+                                                AddrOps: *const i64,
+                                                AddrOpsCount: c_uint,
+                                                DL: ValueRef,
+                                                InsertAtEnd: BasicBlockRef)
+                                                -> ValueRef;
+     pub fn LLVMRustDIBuilderInsertDeclareBefore(Builder: DIBuilderRef,
+                                                 Val: ValueRef,
+                                                 VarInfo: DIVariable,
+                                                 AddrOps: *const i64,
+                                                 AddrOpsCount: c_uint,
+                                                 DL: ValueRef,
+                                                 InsertBefore: ValueRef)
+                                                 -> ValueRef;
+     pub fn LLVMRustDIBuilderCreateEnumerator(Builder: DIBuilderRef,
+                                              Name: *const c_char,
+                                              Val: u64)
+                                              -> DIEnumerator;
+     pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: DIBuilderRef,
+                                                   Scope: DIScope,
+                                                   Name: *const c_char,
+                                                   File: DIFile,
+                                                   LineNumber: c_uint,
+                                                   SizeInBits: u64,
+                                                   AlignInBits: u64,
+                                                   Elements: DIArray,
+                                                   ClassType: DIType)
+                                                   -> DIType;
+     pub fn LLVMRustDIBuilderCreateUnionType(Builder: DIBuilderRef,
+                                             Scope: DIScope,
+                                             Name: *const c_char,
+                                             File: DIFile,
+                                             LineNumber: c_uint,
+                                             SizeInBits: u64,
+                                             AlignInBits: u64,
+                                             Flags: c_uint,
+                                             Elements: DIArray,
+                                             RunTimeLang: c_uint,
+                                             UniqueId: *const c_char)
+                                             -> DIType;
+     pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
+     pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
+                                                         Scope: DIScope,
+                                                         Name: *const c_char,
+                                                         Ty: DIType,
+                                                         File: DIFile,
+                                                         LineNo: c_uint,
+                                                         ColumnNo: c_uint)
+                                                         -> DITemplateTypeParameter;
+     pub fn LLVMRustDIBuilderCreateNameSpace(Builder: DIBuilderRef,
+                                             Scope: DIScope,
+                                             Name: *const c_char,
+                                             File: DIFile,
+                                             LineNo: c_uint)
+                                             -> DINameSpace;
+     pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: DIBuilderRef,
+                                                CompositeType: DIType,
+                                                TypeArray: DIArray);
+     pub fn LLVMRustDIBuilderCreateDebugLocation(Context: ContextRef,
+                                                 Line: c_uint,
+                                                 Column: c_uint,
+                                                 Scope: DIScope,
+                                                 InlinedAt: MetadataRef)
+                                                 -> ValueRef;
+     pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
+     pub fn LLVMRustDIBuilderCreateOpPlus() -> i64;
+     pub fn LLVMRustWriteTypeToString(Type: TypeRef, s: RustStringRef);
+     pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef);
+     pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
+     pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
+     pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
+     pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind;
+     pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
+     pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);
+     pub fn LLVMRustHasFeature(T: TargetMachineRef,
+                               s: *const c_char) -> bool;
++    pub fn LLVMRustPrintTargetCPUs(T: TargetMachineRef);
++    pub fn LLVMRustPrintTargetFeatures(T: TargetMachineRef);
++
+     pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
+                                        CPU: *const c_char,
+                                        Features: *const c_char,
+                                        Model: CodeModel,
+                                        Reloc: RelocMode,
+                                        Level: CodeGenOptLevel,
+                                        UseSoftFP: bool,
+                                        PositionIndependentExecutable: bool,
+                                        FunctionSections: bool,
+                                        DataSections: bool) -> TargetMachineRef;
+     pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
+     pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef,
+                                      PM: PassManagerRef,
+                                      M: ModuleRef);
+     pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
+                                          M: ModuleRef,
+                                          DisableSimplifyLibCalls: bool);
+     pub fn LLVMRustConfigurePassManagerBuilder(PMB: PassManagerBuilderRef,
+                                                OptLevel: CodeGenOptLevel,
+                                                MergeFunctions: bool,
+                                                SLPVectorize: bool,
+                                                LoopVectorize: bool);
+     pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
+                                   DisableSimplifyLibCalls: bool);
+     pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
+     pub fn LLVMRustWriteOutputFile(T: TargetMachineRef,
+                                    PM: PassManagerRef,
+                                    M: ModuleRef,
+                                    Output: *const c_char,
+                                    FileType: FileType)
+                                    -> LLVMRustResult;
+     pub fn LLVMRustPrintModule(PM: PassManagerRef,
+                                M: ModuleRef,
+                                Output: *const c_char);
+     pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
+     pub fn LLVMRustPrintPasses();
+     pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
+     pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef,
+                                        AddLifetimes: bool);
+     pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef,
+                                          bc: *const c_char,
+                                          len: size_t) -> bool;
+     pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
+                                       syms: *const *const c_char,
+                                       len: size_t);
+     pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
+     pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef;
+     pub fn LLVMRustArchiveIteratorNew(AR: ArchiveRef) -> ArchiveIteratorRef;
+     pub fn LLVMRustArchiveIteratorNext(AIR: ArchiveIteratorRef) -> ArchiveChildRef;
+     pub fn LLVMRustArchiveChildName(ACR: ArchiveChildRef,
+                                     size: *mut size_t) -> *const c_char;
+     pub fn LLVMRustArchiveChildData(ACR: ArchiveChildRef,
+                                     size: *mut size_t) -> *const c_char;
+     pub fn LLVMRustArchiveChildFree(ACR: ArchiveChildRef);
+     pub fn LLVMRustArchiveIteratorFree(AIR: ArchiveIteratorRef);
+     pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
+     pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
+                                   data: *mut *const c_char) -> size_t;
+     pub fn LLVMRustWriteTwineToString(T: TwineRef, s: RustStringRef);
+     pub fn LLVMContextSetDiagnosticHandler(C: ContextRef,
+                                            Handler: DiagnosticHandler,
+                                            DiagnosticContext: *mut c_void);
+     pub fn LLVMRustUnpackOptimizationDiagnostic(DI: DiagnosticInfoRef,
+                                                 pass_name_out: *mut *const c_char,
+                                                 function_out: *mut ValueRef,
+                                                 debugloc_out: *mut DebugLocRef,
+                                                 message_out: *mut TwineRef);
+     pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef,
+                                              cookie_out: *mut c_uint,
+                                              message_out: *mut TwineRef,
+                                              instruction_out: *mut ValueRef);
+     pub fn LLVMRustWriteDiagnosticInfoToString(DI: DiagnosticInfoRef,
+                                                s: RustStringRef);
+     pub fn LLVMGetDiagInfoSeverity(DI: DiagnosticInfoRef) -> DiagnosticSeverity;
+     pub fn LLVMRustGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind;
+     pub fn LLVMRustWriteDebugLocToString(C: ContextRef,
+                                          DL: DebugLocRef,
+                                          s: RustStringRef);
+     pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: ContextRef,
+                                                  H: InlineAsmDiagHandler,
+                                                  CX: *mut c_void);
+     pub fn LLVMRustWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef);
+     pub fn LLVMRustWriteArchive(Dst: *const c_char,
+                                 NumMembers: size_t,
+                                 Members: *const RustArchiveMemberRef,
+                                 WriteSymbtab: bool,
+                                 Kind: ArchiveKind) ->
+                                 LLVMRustResult;
+     pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
+                                     Name: *const c_char,
+                                     Child: ArchiveChildRef) -> RustArchiveMemberRef;
+     pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef);
+     pub fn LLVMRustSetDataLayoutFromTargetMachine(M: ModuleRef,
+                                                   TM: TargetMachineRef);
+     pub fn LLVMRustGetModuleDataLayout(M: ModuleRef) -> TargetDataRef;
+     pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char,
+                                          Inputs: *const ValueRef,
+                                          NumInputs: c_uint)
+                                          -> OperandBundleDefRef;
+     pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef);
+     pub fn LLVMRustPositionBuilderAtStart(B: BuilderRef, BB: BasicBlockRef);
+     pub fn LLVMRustSetComdat(M: ModuleRef, V: ValueRef, Name: *const c_char);
+     pub fn LLVMRustUnsetComdat(V: ValueRef);
+     pub fn LLVMRustSetModulePIELevel(M: ModuleRef);
+ }
+ // LLVM requires symbols from this library, but apparently they're not printed
+ // during llvm-config?
+ #[cfg(windows)]
+ #[link(name = "ole32")]
+ extern {}
index 422e3d436b42994fcc67918fa2f5144c39f8b1ac,8ce2fa762f9e2606103399f371c6db5afd9a2329..4e6c6013576f6beac379f8b429e11fabaf614ab6
  
  use back::lto;
  use back::link::{get_linker, remove};
+ use rustc_incremental::save_trans_partition;
  use session::config::{OutputFilenames, Passes, SomePasses, AllPasses};
  use session::Session;
  use session::config::{self, OutputType};
  use llvm;
  use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef};
  use llvm::SMDiagnosticRef;
- use {CrateTranslation, ModuleTranslation};
+ use {CrateTranslation, ModuleLlvm, ModuleSource, ModuleTranslation};
  use util::common::time;
  use util::common::path2cstr;
+ use util::fs::link_or_copy;
  use errors::{self, Handler, Level, DiagnosticBuilder};
  use errors::emitter::Emitter;
  use syntax_pos::MultiSpan;
+ use context::{is_pie_binary, get_reloc_model};
  
  use std::collections::HashMap;
  use std::ffi::{CStr, CString};
@@@ -33,21 -36,6 +36,21 @@@ use std::sync::mpsc::channel
  use std::thread;
  use libc::{c_uint, c_void};
  
-     ("pic", llvm::RelocPIC),
-     ("static", llvm::RelocStatic),
-     ("default", llvm::RelocDefault),
-     ("dynamic-no-pic", llvm::RelocDynamicNoPic),
 +pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 4] = [
- pub const CODE_GEN_MODEL_ARGS : [(&'static str, llvm::CodeGenModel); 5] = [
-     ("default", llvm::CodeModelDefault),
-     ("small", llvm::CodeModelSmall),
-     ("kernel", llvm::CodeModelKernel),
-     ("medium", llvm::CodeModelMedium),
-     ("large", llvm::CodeModelLarge),
++    ("pic", llvm::RelocMode::PIC),
++    ("static", llvm::RelocMode::Static),
++    ("default", llvm::RelocMode::Default),
++    ("dynamic-no-pic", llvm::RelocMode::DynamicNoPic),
 +];
 +
++pub const CODE_GEN_MODEL_ARGS : [(&'static str, llvm::CodeModel); 5] = [
++    ("default", llvm::CodeModel::Default),
++    ("small", llvm::CodeModel::Small),
++    ("kernel", llvm::CodeModel::Kernel),
++    ("medium", llvm::CodeModel::Medium),
++    ("large", llvm::CodeModel::Large),
 +];
 +
  pub fn llvm_err(handler: &errors::Handler, msg: String) -> ! {
      match llvm::last_error() {
          Some(err) => panic!(handler.fatal(&format!("{}: {}", msg, err))),
@@@ -66,7 -54,7 +69,7 @@@ pub fn write_output_file
          let output_c = path2cstr(output);
          let result = llvm::LLVMRustWriteOutputFile(
                  target, pm, m, output_c.as_ptr(), file_type);
-         if !result {
+         if result.into_result().is_err() {
              llvm_err(handler, format!("could not write output to {}", output.display()));
          }
      }
@@@ -150,11 -138,11 +153,11 @@@ fn target_feature(sess: &Session) -> St
  
  fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
      match optimize {
-       config::OptLevel::No => llvm::CodeGenLevelNone,
-       config::OptLevel::Less => llvm::CodeGenLevelLess,
-       config::OptLevel::Default => llvm::CodeGenLevelDefault,
-       config::OptLevel::Aggressive => llvm::CodeGenLevelAggressive,
-       _ => llvm::CodeGenLevelDefault,
+       config::OptLevel::No => llvm::CodeGenOptLevel::None,
+       config::OptLevel::Less => llvm::CodeGenOptLevel::Less,
+       config::OptLevel::Default => llvm::CodeGenOptLevel::Default,
+       config::OptLevel::Aggressive => llvm::CodeGenOptLevel::Aggressive,
+       _ => llvm::CodeGenOptLevel::Default,
      }
  }
  
@@@ -167,30 -155,11 +170,11 @@@ fn get_llvm_opt_size(optimize: config::
  }
  
  pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
-     let reloc_model_arg = match sess.opts.cg.relocation_model {
-         Some(ref s) => &s[..],
-         None => &sess.target.target.options.relocation_model[..],
-     };
-     let reloc_model = match RELOC_MODEL_ARGS.iter().find(
-         |&&arg| arg.0 == reloc_model_arg) {
-         Some(x) => x.1,
-         _ => {
-             sess.err(&format!("{:?} is not a valid relocation mode",
-                              sess.opts
-                                  .cg
-                                  .relocation_model));
-             sess.abort_if_errors();
-             bug!();
-         }
-     };
+     let reloc_model = get_reloc_model(sess);
  
      let opt_level = get_llvm_opt_level(sess.opts.optimize);
      let use_softfp = sess.opts.cg.soft_float;
  
-     let any_library = sess.crate_types.borrow().iter().any(|ty| {
-         *ty != config::CrateTypeExecutable
-     });
      let ffunction_sections = sess.target.target.options.function_sections;
      let fdata_sections = ffunction_sections;
  
          None => &sess.target.target.options.code_model[..],
      };
  
 -    let code_model = match code_model_arg {
 -        "default" => llvm::CodeModel::Default,
 -        "small" => llvm::CodeModel::Small,
 -        "kernel" => llvm::CodeModel::Kernel,
 -        "medium" => llvm::CodeModel::Medium,
 -        "large" => llvm::CodeModel::Large,
 +    let code_model = match CODE_GEN_MODEL_ARGS.iter().find(
 +        |&&arg| arg.0 == code_model_arg) {
 +        Some(x) => x.1,
          _ => {
              sess.err(&format!("{:?} is not a valid code model",
                               sess.opts
              reloc_model,
              opt_level,
              use_softfp,
-             !any_library && reloc_model == llvm::RelocPIC,
+             is_pie_binary(sess),
              ffunction_sections,
              fdata_sections,
          )
@@@ -345,6 -317,8 +329,8 @@@ struct CodegenContext<'a> 
      remark: Passes,
      // Worker thread number
      worker: usize,
+     // Directory where incremental data is stored (if any)
+     incremental: Option<PathBuf>,
  }
  
  impl<'a> CodegenContext<'a> {
              plugin_passes: sess.plugin_llvm_passes.borrow().clone(),
              remark: sess.opts.cg.remark.clone(),
              worker: 0,
+             incremental: sess.opts.incremental.clone(),
          }
      }
  }
@@@ -390,7 -365,7 +377,7 @@@ unsafe extern "C" fn inline_asm_handler
                                          cookie: c_uint) {
      let HandlerFreeVars { cgcx, .. } = *(user as *const HandlerFreeVars);
  
-     let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
+     let msg = llvm::build_string(|s| llvm::LLVMRustWriteSMDiagnosticToString(diag, s))
          .expect("non-UTF8 SMDiagnostic");
  
      report_inline_asm(cgcx, &msg[..], cookie);
@@@ -432,10 -407,11 +419,11 @@@ unsafe extern "C" fn diagnostic_handler
  // Unsafe due to LLVM calls.
  unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
                                 mtrans: ModuleTranslation,
+                                mllvm: ModuleLlvm,
                                 config: ModuleConfig,
                                 output_names: OutputFilenames) {
-     let llmod = mtrans.llmod;
-     let llcx = mtrans.llcx;
+     let llmod = mllvm.llmod;
+     let llcx = mllvm.llcx;
      let tm = config.tm;
  
      // llcx doesn't outlive this function, so we can put this on the stack.
      };
      let fv = &fv as *const HandlerFreeVars as *mut c_void;
  
-     llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
+     llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
      llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
  
      let module_name = Some(&mtrans.name[..]);
                  return false;
              }
              let pass_manager = match llvm::LLVMRustPassKind(pass) {
-                 llvm::SupportedPassKind::Function => fpm,
-                 llvm::SupportedPassKind::Module => mpm,
-                 llvm::SupportedPassKind::Unsupported => {
+                 llvm::PassKind::Function => fpm,
+                 llvm::PassKind::Module => mpm,
+                 llvm::PassKind::Other => {
                      cgcx.handler.err("Encountered LLVM pass kind we can't handle");
                      return true
                  },
              };
              with_codegen(tm, llmod, config.no_builtins, |cpm| {
                  write_output_file(cgcx.handler, tm, cpm, llmod, &path,
-                                   llvm::AssemblyFileType);
+                                   llvm::FileType::AssemblyFile);
              });
              if config.emit_obj {
                  llvm::LLVMDisposeModule(llmod);
  
          if write_obj {
              with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                 write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out, llvm::ObjectFileType);
+                 write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out,
+                                   llvm::FileType::ObjectFile);
              });
          }
      });
  
      if copy_bc_to_obj {
          debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
-         if let Err(e) = fs::copy(&bc_out, &obj_out) {
+         if let Err(e) = link_or_copy(&bc_out, &obj_out) {
              cgcx.handler.err(&format!("failed to copy bitcode to object file: {}", e));
          }
      }
  pub fn cleanup_llvm(trans: &CrateTranslation) {
      for module in trans.modules.iter() {
          unsafe {
-             llvm::LLVMDisposeModule(module.llmod);
-             llvm::LLVMContextDispose(module.llcx);
+             match module.source {
+                 ModuleSource::Translated(llvm) => {
+                     llvm::LLVMDisposeModule(llvm.llmod);
+                     llvm::LLVMContextDispose(llvm.llcx);
+                 }
+                 ModuleSource::Preexisting(_) => {
+                 }
+             }
          }
      }
  }
@@@ -753,6 -736,23 +748,23 @@@ pub fn run_passes(sess: &Session
          run_work_multithreaded(sess, work_items, num_workers);
      }
  
+     // If in incr. comp. mode, preserve the `.o` files for potential re-use
+     for mtrans in trans.modules.iter() {
+         let mut files = vec![];
+         if modules_config.emit_obj {
+             let path = crate_output.temp_path(OutputType::Object, Some(&mtrans.name));
+             files.push((OutputType::Object, path));
+         }
+         if modules_config.emit_bc {
+             let path = crate_output.temp_path(OutputType::Bitcode, Some(&mtrans.name));
+             files.push((OutputType::Bitcode, path));
+         }
+         save_trans_partition(sess, &mtrans.name, mtrans.symbol_name_hash, &files);
+     }
      // All codegen is finished.
      unsafe {
          llvm::LLVMRustDisposeTargetMachine(tm);
@@@ -926,10 -926,37 +938,37 @@@ fn build_work_item(sess: &Session
  fn execute_work_item(cgcx: &CodegenContext,
                       work_item: WorkItem) {
      unsafe {
-         optimize_and_codegen(cgcx,
-                              work_item.mtrans,
-                              work_item.config,
-                              work_item.output_names);
+         match work_item.mtrans.source {
+             ModuleSource::Translated(mllvm) => {
+                 debug!("llvm-optimizing {:?}", work_item.mtrans.name);
+                 optimize_and_codegen(cgcx,
+                                      work_item.mtrans,
+                                      mllvm,
+                                      work_item.config,
+                                      work_item.output_names);
+             }
+             ModuleSource::Preexisting(wp) => {
+                 let incremental = cgcx.incremental.as_ref().unwrap();
+                 let name = &work_item.mtrans.name;
+                 for (kind, saved_file) in wp.saved_files {
+                     let obj_out = work_item.output_names.temp_path(kind, Some(name));
+                     let source_file = incremental.join(&saved_file);
+                     debug!("copying pre-existing module `{}` from {:?} to {}",
+                            work_item.mtrans.name,
+                            source_file,
+                            obj_out.display());
+                     match link_or_copy(&source_file, &obj_out) {
+                         Ok(()) => { }
+                         Err(err) => {
+                             cgcx.handler.err(&format!("unable to copy {} to {}: {}",
+                                                       source_file.display(),
+                                                       obj_out.display(),
+                                                       err));
+                         }
+                     }
+                 }
+             }
+         }
      }
  }
  
@@@ -965,6 -992,8 +1004,8 @@@ fn run_work_multithreaded(sess: &Sessio
          let mut tx = Some(tx);
          futures.push(rx);
  
+         let incremental = sess.opts.incremental.clone();
          thread::Builder::new().name(format!("codegen-{}", i)).spawn(move || {
              let diag_handler = Handler::with_emitter(true, false, box diag_emitter);
  
                  plugin_passes: plugin_passes,
                  remark: remark,
                  worker: i,
+                 incremental: incremental,
              };
  
              loop {
@@@ -1049,7 -1079,7 +1091,7 @@@ pub unsafe fn with_llvm_pmb(llmod: Modu
      // reasonable defaults and prepare it to actually populate the pass
      // manager.
      let builder = llvm::LLVMPassManagerBuilderCreate();
-     let opt_level = config.opt_level.unwrap_or(llvm::CodeGenLevelNone);
+     let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
      let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone);
      let inline_threshold = config.inline_threshold;
  
          (_, _, Some(t)) => {
              llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t as u32);
          }
-         (llvm::CodeGenLevelAggressive, _, _) => {
+         (llvm::CodeGenOptLevel::Aggressive, _, _) => {
              llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);
          }
          (_, llvm::CodeGenOptSizeDefault, _) => {
          (_, llvm::CodeGenOptSizeAggressive, _) => {
              llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 25);
          }
-         (llvm::CodeGenLevelNone, _, _) => {
+         (llvm::CodeGenOptLevel::None, _, _) => {
              llvm::LLVMRustAddAlwaysInlinePass(builder, false);
          }
-         (llvm::CodeGenLevelLess, _, _) => {
+         (llvm::CodeGenOptLevel::Less, _, _) => {
              llvm::LLVMRustAddAlwaysInlinePass(builder, true);
          }
-         (llvm::CodeGenLevelDefault, _, _) => {
+         (llvm::CodeGenOptLevel::Default, _, _) => {
              llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225);
          }
+         (llvm::CodeGenOptLevel::Other, _, _) => {
+             bug!("CodeGenOptLevel::Other selected")
+         }
      }
  
      f(builder);
index 88903726d64f7bbee90ed58128e6ec7391d566eb,166ce990fddfa72303618ca5d0aea7cad9c20dee..246c037c030b21272b88b3a50b5e6d73858828cb
@@@ -10,7 -10,7 +10,7 @@@
  
  use llvm;
  use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef};
- use rustc::dep_graph::{DepNode, DepTrackingMap, DepTrackingMapConfig};
+ use rustc::dep_graph::{DepNode, DepTrackingMap, DepTrackingMapConfig, WorkProduct};
  use middle::cstore::LinkMeta;
  use rustc::hir::def::ExportMap;
  use rustc::hir::def_id::DefId;
@@@ -34,9 -34,10 +34,10 @@@ use rustc::ty::subst::{Substs, VecPerPa
  use rustc::ty::{self, Ty, TyCtxt};
  use session::config::NoDebugInfo;
  use session::Session;
+ use session::config;
  use symbol_map::SymbolMap;
  use util::sha2::Sha256;
- use util::nodemap::{NodeMap, NodeSet, DefIdMap, FnvHashMap, FnvHashSet};
+ use util::nodemap::{NodeSet, DefIdMap, FnvHashMap, FnvHashSet};
  
  use std::ffi::{CStr, CString};
  use std::cell::{Cell, RefCell};
@@@ -95,16 -96,12 +96,12 @@@ pub struct SharedCrateContext<'a, 'tcx
  pub struct LocalCrateContext<'tcx> {
      llmod: ModuleRef,
      llcx: ContextRef,
+     previous_work_product: Option<WorkProduct>,
      tn: TypeNames, // FIXME: This seems to be largely unused.
      codegen_unit: CodegenUnit<'tcx>,
      needs_unwind_cleanup_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,
      fn_pointer_shims: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
      drop_glues: RefCell<FnvHashMap<DropGlueKind<'tcx>, (ValueRef, FnType)>>,
-     /// Track mapping of external ids to local items imported for inlining
-     external: RefCell<DefIdMap<Option<ast::NodeId>>>,
-     /// Backwards version of the `external` map (inlined items to where they
-     /// came from)
-     external_srcs: RefCell<NodeMap<DefId>>,
      /// Cache instances of monomorphic and polymorphic items
      instances: RefCell<FnvHashMap<Instance<'tcx>, ValueRef>>,
      monomorphizing: RefCell<DefIdMap<usize>>,
@@@ -198,24 -195,39 +195,39 @@@ pub struct CrateContextList<'a, 'tcx: '
  }
  
  impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> {
      pub fn new(shared_ccx: &'a SharedCrateContext<'a, 'tcx>,
                 codegen_units: Vec<CodegenUnit<'tcx>>,
+                previous_work_products: Vec<Option<WorkProduct>>,
                 symbol_map: Rc<SymbolMap<'tcx>>)
                 -> CrateContextList<'a, 'tcx> {
          CrateContextList {
              shared: shared_ccx,
-             local_ccxs: codegen_units.into_iter().map(|codegen_unit| {
-                 LocalCrateContext::new(shared_ccx, codegen_unit, symbol_map.clone())
+             local_ccxs: codegen_units.into_iter().zip(previous_work_products).map(|(cgu, wp)| {
+                 LocalCrateContext::new(shared_ccx, cgu, wp, symbol_map.clone())
              }).collect()
          }
      }
  
-     pub fn iter<'b>(&'b self) -> CrateContextIterator<'b, 'tcx> {
+     /// Iterate over all crate contexts, whether or not they need
+     /// translation.  That is, whether or not a `.o` file is available
+     /// for re-use from a previous incr. comp.).
+     pub fn iter_all<'b>(&'b self) -> CrateContextIterator<'b, 'tcx> {
          CrateContextIterator {
              shared: self.shared,
              index: 0,
-             local_ccxs: &self.local_ccxs[..]
+             local_ccxs: &self.local_ccxs[..],
+             filter_to_previous_work_product_unavail: false,
+         }
+     }
+     /// Iterator over all CCX that need translation (cannot reuse results from
+     /// previous incr. comp.).
+     pub fn iter_need_trans<'b>(&'b self) -> CrateContextIterator<'b, 'tcx> {
+         CrateContextIterator {
+             shared: self.shared,
+             index: 0,
+             local_ccxs: &self.local_ccxs[..],
+             filter_to_previous_work_product_unavail: true,
          }
      }
  
@@@ -239,24 -251,38 +251,38 @@@ pub struct CrateContextIterator<'a, 'tc
      shared: &'a SharedCrateContext<'a, 'tcx>,
      local_ccxs: &'a [LocalCrateContext<'tcx>],
      index: usize,
+     /// if true, only return results where `previous_work_product` is none
+     filter_to_previous_work_product_unavail: bool,
  }
  
  impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> {
      type Item = CrateContext<'a, 'tcx>;
  
      fn next(&mut self) -> Option<CrateContext<'a, 'tcx>> {
-         if self.index >= self.local_ccxs.len() {
-             return None;
-         }
+         loop {
+             if self.index >= self.local_ccxs.len() {
+                 return None;
+             }
  
-         let index = self.index;
-         self.index += 1;
+             let index = self.index;
+             self.index += 1;
  
-         Some(CrateContext {
-             shared: self.shared,
-             index: index,
-             local_ccxs: self.local_ccxs,
-         })
+             let ccx = CrateContext {
+                 shared: self.shared,
+                 index: index,
+                 local_ccxs: self.local_ccxs,
+             };
+             if
+                 self.filter_to_previous_work_product_unavail &&
+                 ccx.previous_work_product().is_some()
+             {
+                 continue;
+             }
+             return Some(ccx);
+         }
      }
  }
  
@@@ -292,6 -318,38 +318,36 @@@ impl<'a, 'tcx> Iterator for CrateContex
      }
  }
  
 -    match reloc_model_arg {
 -        "pic" => llvm::RelocMode::PIC,
 -        "static" => llvm::RelocMode::Static,
 -        "default" => llvm::RelocMode::Default,
 -        "dynamic-no-pic" => llvm::RelocMode::DynamicNoPic,
+ pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
+     let reloc_model_arg = match sess.opts.cg.relocation_model {
+         Some(ref s) => &s[..],
+         None => &sess.target.target.options.relocation_model[..],
+     };
 -                                 .relocation_model));
++    match ::back::write::RELOC_MODEL_ARGS.iter().find(
++        |&&arg| arg.0 == reloc_model_arg) {
++        Some(x) => x.1,
+         _ => {
+             sess.err(&format!("{:?} is not a valid relocation mode",
+                              sess.opts
+                                  .cg
++                                 .code_model));
+             sess.abort_if_errors();
+             bug!();
+         }
+     }
+ }
+ fn is_any_library(sess: &Session) -> bool {
+     sess.crate_types.borrow().iter().any(|ty| {
+         *ty != config::CrateTypeExecutable
+     })
+ }
+ pub fn is_pie_binary(sess: &Session) -> bool {
+     !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC
+ }
  unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
      let llcx = llvm::LLVMContextCreate();
      let mod_name = CString::new(mod_name).unwrap();
          let data_layout = str::from_utf8(CStr::from_ptr(data_layout).to_bytes())
              .ok().expect("got a non-UTF8 data-layout from LLVM");
  
-         if sess.target.target.data_layout != data_layout {
+         // Unfortunately LLVM target specs change over time, and right now we
+         // don't have proper support to work with any more than one
+         // `data_layout` than the one that is in the rust-lang/rust repo. If
+         // this compiler is configured against a custom LLVM, we may have a
+         // differing data layout, even though we should update our own to use
+         // that one.
+         //
+         // As an interim hack, if CFG_LLVM_ROOT is not an empty string then we
+         // disable this check entirely as we may be configured with something
+         // that has a different target layout.
+         //
+         // Unsure if this will actually cause breakage when rustc is configured
+         // as such.
+         //
+         // FIXME(#34960)
+         let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or("");
+         let custom_llvm_used = cfg_llvm_root.trim() != "";
+         if !custom_llvm_used && sess.target.target.data_layout != data_layout {
              bug!("data-layout for builtin `{}` target, `{}`, \
                    differs from LLVM default, `{}`",
                   sess.target.target.llvm_target,
      let llvm_target = sess.target.target.llvm_target.as_bytes();
      let llvm_target = CString::new(llvm_target).unwrap();
      llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
+     if is_pie_binary(sess) {
+         llvm::LLVMRustSetModulePIELevel(llmod);
+     }
      (llcx, llmod)
  }
  
@@@ -510,6 -591,7 +589,7 @@@ impl<'b, 'tcx> SharedCrateContext<'b, '
  impl<'tcx> LocalCrateContext<'tcx> {
      fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
                 codegen_unit: CodegenUnit<'tcx>,
+                previous_work_product: Option<WorkProduct>,
                 symbol_map: Rc<SymbolMap<'tcx>>)
             -> LocalCrateContext<'tcx> {
          unsafe {
              // crashes if the module identifier is same as other symbols
              // such as a function name in the module.
              // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
-             let llmod_id = format!("{}.rs", codegen_unit.name);
+             let llmod_id = format!("{}.rs", codegen_unit.name());
  
              let (llcx, llmod) = create_context_and_module(&shared.tcx.sess,
                                                            &llmod_id[..]);
  
              let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo {
-                 Some(debuginfo::CrateDebugContext::new(llmod))
+                 let dctx = debuginfo::CrateDebugContext::new(llmod);
+                 debuginfo::metadata::compile_unit_metadata(shared, &dctx, shared.tcx.sess);
+                 Some(dctx)
              } else {
                  None
              };
              let local_ccx = LocalCrateContext {
                  llmod: llmod,
                  llcx: llcx,
+                 previous_work_product: previous_work_product,
                  codegen_unit: codegen_unit,
                  tn: TypeNames::new(),
                  needs_unwind_cleanup_cache: RefCell::new(FnvHashMap()),
                  fn_pointer_shims: RefCell::new(FnvHashMap()),
                  drop_glues: RefCell::new(FnvHashMap()),
-                 external: RefCell::new(DefIdMap()),
-                 external_srcs: RefCell::new(NodeMap()),
                  instances: RefCell::new(FnvHashMap()),
                  monomorphizing: RefCell::new(DefIdMap()),
                  vtables: RefCell::new(FnvHashMap()),
@@@ -694,6 -777,10 +775,10 @@@ impl<'b, 'tcx> CrateContext<'b, 'tcx> 
          self.local().llcx
      }
  
+     pub fn previous_work_product(&self) -> Option<&WorkProduct> {
+         self.local().previous_work_product.as_ref()
+     }
      pub fn codegen_unit(&self) -> &CodegenUnit<'tcx> {
          &self.local().codegen_unit
      }
          &self.local().drop_glues
      }
  
-     pub fn external<'a>(&'a self) -> &'a RefCell<DefIdMap<Option<ast::NodeId>>> {
-         &self.local().external
+     pub fn local_node_for_inlined_defid<'a>(&'a self, def_id: DefId) -> Option<ast::NodeId> {
+         self.sess().cstore.local_node_for_inlined_defid(def_id)
      }
  
-     pub fn external_srcs<'a>(&'a self) -> &'a RefCell<NodeMap<DefId>> {
-         &self.local().external_srcs
+     pub fn defid_for_inlined_node<'a>(&'a self, node_id: ast::NodeId) -> Option<DefId> {
+         self.sess().cstore.defid_for_inlined_node(node_id)
      }
  
      pub fn instances<'a>(&'a self) -> &'a RefCell<FnvHashMap<Instance<'tcx>, ValueRef>> {
diff --combined src/llvm
index a3c12a7ad8a0d32a957f67f127936907b9ba522c,d1cc48989b13780f21c408fef17dceb104a09c9d..d295833b773313dbef26041f481fc91a2954fbb9
+++ b/src/llvm
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit a3c12a7ad8a0d32a957f67f127936907b9ba522c
 -Subproject commit d1cc48989b13780f21c408fef17dceb104a09c9d
++Subproject commit d295833b773313dbef26041f481fc91a2954fbb9
index b94e667701c826d825a5cfd36ddee780f817e561,3a20bb2714ece5b7967f9ee0eb698cd46d3a11dd..0555a96ff24ce900d6b6f53f56021a6c02496a91
@@@ -17,6 -17,7 +17,7 @@@
  #include "llvm/Support/Host.h"
  #include "llvm/Analysis/TargetLibraryInfo.h"
  #include "llvm/Analysis/TargetTransformInfo.h"
+ #include "llvm/IR/AutoUpgrade.h"
  #include "llvm/Target/TargetMachine.h"
  #include "llvm/Target/TargetSubtargetInfo.h"
  #include "llvm/Transforms/IPO/PassManagerBuilder.h"
@@@ -54,41 -55,48 +55,48 @@@ LLVMInitializePasses() 
    initializeTarget(Registry);
  }
  
- enum class SupportedPassKind {
+ enum class LLVMRustPassKind {
+   Other,
    Function,
    Module,
-   Unsupported
  };
  
- extern "C" Pass*
+ static LLVMRustPassKind
+ to_rust(PassKind kind)
+ {
+   switch (kind) {
+   case PT_Function:
+       return LLVMRustPassKind::Function;
+   case PT_Module:
+       return LLVMRustPassKind::Module;
+   default:
+       return LLVMRustPassKind::Other;
+   }
+ }
+ extern "C" LLVMPassRef
  LLVMRustFindAndCreatePass(const char *PassName) {
      StringRef SR(PassName);
      PassRegistry *PR = PassRegistry::getPassRegistry();
  
      const PassInfo *PI = PR->getPassInfo(SR);
      if (PI) {
-         return PI->createPass();
+       return wrap(PI->createPass());
      }
      return NULL;
  }
  
- extern "C" SupportedPassKind
- LLVMRustPassKind(Pass *pass) {
-     assert(pass);
-     PassKind passKind = pass->getPassKind();
-     if (passKind == PT_Module) {
-         return SupportedPassKind::Module;
-     } else if (passKind == PT_Function) {
-         return SupportedPassKind::Function;
-     } else {
-         return SupportedPassKind::Unsupported;
-     }
+ extern "C" LLVMRustPassKind
+ LLVMRustPassKind(LLVMPassRef rust_pass) {
+     assert(rust_pass);
+     Pass *pass = unwrap(rust_pass);
+     return to_rust(pass->getPassKind());
  }
  
  extern "C" void
- LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
-     assert(pass);
+ LLVMRustAddPass(LLVMPassManagerRef PM, LLVMPassRef rust_pass) {
+     assert(rust_pass);
+     Pass *pass = unwrap(rust_pass);
      PassManagerBase *pm = unwrap(PM);
      pm->add(pass);
  }
@@@ -162,69 -170,99 +170,151 @@@ LLVMRustHasFeature(LLVMTargetMachineRe
      return (Bits & FeatureEntry->Value) == FeatureEntry->Value;
  }
  
+ enum class LLVMRustCodeModel {
+     Other,
+     Default,
+     JITDefault,
+     Small,
+     Kernel,
+     Medium,
+     Large,
+ };
+ static CodeModel::Model
+ from_rust(LLVMRustCodeModel model)
+ {
+     switch (model) {
+     case LLVMRustCodeModel::Default:
+         return CodeModel::Default;
+     case LLVMRustCodeModel::JITDefault:
+         return CodeModel::JITDefault;
+     case LLVMRustCodeModel::Small:
+         return CodeModel::Small;
+     case LLVMRustCodeModel::Kernel:
+         return CodeModel::Kernel;
+     case LLVMRustCodeModel::Medium:
+         return CodeModel::Medium;
+     case LLVMRustCodeModel::Large:
+         return CodeModel::Large;
+     default:
+         llvm_unreachable("Bad CodeModel.");
+   }
+ }
+ enum class LLVMRustCodeGenOptLevel {
+     Other,
+     None,
+     Less,
+     Default,
+     Aggressive,
+ };
+ static CodeGenOpt::Level
+ from_rust(LLVMRustCodeGenOptLevel level)
+ {
+     switch (level) {
+     case LLVMRustCodeGenOptLevel::None:
+         return CodeGenOpt::None;
+     case LLVMRustCodeGenOptLevel::Less:
+         return CodeGenOpt::Less;
+     case LLVMRustCodeGenOptLevel::Default:
+         return CodeGenOpt::Default;
+     case LLVMRustCodeGenOptLevel::Aggressive:
+         return CodeGenOpt::Aggressive;
+     default:
+         llvm_unreachable("Bad CodeGenOptLevel.");
+   }
+ }
 +#if LLVM_RUSTLLVM
 +/// getLongestEntryLength - Return the length of the longest entry in the table.
 +///
 +static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
 +  size_t MaxLen = 0;
 +  for (auto &I : Table)
 +    MaxLen = std::max(MaxLen, std::strlen(I.Key));
 +  return MaxLen;
 +}
 +
 +extern "C" void
 +LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
 +    const TargetMachine *Target = unwrap(TM);
 +    const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
 +    const ArrayRef<SubtargetFeatureKV> CPUTable = MCInfo->getCPUTable();
 +    unsigned MaxCPULen = getLongestEntryLength(CPUTable);
 +
 +    printf("Available CPUs for this target:\n");
 +    for (auto &CPU : CPUTable)
 +        printf("    %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
 +    printf("\n");
 +}
 +
 +extern "C" void
 +LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
 +    const TargetMachine *Target = unwrap(TM);
 +    const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
 +    const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
 +    unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
 +
 +    printf("Available features for this target:\n");
 +    for (auto &Feature : FeatTable)
 +        printf("    %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
 +    printf("\n");
 +
 +    printf("Use +feature to enable a feature, or -feature to disable it.\n"
 +            "For example, rustc -C -target-cpu=mycpu -C target-feature=+feature1,-feature2\n\n");
 +}
 +
 +#else
 +
 +extern "C" void
 +LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
 +    printf("Target CPU help is not supported by this LLVM version.\n\n");
 +}
 +
 +extern "C" void
 +LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
 +    printf("Target features help is not supported by this LLVM version.\n\n");
 +}
 +#endif
 +
  extern "C" LLVMTargetMachineRef
  LLVMRustCreateTargetMachine(const char *triple,
                              const char *cpu,
                              const char *feature,
-                             CodeModel::Model CM,
-                             Reloc::Model RM,
-                             CodeGenOpt::Level OptLevel,
+                             LLVMRustCodeModel rust_CM,
+                             LLVMRelocMode Reloc,
+                             LLVMRustCodeGenOptLevel rust_OptLevel,
                              bool UseSoftFloat,
                              bool PositionIndependentExecutable,
                              bool FunctionSections,
                              bool DataSections) {
+ #if LLVM_VERSION_MINOR <= 8
+     Reloc::Model RM;
+ #else
+     Optional<Reloc::Model> RM;
+ #endif
+     auto CM = from_rust(rust_CM);
+     auto OptLevel = from_rust(rust_OptLevel);
+     switch (Reloc){
+         case LLVMRelocStatic:
+             RM = Reloc::Static;
+             break;
+         case LLVMRelocPIC:
+             RM = Reloc::PIC_;
+             break;
+         case LLVMRelocDynamicNoPic:
+             RM = Reloc::DynamicNoPIC;
+             break;
+         default:
+ #if LLVM_VERSION_MINOR <= 8
+             RM = Reloc::Default;
+ #endif
+             break;
+     }
      std::string Error;
      Triple Trip(Triple::normalize(triple));
      const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
      }
  
      TargetOptions Options;
+ #if LLVM_VERSION_MINOR <= 8
      Options.PositionIndependentExecutable = PositionIndependentExecutable;
+ #endif
      Options.FloatABIType = FloatABI::Default;
      if (UseSoftFloat) {
          Options.FloatABIType = FloatABI::Soft;
@@@ -277,14 -318,14 +370,14 @@@ LLVMRustAddAnalysisPasses(LLVMTargetMac
  
  extern "C" void
  LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB,
-                                     CodeGenOpt::Level OptLevel,
+                                   LLVMRustCodeGenOptLevel OptLevel,
                                      bool MergeFunctions,
                                      bool SLPVectorize,
                                      bool LoopVectorize) {
      // Ignore mergefunc for now as enabling it causes crashes.
      //unwrap(PMB)->MergeFunctions = MergeFunctions;
      unwrap(PMB)->SLPVectorize = SLPVectorize;
-     unwrap(PMB)->OptLevel = OptLevel;
+     unwrap(PMB)->OptLevel = from_rust(OptLevel);
      unwrap(PMB)->LoopVectorize = LoopVectorize;
  }
  
@@@ -319,12 -360,19 +412,19 @@@ LLVMRustAddLibraryInfo(LLVMPassManagerR
  // similar code in clang's BackendUtil.cpp file.
  extern "C" void
  LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
-     FunctionPassManager *P = unwrap<FunctionPassManager>(PM);
+     llvm::legacy::FunctionPassManager *P = unwrap<llvm::legacy::FunctionPassManager>(PM);
      P->doInitialization();
+     // Upgrade all calls to old intrinsics first.
+     for (Module::iterator I = unwrap(M)->begin(),
+          E = unwrap(M)->end(); I != E;)
+         UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
      for (Module::iterator I = unwrap(M)->begin(),
           E = unwrap(M)->end(); I != E; ++I)
          if (!I->isDeclaration())
              P->run(*I);
      P->doFinalization();
  }
  
@@@ -340,13 -388,33 +440,33 @@@ LLVMRustSetLLVMOptions(int Argc, char *
      cl::ParseCommandLineOptions(Argc, Argv);
  }
  
- extern "C" bool
+ enum class LLVMRustFileType {
+     Other,
+     AssemblyFile,
+     ObjectFile,
+ };
+ static TargetMachine::CodeGenFileType
+ from_rust(LLVMRustFileType type)
+ {
+     switch (type) {
+     case LLVMRustFileType::AssemblyFile:
+         return TargetMachine::CGFT_AssemblyFile;
+     case LLVMRustFileType::ObjectFile:
+         return TargetMachine::CGFT_ObjectFile;
+     default:
+         llvm_unreachable("Bad FileType.");
+   }
+ }
+ extern "C" LLVMRustResult
  LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
                          LLVMPassManagerRef PMR,
                          LLVMModuleRef M,
                          const char *path,
-                         TargetMachine::CodeGenFileType FileType) {
-   PassManager *PM = unwrap<PassManager>(PMR);
+                         LLVMRustFileType rust_FileType) {
+   llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
+   auto FileType = from_rust(rust_FileType);
  
    std::string ErrorInfo;
    std::error_code EC;
      ErrorInfo = EC.message();
    if (ErrorInfo != "") {
      LLVMRustSetLastError(ErrorInfo.c_str());
-     return false;
+     return LLVMRustResult::Failure;
    }
  
    unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
    // stream (OS), so the only real safe place to delete this is here? Don't we
    // wish this was written in Rust?
    delete PM;
-   return true;
+   return LLVMRustResult::Success;
  }
  
  extern "C" void
  LLVMRustPrintModule(LLVMPassManagerRef PMR,
                      LLVMModuleRef M,
                      const char* path) {
-   PassManager *PM = unwrap<PassManager>(PMR);
+   llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
    std::string ErrorInfo;
  
    std::error_code EC;
@@@ -410,9 -478,24 +530,24 @@@ LLVMRustAddAlwaysInlinePass(LLVMPassMan
  
  extern "C" void
  LLVMRustRunRestrictionPass(LLVMModuleRef M, char **symbols, size_t len) {
-     PassManager passes;
+     llvm::legacy::PassManager passes;
+ #if LLVM_VERSION_MINOR <= 8
      ArrayRef<const char*> ref(symbols, len);
      passes.add(llvm::createInternalizePass(ref));
+ #else
+     auto PreserveFunctions = [=](const GlobalValue &GV) {
+         for (size_t i=0; i<len; i++) {
+             if (GV.getName() == symbols[i]) {
+                 return true;
+             }
+         }
+         return false;
+     };
+     passes.add(llvm::createInternalizePass(PreserveFunctions));
+ #endif
      passes.run(*unwrap(M));
  }
  
@@@ -448,3 -531,10 +583,10 @@@ extern "C" LLVMTargetDataRe
  LLVMRustGetModuleDataLayout(LLVMModuleRef M) {
      return wrap(&unwrap(M)->getDataLayout());
  }
+ extern "C" void
+ LLVMRustSetModulePIELevel(LLVMModuleRef M) {
+ #if LLVM_VERSION_MINOR >= 9
+     unwrap(M)->setPIELevel(PIELevel::Level::Large);
+ #endif
+ }