about summary refs log tree commit diff
path: root/src/librustc_back/target
diff options
context:
space:
mode:
authorDoug Goldstein <cardoe@cardoe.com>2016-04-07 22:29:01 -0500
committerDoug Goldstein <cardoe@cardoe.com>2016-07-27 10:24:36 -0700
commitc7b6ed27bcbe63906825d6e541a7a1f62bdd03c9 (patch)
tree64160f65a9c26c942d0e34ddbb989f178a979dca /src/librustc_back/target
parent9c83fa41b05dd0a2ffedc88e9b97508341e2b92a (diff)
downloadrust-c7b6ed27bcbe63906825d6e541a7a1f62bdd03c9.tar.gz
rust-c7b6ed27bcbe63906825d6e541a7a1f62bdd03c9.zip
librustc_back: add ToJson trait to Target
Target's can already be built up from JSON files as well as built into
librustc_back so this adds the ability to convert any Target back into
JSON.

Signed-off-by: Doug Goldstein <cardoe@cardoe.com>
Diffstat (limited to 'src/librustc_back/target')
-rw-r--r--src/librustc_back/target/mod.rs98
1 files changed, 96 insertions, 2 deletions
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 78edcd55541..067885c92fd 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -44,7 +44,8 @@
 //! the target's settings, though `target-feature` and `link-args` will *add*
 //! to the list specified by the target, rather than replace.
 
-use serialize::json::Json;
+use serialize::json::{Json, ToJson};
+use std::collections::BTreeMap;
 use std::default::Default;
 use std::io::prelude::*;
 use syntax::abi::Abi;
@@ -364,7 +365,12 @@ impl Target {
 
     /// Load a target descriptor from a JSON object.
     pub fn from_json(obj: Json) -> Target {
-        // this is 1. ugly, 2. error prone.
+        // While ugly, this code must remain this way to retain
+        // compatibility with existing JSON fields and the internal
+        // expected naming of the Target and TargetOptions structs.
+        // To ensure compatibility is retained, the built-in targets
+        // are round-tripped through this code to catch cases where
+        // the JSON parser is not updated to match the structs.
 
         let get_req_field = |name: &str| {
             match obj.find(name)
@@ -535,6 +541,94 @@ impl Target {
     }
 }
 
+impl ToJson for Target {
+    fn to_json(&self) -> Json {
+        let mut d = BTreeMap::new();
+        let default: TargetOptions = Default::default();
+
+        macro_rules! target_val {
+            ($attr:ident) => ( {
+                let name = (stringify!($attr)).replace("_", "-");
+                d.insert(name.to_string(), self.$attr.to_json());
+            } );
+            ($attr:ident, $key_name:expr) => ( {
+                let name = $key_name;
+                d.insert(name.to_string(), self.$attr.to_json());
+            } );
+        }
+
+        macro_rules! target_option_val {
+            ($attr:ident) => ( {
+                let name = (stringify!($attr)).replace("_", "-");
+                if default.$attr != self.options.$attr {
+                    d.insert(name.to_string(), self.options.$attr.to_json());
+                }
+            } );
+            ($attr:ident, $key_name:expr) => ( {
+                let name = $key_name;
+                if default.$attr != self.options.$attr {
+                    d.insert(name.to_string(), self.options.$attr.to_json());
+                }
+            } );
+        }
+
+        target_val!(llvm_target);
+        target_val!(target_endian);
+        target_val!(target_pointer_width);
+        target_val!(arch);
+        target_val!(target_os, "os");
+        target_val!(target_env, "env");
+        target_val!(target_vendor, "vendor");
+        target_val!(arch);
+        target_val!(data_layout);
+
+        target_option_val!(is_builtin);
+        target_option_val!(linker);
+        target_option_val!(ar);
+        target_option_val!(pre_link_args);
+        target_option_val!(pre_link_objects_exe);
+        target_option_val!(pre_link_objects_dll);
+        target_option_val!(late_link_args);
+        target_option_val!(post_link_objects);
+        target_option_val!(post_link_args);
+        target_option_val!(cpu);
+        target_option_val!(features);
+        target_option_val!(dynamic_linking);
+        target_option_val!(executables);
+        target_option_val!(relocation_model);
+        target_option_val!(code_model);
+        target_option_val!(disable_redzone);
+        target_option_val!(eliminate_frame_pointer);
+        target_option_val!(function_sections);
+        target_option_val!(dll_prefix);
+        target_option_val!(dll_suffix);
+        target_option_val!(exe_suffix);
+        target_option_val!(staticlib_prefix);
+        target_option_val!(staticlib_suffix);
+        target_option_val!(target_family);
+        target_option_val!(is_like_osx);
+        target_option_val!(is_like_solaris);
+        target_option_val!(is_like_windows);
+        target_option_val!(is_like_msvc);
+        target_option_val!(is_like_android);
+        target_option_val!(linker_is_gnu);
+        target_option_val!(has_rpath);
+        target_option_val!(no_compiler_rt);
+        target_option_val!(no_default_libraries);
+        target_option_val!(position_independent_executables);
+        target_option_val!(archive_format);
+        target_option_val!(allow_asm);
+        target_option_val!(custom_unwind_resume);
+        target_option_val!(lib_allocation_crate);
+        target_option_val!(exe_allocation_crate);
+        target_option_val!(has_elf_tls);
+        target_option_val!(obj_is_bitcode);
+        target_option_val!(max_atomic_width);
+
+        Json::Object(d)
+    }
+}
+
 fn maybe_jemalloc() -> String {
     if cfg!(feature = "jemalloc") {
         "alloc_jemalloc".to_string()