Auto merge of #62555 - Centril:rollup-ti46adx, r=Centril
Rollup of 5 pull requests Successful merges: - #61853 (Emit warning when trying to use PGO in conjunction with unwinding on …) - #62278 (Add Iterator::partition_in_place() and is_partitioned()) - #62283 (Target::arch can take more than listed options) - #62393 (Fix pretty-printing of `$crate` (take 4)) - #62474 (Prepare for LLVM 9 update) Failed merges: r? @ghost
This commit is contained in:
commit
0324a2b309
60 changed files with 551 additions and 180 deletions
|
@ -1472,6 +1472,11 @@ pub trait Iterator {
|
||||||
/// `partition()` returns a pair, all of the elements for which it returned
|
/// `partition()` returns a pair, all of the elements for which it returned
|
||||||
/// `true`, and all of the elements for which it returned `false`.
|
/// `true`, and all of the elements for which it returned `false`.
|
||||||
///
|
///
|
||||||
|
/// See also [`is_partitioned()`] and [`partition_in_place()`].
|
||||||
|
///
|
||||||
|
/// [`is_partitioned()`]: #method.is_partitioned
|
||||||
|
/// [`partition_in_place()`]: #method.partition_in_place
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
|
@ -1506,6 +1511,101 @@ pub trait Iterator {
|
||||||
(left, right)
|
(left, right)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reorder the elements of this iterator *in-place* according to the given predicate,
|
||||||
|
/// such that all those that return `true` precede all those that return `false`.
|
||||||
|
/// Returns the number of `true` elements found.
|
||||||
|
///
|
||||||
|
/// The relative order of partitioned items is not maintained.
|
||||||
|
///
|
||||||
|
/// See also [`is_partitioned()`] and [`partition()`].
|
||||||
|
///
|
||||||
|
/// [`is_partitioned()`]: #method.is_partitioned
|
||||||
|
/// [`partition()`]: #method.partition
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(iter_partition_in_place)]
|
||||||
|
///
|
||||||
|
/// let mut a = [1, 2, 3, 4, 5, 6, 7];
|
||||||
|
///
|
||||||
|
/// // Partition in-place between evens and odds
|
||||||
|
/// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0);
|
||||||
|
///
|
||||||
|
/// assert_eq!(i, 3);
|
||||||
|
/// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens
|
||||||
|
/// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")]
|
||||||
|
fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
|
||||||
|
where
|
||||||
|
Self: Sized + DoubleEndedIterator<Item = &'a mut T>,
|
||||||
|
P: FnMut(&T) -> bool,
|
||||||
|
{
|
||||||
|
// FIXME: should we worry about the count overflowing? The only way to have more than
|
||||||
|
// `usize::MAX` mutable references is with ZSTs, which aren't useful to partition...
|
||||||
|
|
||||||
|
// These closure "factory" functions exist to avoid genericity in `Self`.
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_false<'a, T>(
|
||||||
|
predicate: &'a mut impl FnMut(&T) -> bool,
|
||||||
|
true_count: &'a mut usize,
|
||||||
|
) -> impl FnMut(&&mut T) -> bool + 'a {
|
||||||
|
move |x| {
|
||||||
|
let p = predicate(&**x);
|
||||||
|
*true_count += p as usize;
|
||||||
|
!p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_true<T>(
|
||||||
|
predicate: &mut impl FnMut(&T) -> bool
|
||||||
|
) -> impl FnMut(&&mut T) -> bool + '_ {
|
||||||
|
move |x| predicate(&**x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repeatedly find the first `false` and swap it with the last `true`.
|
||||||
|
let mut true_count = 0;
|
||||||
|
while let Some(head) = self.find(is_false(predicate, &mut true_count)) {
|
||||||
|
if let Some(tail) = self.rfind(is_true(predicate)) {
|
||||||
|
crate::mem::swap(head, tail);
|
||||||
|
true_count += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true_count
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if the elements of this iterator are partitioned according to the given predicate,
|
||||||
|
/// such that all those that return `true` precede all those that return `false`.
|
||||||
|
///
|
||||||
|
/// See also [`partition()`] and [`partition_in_place()`].
|
||||||
|
///
|
||||||
|
/// [`partition()`]: #method.partition
|
||||||
|
/// [`partition_in_place()`]: #method.partition_in_place
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(iter_is_partitioned)]
|
||||||
|
///
|
||||||
|
/// assert!("Iterator".chars().is_partitioned(char::is_uppercase));
|
||||||
|
/// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase));
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")]
|
||||||
|
fn is_partitioned<P>(mut self, mut predicate: P) -> bool
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
P: FnMut(Self::Item) -> bool,
|
||||||
|
{
|
||||||
|
// Either all items test `true`, or the first clause stops at `false`
|
||||||
|
// and we check that there are no more `true` items after that.
|
||||||
|
self.all(&mut predicate) || !self.any(predicate)
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator method that applies a function as long as it returns
|
/// An iterator method that applies a function as long as it returns
|
||||||
/// successfully, producing a single, final value.
|
/// successfully, producing a single, final value.
|
||||||
///
|
///
|
||||||
|
|
|
@ -2460,3 +2460,39 @@ fn test_is_sorted() {
|
||||||
assert!(!["c", "bb", "aaa"].iter().is_sorted());
|
assert!(!["c", "bb", "aaa"].iter().is_sorted());
|
||||||
assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
|
assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_partition() {
|
||||||
|
fn check(xs: &mut [i32], ref p: impl Fn(&i32) -> bool, expected: usize) {
|
||||||
|
let i = xs.iter_mut().partition_in_place(p);
|
||||||
|
assert_eq!(expected, i);
|
||||||
|
assert!(xs[..i].iter().all(p));
|
||||||
|
assert!(!xs[i..].iter().any(p));
|
||||||
|
assert!(xs.iter().is_partitioned(p));
|
||||||
|
if i == 0 || i == xs.len() {
|
||||||
|
assert!(xs.iter().rev().is_partitioned(p));
|
||||||
|
} else {
|
||||||
|
assert!(!xs.iter().rev().is_partitioned(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check(&mut [], |_| true, 0);
|
||||||
|
check(&mut [], |_| false, 0);
|
||||||
|
|
||||||
|
check(&mut [0], |_| true, 1);
|
||||||
|
check(&mut [0], |_| false, 0);
|
||||||
|
|
||||||
|
check(&mut [-1, 1], |&x| x > 0, 1);
|
||||||
|
check(&mut [-1, 1], |&x| x < 0, 1);
|
||||||
|
|
||||||
|
let ref mut xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
|
check(xs, |_| true, 10);
|
||||||
|
check(xs, |_| false, 0);
|
||||||
|
check(xs, |&x| x % 2 == 0, 5); // evens
|
||||||
|
check(xs, |&x| x % 2 == 1, 5); // odds
|
||||||
|
check(xs, |&x| x % 3 == 0, 4); // multiple of 3
|
||||||
|
check(xs, |&x| x % 4 == 0, 3); // multiple of 4
|
||||||
|
check(xs, |&x| x % 5 == 0, 2); // multiple of 5
|
||||||
|
check(xs, |&x| x < 3, 3); // small
|
||||||
|
check(xs, |&x| x > 6, 3); // large
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#![feature(slice_partition_dedup)]
|
#![feature(slice_partition_dedup)]
|
||||||
#![feature(int_error_matching)]
|
#![feature(int_error_matching)]
|
||||||
#![feature(const_fn)]
|
#![feature(const_fn)]
|
||||||
|
#![feature(iter_partition_in_place)]
|
||||||
|
#![feature(iter_is_partitioned)]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
|
@ -1303,13 +1303,13 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PGO does not work reliably with panic=unwind on Windows. Let's make it
|
// PGO does not work reliably with panic=unwind on Windows. Let's make it
|
||||||
// an error to combine the two for now. It always runs into an assertions
|
// a warning to combine the two for now. It always runs into an assertions
|
||||||
// if LLVM is built with assertions, but without assertions it sometimes
|
// if LLVM is built with assertions, but without assertions it sometimes
|
||||||
// does not crash and will probably generate a corrupted binary.
|
// does not crash and will probably generate a corrupted binary.
|
||||||
if sess.opts.cg.profile_generate.enabled() &&
|
if sess.opts.cg.profile_generate.enabled() &&
|
||||||
sess.target.target.options.is_like_msvc &&
|
sess.target.target.options.is_like_msvc &&
|
||||||
sess.panic_strategy() == PanicStrategy::Unwind {
|
sess.panic_strategy() == PanicStrategy::Unwind {
|
||||||
sess.err("Profile-guided optimization does not yet work in conjunction \
|
sess.warn("Profile-guided optimization does not yet work in conjunction \
|
||||||
with `-Cpanic=unwind` on Windows when targeting MSVC. \
|
with `-Cpanic=unwind` on Windows when targeting MSVC. \
|
||||||
See https://github.com/rust-lang/rust/issues/61002 for details.");
|
See https://github.com/rust-lang/rust/issues/61002 for details.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,17 +34,17 @@ trait ArgAttributeExt {
|
||||||
impl ArgAttributeExt for ArgAttribute {
|
impl ArgAttributeExt for ArgAttribute {
|
||||||
fn for_each_kind<F>(&self, mut f: F) where F: FnMut(llvm::Attribute) {
|
fn for_each_kind<F>(&self, mut f: F) where F: FnMut(llvm::Attribute) {
|
||||||
for_each_kind!(self, f,
|
for_each_kind!(self, f,
|
||||||
ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg)
|
NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ArgAttributesExt {
|
pub trait ArgAttributesExt {
|
||||||
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value);
|
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>);
|
||||||
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value);
|
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArgAttributesExt for ArgAttributes {
|
impl ArgAttributesExt for ArgAttributes {
|
||||||
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) {
|
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>) {
|
||||||
let mut regular = self.regular;
|
let mut regular = self.regular;
|
||||||
unsafe {
|
unsafe {
|
||||||
let deref = self.pointee_size.bytes();
|
let deref = self.pointee_size.bytes();
|
||||||
|
@ -65,11 +65,14 @@ impl ArgAttributesExt for ArgAttributes {
|
||||||
idx.as_uint(),
|
idx.as_uint(),
|
||||||
align.bytes() as u32);
|
align.bytes() as u32);
|
||||||
}
|
}
|
||||||
|
if regular.contains(ArgAttribute::ByVal) {
|
||||||
|
llvm::LLVMRustAddByValAttr(llfn, idx.as_uint(), ty.unwrap());
|
||||||
|
}
|
||||||
regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn));
|
regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) {
|
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>) {
|
||||||
let mut regular = self.regular;
|
let mut regular = self.regular;
|
||||||
unsafe {
|
unsafe {
|
||||||
let deref = self.pointee_size.bytes();
|
let deref = self.pointee_size.bytes();
|
||||||
|
@ -90,6 +93,9 @@ impl ArgAttributesExt for ArgAttributes {
|
||||||
idx.as_uint(),
|
idx.as_uint(),
|
||||||
align.bytes() as u32);
|
align.bytes() as u32);
|
||||||
}
|
}
|
||||||
|
if regular.contains(ArgAttribute::ByVal) {
|
||||||
|
llvm::LLVMRustAddByValCallSiteAttr(callsite, idx.as_uint(), ty.unwrap());
|
||||||
|
}
|
||||||
regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite));
|
regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,7 +304,7 @@ pub trait FnTypeLlvmExt<'tcx> {
|
||||||
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||||
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||||
fn llvm_cconv(&self) -> llvm::CallConv;
|
fn llvm_cconv(&self) -> llvm::CallConv;
|
||||||
fn apply_attrs_llfn(&self, llfn: &'ll Value);
|
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value);
|
||||||
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
|
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,51 +390,51 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_attrs_llfn(&self, llfn: &'ll Value) {
|
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut apply = |attrs: &ArgAttributes| {
|
let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
|
||||||
attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
|
attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
match self.ret.mode {
|
match self.ret.mode {
|
||||||
PassMode::Direct(ref attrs) => {
|
PassMode::Direct(ref attrs) => {
|
||||||
attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn);
|
attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn, None);
|
||||||
}
|
}
|
||||||
PassMode::Indirect(ref attrs, _) => apply(attrs),
|
PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(cx))),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
for arg in &self.args {
|
for arg in &self.args {
|
||||||
if arg.pad.is_some() {
|
if arg.pad.is_some() {
|
||||||
apply(&ArgAttributes::new());
|
apply(&ArgAttributes::new(), None);
|
||||||
}
|
}
|
||||||
match arg.mode {
|
match arg.mode {
|
||||||
PassMode::Ignore(_) => {}
|
PassMode::Ignore(_) => {}
|
||||||
PassMode::Direct(ref attrs) |
|
PassMode::Direct(ref attrs) |
|
||||||
PassMode::Indirect(ref attrs, None) => apply(attrs),
|
PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(cx))),
|
||||||
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
|
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
|
||||||
apply(attrs);
|
apply(attrs, None);
|
||||||
apply(extra_attrs);
|
apply(extra_attrs, None);
|
||||||
}
|
}
|
||||||
PassMode::Pair(ref a, ref b) => {
|
PassMode::Pair(ref a, ref b) => {
|
||||||
apply(a);
|
apply(a, None);
|
||||||
apply(b);
|
apply(b, None);
|
||||||
}
|
}
|
||||||
PassMode::Cast(_) => apply(&ArgAttributes::new()),
|
PassMode::Cast(_) => apply(&ArgAttributes::new(), None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
|
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut apply = |attrs: &ArgAttributes| {
|
let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
|
||||||
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
|
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
match self.ret.mode {
|
match self.ret.mode {
|
||||||
PassMode::Direct(ref attrs) => {
|
PassMode::Direct(ref attrs) => {
|
||||||
attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite);
|
attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite, None);
|
||||||
}
|
}
|
||||||
PassMode::Indirect(ref attrs, _) => apply(attrs),
|
PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(bx))),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi {
|
if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi {
|
||||||
|
@ -446,21 +452,21 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||||
}
|
}
|
||||||
for arg in &self.args {
|
for arg in &self.args {
|
||||||
if arg.pad.is_some() {
|
if arg.pad.is_some() {
|
||||||
apply(&ArgAttributes::new());
|
apply(&ArgAttributes::new(), None);
|
||||||
}
|
}
|
||||||
match arg.mode {
|
match arg.mode {
|
||||||
PassMode::Ignore(_) => {}
|
PassMode::Ignore(_) => {}
|
||||||
PassMode::Direct(ref attrs) |
|
PassMode::Direct(ref attrs) |
|
||||||
PassMode::Indirect(ref attrs, None) => apply(attrs),
|
PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(bx))),
|
||||||
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
|
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
|
||||||
apply(attrs);
|
apply(attrs, None);
|
||||||
apply(extra_attrs);
|
apply(extra_attrs, None);
|
||||||
}
|
}
|
||||||
PassMode::Pair(ref a, ref b) => {
|
PassMode::Pair(ref a, ref b) => {
|
||||||
apply(a);
|
apply(a, None);
|
||||||
apply(b);
|
apply(b, None);
|
||||||
}
|
}
|
||||||
PassMode::Cast(_) => apply(&ArgAttributes::new()),
|
PassMode::Cast(_) => apply(&ArgAttributes::new(), None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,29 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
||||||
const_cstr!("probe-stack"), const_cstr!("__rust_probestack"));
|
const_cstr!("probe-stack"), const_cstr!("__rust_probestack"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn translate_obsolete_target_features(feature: &str) -> &str {
|
||||||
|
const LLVM9_FEATURE_CHANGES: &[(&str, &str)] = &[
|
||||||
|
("+fp-only-sp", "-fp64"),
|
||||||
|
("-fp-only-sp", "+fp64"),
|
||||||
|
("+d16", "-d32"),
|
||||||
|
("-d16", "+d32"),
|
||||||
|
];
|
||||||
|
if llvm_util::get_major_version() >= 9 {
|
||||||
|
for &(old, new) in LLVM9_FEATURE_CHANGES {
|
||||||
|
if feature == old {
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for &(old, new) in LLVM9_FEATURE_CHANGES {
|
||||||
|
if feature == new {
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
feature
|
||||||
|
}
|
||||||
|
|
||||||
pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
|
pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
|
||||||
const RUSTC_SPECIFIC_FEATURES: &[&str] = &[
|
const RUSTC_SPECIFIC_FEATURES: &[&str] = &[
|
||||||
"crt-static",
|
"crt-static",
|
||||||
|
@ -129,6 +152,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
|
||||||
sess.target.target.options.features.split(',')
|
sess.target.target.options.features.split(',')
|
||||||
.chain(cmdline)
|
.chain(cmdline)
|
||||||
.filter(|l| !l.is_empty())
|
.filter(|l| !l.is_empty())
|
||||||
|
.map(translate_obsolete_target_features)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
||||||
|
|
|
@ -249,6 +249,10 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
self.const_uint(self.type_i8(), i as u64)
|
self.const_uint(self.type_i8(), i as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn const_real(&self, t: &'ll Type, val: f64) -> &'ll Value {
|
||||||
|
unsafe { llvm::LLVMConstReal(t, val) }
|
||||||
|
}
|
||||||
|
|
||||||
fn const_struct(
|
fn const_struct(
|
||||||
&self,
|
&self,
|
||||||
elts: &[&'ll Value],
|
elts: &[&'ll Value],
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::attributes;
|
use crate::attributes;
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
|
use crate::llvm_util;
|
||||||
use crate::debuginfo;
|
use crate::debuginfo;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use rustc::dep_graph::DepGraphSafe;
|
use rustc::dep_graph::DepGraphSafe;
|
||||||
|
@ -140,6 +141,11 @@ pub fn is_pie_binary(sess: &Session) -> bool {
|
||||||
!is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC
|
!is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn strip_function_ptr_alignment(data_layout: String) -> String {
|
||||||
|
// FIXME: Make this more general.
|
||||||
|
data_layout.replace("-Fi8-", "-")
|
||||||
|
}
|
||||||
|
|
||||||
pub unsafe fn create_module(
|
pub unsafe fn create_module(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
llcx: &'ll llvm::Context,
|
llcx: &'ll llvm::Context,
|
||||||
|
@ -149,14 +155,19 @@ pub unsafe fn create_module(
|
||||||
let mod_name = SmallCStr::new(mod_name);
|
let mod_name = SmallCStr::new(mod_name);
|
||||||
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
|
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
|
||||||
|
|
||||||
|
let mut target_data_layout = sess.target.target.data_layout.clone();
|
||||||
|
if llvm_util::get_major_version() < 9 {
|
||||||
|
target_data_layout = strip_function_ptr_alignment(target_data_layout);
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the data-layout values hardcoded remain the defaults.
|
// Ensure the data-layout values hardcoded remain the defaults.
|
||||||
if sess.target.target.options.is_builtin {
|
if sess.target.target.options.is_builtin {
|
||||||
let tm = crate::back::write::create_informational_target_machine(&tcx.sess, false);
|
let tm = crate::back::write::create_informational_target_machine(&tcx.sess, false);
|
||||||
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm);
|
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm);
|
||||||
llvm::LLVMRustDisposeTargetMachine(tm);
|
llvm::LLVMRustDisposeTargetMachine(tm);
|
||||||
|
|
||||||
let data_layout = llvm::LLVMGetDataLayout(llmod);
|
let llvm_data_layout = llvm::LLVMGetDataLayout(llmod);
|
||||||
let data_layout = str::from_utf8(CStr::from_ptr(data_layout).to_bytes())
|
let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
|
||||||
.ok().expect("got a non-UTF8 data-layout from LLVM");
|
.ok().expect("got a non-UTF8 data-layout from LLVM");
|
||||||
|
|
||||||
// Unfortunately LLVM target specs change over time, and right now we
|
// Unfortunately LLVM target specs change over time, and right now we
|
||||||
|
@ -177,16 +188,16 @@ pub unsafe fn create_module(
|
||||||
let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or("");
|
let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or("");
|
||||||
let custom_llvm_used = cfg_llvm_root.trim() != "";
|
let custom_llvm_used = cfg_llvm_root.trim() != "";
|
||||||
|
|
||||||
if !custom_llvm_used && sess.target.target.data_layout != data_layout {
|
if !custom_llvm_used && target_data_layout != llvm_data_layout {
|
||||||
bug!("data-layout for builtin `{}` target, `{}`, \
|
bug!("data-layout for builtin `{}` target, `{}`, \
|
||||||
differs from LLVM default, `{}`",
|
differs from LLVM default, `{}`",
|
||||||
sess.target.target.llvm_target,
|
sess.target.target.llvm_target,
|
||||||
sess.target.target.data_layout,
|
target_data_layout,
|
||||||
data_layout);
|
llvm_data_layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let data_layout = SmallCStr::new(&sess.target.target.data_layout);
|
let data_layout = SmallCStr::new(&target_data_layout);
|
||||||
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
|
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
|
||||||
|
|
||||||
let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
|
let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
|
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
fty.apply_attrs_llfn(llfn);
|
fty.apply_attrs_llfn(self, llfn);
|
||||||
|
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
|
|
|
@ -1663,9 +1663,10 @@ fn generic_simd_intrinsic(
|
||||||
acc
|
acc
|
||||||
} else {
|
} else {
|
||||||
// unordered arithmetic reductions do not:
|
// unordered arithmetic reductions do not:
|
||||||
|
let identity_acc = if $name.contains("mul") { 1.0 } else { 0.0 };
|
||||||
match f.bit_width() {
|
match f.bit_width() {
|
||||||
32 => bx.const_undef(bx.type_f32()),
|
32 => bx.const_real(bx.type_f32(), identity_acc),
|
||||||
64 => bx.const_undef(bx.type_f64()),
|
64 => bx.const_real(bx.type_f64(), identity_acc),
|
||||||
v => {
|
v => {
|
||||||
return_error!(r#"
|
return_error!(r#"
|
||||||
unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
||||||
|
|
|
@ -715,6 +715,7 @@ extern "C" {
|
||||||
// Operations on scalar constants
|
// Operations on scalar constants
|
||||||
pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value;
|
pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value;
|
||||||
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value;
|
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value;
|
||||||
|
pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value;
|
||||||
pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong;
|
pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong;
|
||||||
pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool,
|
pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool,
|
||||||
high: &mut u64, low: &mut u64) -> bool;
|
high: &mut u64, low: &mut u64) -> bool;
|
||||||
|
@ -794,6 +795,7 @@ extern "C" {
|
||||||
pub fn LLVMRustAddAlignmentAttr(Fn: &Value, index: c_uint, bytes: u32);
|
pub fn LLVMRustAddAlignmentAttr(Fn: &Value, index: c_uint, bytes: u32);
|
||||||
pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64);
|
pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64);
|
||||||
pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64);
|
pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64);
|
||||||
|
pub fn LLVMRustAddByValAttr(Fn: &Value, index: c_uint, ty: &Type);
|
||||||
pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute);
|
pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute);
|
||||||
pub fn LLVMRustAddFunctionAttrStringValue(Fn: &Value,
|
pub fn LLVMRustAddFunctionAttrStringValue(Fn: &Value,
|
||||||
index: c_uint,
|
index: c_uint,
|
||||||
|
@ -824,6 +826,7 @@ extern "C" {
|
||||||
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value,
|
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value,
|
||||||
index: c_uint,
|
index: c_uint,
|
||||||
bytes: u64);
|
bytes: u64);
|
||||||
|
pub fn LLVMRustAddByValCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type);
|
||||||
|
|
||||||
// Operations on load/store instructions (only)
|
// Operations on load/store instructions (only)
|
||||||
pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool);
|
pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool);
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
|
||||||
fn const_u64(&self, i: u64) -> Self::Value;
|
fn const_u64(&self, i: u64) -> Self::Value;
|
||||||
fn const_usize(&self, i: u64) -> Self::Value;
|
fn const_usize(&self, i: u64) -> Self::Value;
|
||||||
fn const_u8(&self, i: u8) -> Self::Value;
|
fn const_u8(&self, i: u8) -> Self::Value;
|
||||||
|
fn const_real(&self, t: Self::Type, val: f64) -> Self::Value;
|
||||||
|
|
||||||
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
|
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
|
||||||
|
|
||||||
|
|
|
@ -758,7 +758,10 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn macro_def_scope(&mut self, expansion: Mark) -> Module<'a> {
|
pub fn macro_def_scope(&mut self, expansion: Mark) -> Module<'a> {
|
||||||
let def_id = self.macro_defs[&expansion];
|
let def_id = match self.macro_defs.get(&expansion) {
|
||||||
|
Some(def_id) => *def_id,
|
||||||
|
None => return self.graph_root,
|
||||||
|
};
|
||||||
if let Some(id) = self.definitions.as_local_node_id(def_id) {
|
if let Some(id) = self.definitions.as_local_node_id(def_id) {
|
||||||
self.local_macro_def_scopes[&id]
|
self.local_macro_def_scopes[&id]
|
||||||
} else if def_id.krate == CrateNum::BuiltinMacros {
|
} else if def_id.krate == CrateNum::BuiltinMacros {
|
||||||
|
|
|
@ -17,12 +17,11 @@ use syntax::errors::DiagnosticBuilder;
|
||||||
use syntax::ext::base::{self, Determinacy};
|
use syntax::ext::base::{self, Determinacy};
|
||||||
use syntax::ext::base::{MacroKind, SyntaxExtension};
|
use syntax::ext::base::{MacroKind, SyntaxExtension};
|
||||||
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
|
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
|
||||||
use syntax::ext::hygiene::Mark;
|
use syntax::ext::hygiene::{self, Mark};
|
||||||
use syntax::ext::tt::macro_rules;
|
use syntax::ext::tt::macro_rules;
|
||||||
use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name};
|
use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name};
|
||||||
use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES};
|
use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES};
|
||||||
use syntax::symbol::{Symbol, kw, sym};
|
use syntax::symbol::{Symbol, kw, sym};
|
||||||
use syntax::visit::Visitor;
|
|
||||||
use syntax::util::lev_distance::find_best_match_for_name;
|
use syntax::util::lev_distance::find_best_match_for_name;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use errors::Applicability;
|
use errors::Applicability;
|
||||||
|
@ -146,24 +145,14 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
mark
|
mark
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_dollar_crates(&mut self, fragment: &AstFragment) {
|
fn resolve_dollar_crates(&mut self) {
|
||||||
struct ResolveDollarCrates<'a, 'b> {
|
hygiene::update_dollar_crate_names(|ctxt| {
|
||||||
resolver: &'a mut Resolver<'b>
|
let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
|
||||||
}
|
match self.resolve_crate_root(ident).kind {
|
||||||
impl<'a> Visitor<'a> for ResolveDollarCrates<'a, '_> {
|
|
||||||
fn visit_ident(&mut self, ident: Ident) {
|
|
||||||
if ident.name == kw::DollarCrate {
|
|
||||||
let name = match self.resolver.resolve_crate_root(ident).kind {
|
|
||||||
ModuleKind::Def(.., name) if name != kw::Invalid => name,
|
ModuleKind::Def(.., name) if name != kw::Invalid => name,
|
||||||
_ => kw::Crate,
|
_ => kw::Crate,
|
||||||
};
|
|
||||||
ident.span.ctxt().set_dollar_crate_name(name);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
fn visit_mac(&mut self, _: &ast::Mac) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment.visit_with(&mut ResolveDollarCrates { resolver: self });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
|
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "android".to_string(),
|
target_os: "android".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "gnu".to_string(),
|
target_env: "gnu".to_string(),
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "gnu".to_string(),
|
target_env: "gnu".to_string(),
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "musl".to_string(),
|
target_env: "musl".to_string(),
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "musl".to_string(),
|
target_env: "musl".to_string(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "big".to_string(),
|
target_endian: "big".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: "".to_string(),
|
target_env: "".to_string(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "big".to_string(),
|
target_endian: "big".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
@ -21,7 +21,7 @@ pub fn target() -> TargetResult {
|
||||||
linker: Some("rust-lld".to_owned()),
|
linker: Some("rust-lld".to_owned()),
|
||||||
relocation_model: "static".to_string(),
|
relocation_model: "static".to_string(),
|
||||||
panic_strategy: PanicStrategy::Abort,
|
panic_strategy: PanicStrategy::Abort,
|
||||||
features: "+vfp3,+d16,+fp-only-sp".to_string(),
|
features: "+vfp3,-d32,-fp16".to_string(),
|
||||||
max_atomic_width: Some(32),
|
max_atomic_width: Some(32),
|
||||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||||
emit_debug_gdb_scripts: false,
|
emit_debug_gdb_scripts: false,
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "gnu".to_string(),
|
target_env: "gnu".to_string(),
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "gnu".to_string(),
|
target_env: "gnu".to_string(),
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "musl".to_string(),
|
target_env: "musl".to_string(),
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "freebsd".to_string(),
|
target_os: "freebsd".to_string(),
|
||||||
target_env: "gnueabihf".to_string(),
|
target_env: "gnueabihf".to_string(),
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "netbsd".to_string(),
|
target_os: "netbsd".to_string(),
|
||||||
target_env: "eabihf".to_string(),
|
target_env: "eabihf".to_string(),
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(),
|
data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "ios".to_string(),
|
target_os: "ios".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
pub fn target() -> TargetResult {
|
pub fn target() -> TargetResult {
|
||||||
let mut base = super::android_base::opts();
|
let mut base = super::android_base::opts();
|
||||||
base.features = "+v7,+thumb-mode,+thumb2,+vfp3,+d16,-neon".to_string();
|
base.features = "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args
|
base.pre_link_args
|
||||||
.get_mut(&LinkerFlavor::Gcc).unwrap().push("-march=armv7-a".to_string());
|
.get_mut(&LinkerFlavor::Gcc).unwrap().push("-march=armv7-a".to_string());
|
||||||
|
@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "android".to_string(),
|
target_os: "android".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "cloudabi".to_string(),
|
target_os: "cloudabi".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "freebsd".to_string(),
|
target_os: "freebsd".to_string(),
|
||||||
target_env: "gnueabihf".to_string(),
|
target_env: "gnueabihf".to_string(),
|
||||||
|
@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
|
||||||
linker_flavor: LinkerFlavor::Gcc,
|
linker_flavor: LinkerFlavor::Gcc,
|
||||||
|
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
|
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||||
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
|
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "gnu".to_string(),
|
target_env: "gnu".to_string(),
|
||||||
|
@ -19,7 +19,7 @@ pub fn target() -> TargetResult {
|
||||||
|
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
// Info about features at https://wiki.debian.org/ArmHardFloatPort
|
// Info about features at https://wiki.debian.org/ArmHardFloatPort
|
||||||
features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
|
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
|
||||||
cpu: "generic".to_string(),
|
cpu: "generic".to_string(),
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "musl".to_string(),
|
target_env: "musl".to_string(),
|
||||||
|
@ -22,7 +22,7 @@ pub fn target() -> TargetResult {
|
||||||
// Most of these settings are copied from the armv7_unknown_linux_gnueabihf
|
// Most of these settings are copied from the armv7_unknown_linux_gnueabihf
|
||||||
// target.
|
// target.
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
|
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
|
||||||
cpu: "generic".to_string(),
|
cpu: "generic".to_string(),
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "netbsd".to_string(),
|
target_os: "netbsd".to_string(),
|
||||||
target_env: "eabihf".to_string(),
|
target_env: "eabihf".to_string(),
|
||||||
|
@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
|
||||||
linker_flavor: LinkerFlavor::Gcc,
|
linker_flavor: LinkerFlavor::Gcc,
|
||||||
|
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
|
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
|
||||||
cpu: "generic".to_string(),
|
cpu: "generic".to_string(),
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: "".to_string(),
|
target_env: "".to_string(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: "".to_string(),
|
target_env: "".to_string(),
|
||||||
|
@ -21,7 +21,7 @@ pub fn target() -> TargetResult {
|
||||||
linker: Some("rust-lld".to_owned()),
|
linker: Some("rust-lld".to_owned()),
|
||||||
relocation_model: "static".to_string(),
|
relocation_model: "static".to_string(),
|
||||||
panic_strategy: PanicStrategy::Abort,
|
panic_strategy: PanicStrategy::Abort,
|
||||||
features: "+vfp3,+d16,+fp-only-sp".to_string(),
|
features: "+vfp3,-d32,-fp16".to_string(),
|
||||||
max_atomic_width: Some(32),
|
max_atomic_width: Some(32),
|
||||||
abi_blacklist: super::arm_base::abi_blacklist(),
|
abi_blacklist: super::arm_base::abi_blacklist(),
|
||||||
emit_debug_gdb_scripts: false,
|
emit_debug_gdb_scripts: false,
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(),
|
data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "ios".to_string(),
|
target_os: "ios".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -497,8 +497,8 @@ pub struct Target {
|
||||||
pub target_env: String,
|
pub target_env: String,
|
||||||
/// Vendor name to use for conditional compilation.
|
/// Vendor name to use for conditional compilation.
|
||||||
pub target_vendor: String,
|
pub target_vendor: String,
|
||||||
/// Architecture to use for ABI considerations. Valid options: "x86",
|
/// Architecture to use for ABI considerations. Valid options include: "x86",
|
||||||
/// "x86_64", "arm", "aarch64", "mips", "powerpc", and "powerpc64".
|
/// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", and others.
|
||||||
pub arch: String,
|
pub arch: String,
|
||||||
/// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
|
/// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
|
||||||
pub data_layout: String,
|
pub data_layout: String,
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:w-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "windows".to_string(),
|
target_os: "windows".to_string(),
|
||||||
target_env: "msvc".to_string(),
|
target_env: "msvc".to_string(),
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// Additionally, this target uses the "hard" floating convention (ABI) where floating point values
|
// Additionally, this target uses the "hard" floating convention (ABI) where floating point values
|
||||||
// are passed to/from subroutines via FPU registers (S0, S1, D0, D1, etc.).
|
// are passed to/from subroutines via FPU registers (S0, S1, D0, D1, etc.).
|
||||||
//
|
//
|
||||||
// To opt into double precision hardware support, use the `-C target-feature=-fp-only-sp` flag.
|
// To opt into double precision hardware support, use the `-C target-feature=+fp64` flag.
|
||||||
|
|
||||||
use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
|
use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
@ -26,14 +26,14 @@ pub fn target() -> TargetResult {
|
||||||
options: TargetOptions {
|
options: TargetOptions {
|
||||||
// `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the
|
// `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the
|
||||||
// Cortex-M7 (vfp5)
|
// Cortex-M7 (vfp5)
|
||||||
// `+d16` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers
|
// `-d32` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers
|
||||||
// available
|
// available
|
||||||
// `+fp-only-sp` The Cortex-M4 only supports single precision floating point operations
|
// `-fp64` The Cortex-M4 only supports single precision floating point operations
|
||||||
// whereas in the Cortex-M7 double precision is optional
|
// whereas in the Cortex-M7 double precision is optional
|
||||||
//
|
//
|
||||||
// Reference:
|
// Reference:
|
||||||
// ARMv7-M Architecture Reference Manual - A2.5 The optional floating-point extension
|
// ARMv7-M Architecture Reference Manual - A2.5 The optional floating-point extension
|
||||||
features: "+vfp4,+d16,+fp-only-sp".to_string(),
|
features: "+vfp4,-d32,-fp64".to_string(),
|
||||||
max_atomic_width: Some(32),
|
max_atomic_width: Some(32),
|
||||||
.. super::thumb_base::opts()
|
.. super::thumb_base::opts()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "android".to_string(),
|
target_os: "android".to_string(),
|
||||||
target_env: "".to_string(),
|
target_env: "".to_string(),
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "linux".to_string(),
|
target_os: "linux".to_string(),
|
||||||
target_env: "gnu".to_string(),
|
target_env: "gnu".to_string(),
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub fn target() -> TargetResult {
|
||||||
target_endian: "little".to_string(),
|
target_endian: "little".to_string(),
|
||||||
target_pointer_width: "32".to_string(),
|
target_pointer_width: "32".to_string(),
|
||||||
target_c_int_width: "32".to_string(),
|
target_c_int_width: "32".to_string(),
|
||||||
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
|
||||||
arch: "arm".to_string(),
|
arch: "arm".to_string(),
|
||||||
target_os: "none".to_string(),
|
target_os: "none".to_string(),
|
||||||
target_env: String::new(),
|
target_env: String::new(),
|
||||||
|
@ -22,7 +22,7 @@ pub fn target() -> TargetResult {
|
||||||
// the FPU uses the FPv5 architecture, single-precision instructions
|
// the FPU uses the FPv5 architecture, single-precision instructions
|
||||||
// and 16 D registers.
|
// and 16 D registers.
|
||||||
// These parameters map to the following LLVM features.
|
// These parameters map to the following LLVM features.
|
||||||
features: "+fp-armv8,+fp-only-sp,+d16".to_string(),
|
features: "+fp-armv8,-fp64,-d32".to_string(),
|
||||||
max_atomic_width: Some(32),
|
max_atomic_width: Some(32),
|
||||||
.. super::thumb_base::opts()
|
.. super::thumb_base::opts()
|
||||||
},
|
},
|
||||||
|
|
|
@ -701,7 +701,7 @@ pub trait Resolver {
|
||||||
|
|
||||||
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
|
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
|
||||||
|
|
||||||
fn resolve_dollar_crates(&mut self, fragment: &AstFragment);
|
fn resolve_dollar_crates(&mut self);
|
||||||
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
|
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
|
||||||
derives: &[Mark]);
|
derives: &[Mark]);
|
||||||
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
|
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
|
||||||
|
|
|
@ -429,7 +429,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[Mark])
|
fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[Mark])
|
||||||
-> (AstFragment, Vec<Invocation>) {
|
-> (AstFragment, Vec<Invocation>) {
|
||||||
// Resolve `$crate`s in the fragment for pretty-printing.
|
// Resolve `$crate`s in the fragment for pretty-printing.
|
||||||
self.cx.resolver.resolve_dollar_crates(&fragment);
|
self.cx.resolver.resolve_dollar_crates();
|
||||||
|
|
||||||
let invocations = {
|
let invocations = {
|
||||||
let mut collector = InvocationCollector {
|
let mut collector = InvocationCollector {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree};
|
||||||
|
|
||||||
use rustc_target::spec::abi::{self, Abi};
|
use rustc_target::spec::abi::{self, Abi};
|
||||||
use syntax_pos::{self, BytePos};
|
use syntax_pos::{self, BytePos};
|
||||||
use syntax_pos::{DUMMY_SP, FileName};
|
use syntax_pos::{DUMMY_SP, FileName, Span};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
@ -181,7 +181,46 @@ pub fn literal_to_string(lit: token::Lit) -> String {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ident_to_string(ident: ast::Ident, is_raw: bool) -> String {
|
||||||
|
ident_to_string_ext(ident.name, is_raw, Some(ident.span))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AST pretty-printer is used as a fallback for turning AST structures into token streams for
|
||||||
|
// proc macros. Additionally, proc macros may stringify their input and expect it survive the
|
||||||
|
// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
|
||||||
|
// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
|
||||||
|
// hygiene data, most importantly name of the crate it refers to.
|
||||||
|
// As a result we print `$crate` as `crate` if it refers to the local crate
|
||||||
|
// and as `::other_crate_name` if it refers to some other crate.
|
||||||
|
// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
|
||||||
|
// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
|
||||||
|
// so we should not perform this lossy conversion if the top level call to the pretty-printer was
|
||||||
|
// done for a token stream or a single token.
|
||||||
|
fn ident_to_string_ext(
|
||||||
|
name: ast::Name, is_raw: bool, convert_dollar_crate: Option<Span>
|
||||||
|
) -> String {
|
||||||
|
if is_raw {
|
||||||
|
format!("r#{}", name)
|
||||||
|
} else {
|
||||||
|
if name == kw::DollarCrate {
|
||||||
|
if let Some(span) = convert_dollar_crate {
|
||||||
|
let converted = span.ctxt().dollar_crate_name();
|
||||||
|
return if converted.is_path_segment_keyword() {
|
||||||
|
converted.to_string()
|
||||||
|
} else {
|
||||||
|
format!("::{}", converted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn token_kind_to_string(tok: &TokenKind) -> String {
|
pub fn token_kind_to_string(tok: &TokenKind) -> String {
|
||||||
|
token_kind_to_string_ext(tok, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>) -> String {
|
||||||
match *tok {
|
match *tok {
|
||||||
token::Eq => "=".to_string(),
|
token::Eq => "=".to_string(),
|
||||||
token::Lt => "<".to_string(),
|
token::Lt => "<".to_string(),
|
||||||
|
@ -227,8 +266,7 @@ pub fn token_kind_to_string(tok: &TokenKind) -> String {
|
||||||
token::Literal(lit) => literal_to_string(lit),
|
token::Literal(lit) => literal_to_string(lit),
|
||||||
|
|
||||||
/* Name components */
|
/* Name components */
|
||||||
token::Ident(s, false) => s.to_string(),
|
token::Ident(s, is_raw) => ident_to_string_ext(s, is_raw, convert_dollar_crate),
|
||||||
token::Ident(s, true) => format!("r#{}", s),
|
|
||||||
token::Lifetime(s) => s.to_string(),
|
token::Lifetime(s) => s.to_string(),
|
||||||
|
|
||||||
/* Other */
|
/* Other */
|
||||||
|
@ -243,7 +281,12 @@ pub fn token_kind_to_string(tok: &TokenKind) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn token_to_string(token: &Token) -> String {
|
pub fn token_to_string(token: &Token) -> String {
|
||||||
token_kind_to_string(&token.kind)
|
token_to_string_ext(token, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
|
||||||
|
let convert_dollar_crate = if convert_dollar_crate { Some(token.span) } else { None };
|
||||||
|
token_kind_to_string_ext(&token.kind, convert_dollar_crate)
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn nonterminal_to_string(nt: &Nonterminal) -> String {
|
crate fn nonterminal_to_string(nt: &Nonterminal) -> String {
|
||||||
|
@ -256,9 +299,8 @@ crate fn nonterminal_to_string(nt: &Nonterminal) -> String {
|
||||||
token::NtBlock(ref e) => block_to_string(e),
|
token::NtBlock(ref e) => block_to_string(e),
|
||||||
token::NtStmt(ref e) => stmt_to_string(e),
|
token::NtStmt(ref e) => stmt_to_string(e),
|
||||||
token::NtPat(ref e) => pat_to_string(e),
|
token::NtPat(ref e) => pat_to_string(e),
|
||||||
token::NtIdent(e, false) => ident_to_string(e),
|
token::NtIdent(e, is_raw) => ident_to_string(e, is_raw),
|
||||||
token::NtIdent(e, true) => format!("r#{}", ident_to_string(e)),
|
token::NtLifetime(e) => e.to_string(),
|
||||||
token::NtLifetime(e) => ident_to_string(e),
|
|
||||||
token::NtLiteral(ref e) => expr_to_string(e),
|
token::NtLiteral(ref e) => expr_to_string(e),
|
||||||
token::NtTT(ref tree) => tt_to_string(tree.clone()),
|
token::NtTT(ref tree) => tt_to_string(tree.clone()),
|
||||||
token::NtImplItem(ref e) => impl_item_to_string(e),
|
token::NtImplItem(ref e) => impl_item_to_string(e),
|
||||||
|
@ -293,15 +335,15 @@ pub fn lifetime_to_string(lt: &ast::Lifetime) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
|
pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
|
||||||
to_string(|s| s.print_tt(tt))
|
to_string(|s| s.print_tt(tt, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String {
|
pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String {
|
||||||
to_string(|s| s.print_tts(tts.iter().cloned().collect()))
|
tokens_to_string(tts.iter().cloned().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tokens_to_string(tokens: TokenStream) -> String {
|
pub fn tokens_to_string(tokens: TokenStream) -> String {
|
||||||
to_string(|s| s.print_tts(tokens))
|
to_string(|s| s.print_tts_ext(tokens, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
|
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
|
||||||
|
@ -344,10 +386,6 @@ pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
|
||||||
to_string(|s| s.print_path_segment(p, false))
|
to_string(|s| s.print_path_segment(p, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ident_to_string(id: ast::Ident) -> String {
|
|
||||||
to_string(|s| s.print_ident(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn vis_to_string(v: &ast::Visibility) -> String {
|
pub fn vis_to_string(v: &ast::Visibility) -> String {
|
||||||
to_string(|s| s.print_visibility(v))
|
to_string(|s| s.print_visibility(v))
|
||||||
}
|
}
|
||||||
|
@ -629,11 +667,7 @@ pub trait PrintState<'a> {
|
||||||
self.writer().word("::");
|
self.writer().word("::");
|
||||||
}
|
}
|
||||||
if segment.ident.name != kw::PathRoot {
|
if segment.ident.name != kw::PathRoot {
|
||||||
if segment.ident.name == kw::DollarCrate {
|
self.writer().word(ident_to_string(segment.ident, segment.ident.is_raw_guess()));
|
||||||
self.print_dollar_crate(segment.ident);
|
|
||||||
} else {
|
|
||||||
self.writer().word(segment.ident.as_str().to_string());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -707,10 +741,10 @@ pub trait PrintState<'a> {
|
||||||
/// appropriate macro, transcribe back into the grammar we just parsed from,
|
/// appropriate macro, transcribe back into the grammar we just parsed from,
|
||||||
/// and then pretty-print the resulting AST nodes (so, e.g., we print
|
/// and then pretty-print the resulting AST nodes (so, e.g., we print
|
||||||
/// expression arguments as expressions). It can be done! I think.
|
/// expression arguments as expressions). It can be done! I think.
|
||||||
fn print_tt(&mut self, tt: tokenstream::TokenTree) {
|
fn print_tt(&mut self, tt: tokenstream::TokenTree, convert_dollar_crate: bool) {
|
||||||
match tt {
|
match tt {
|
||||||
TokenTree::Token(ref token) => {
|
TokenTree::Token(ref token) => {
|
||||||
self.writer().word(token_to_string(&token));
|
self.writer().word(token_to_string_ext(&token, convert_dollar_crate));
|
||||||
match token.kind {
|
match token.kind {
|
||||||
token::DocComment(..) => {
|
token::DocComment(..) => {
|
||||||
self.writer().hardbreak()
|
self.writer().hardbreak()
|
||||||
|
@ -729,12 +763,16 @@ pub trait PrintState<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_tts(&mut self, tts: tokenstream::TokenStream) {
|
fn print_tts(&mut self, tts: tokenstream::TokenStream) {
|
||||||
|
self.print_tts_ext(tts, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_tts_ext(&mut self, tts: tokenstream::TokenStream, convert_dollar_crate: bool) {
|
||||||
self.ibox(0);
|
self.ibox(0);
|
||||||
for (i, tt) in tts.into_trees().enumerate() {
|
for (i, tt) in tts.into_trees().enumerate() {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
self.writer().space();
|
self.writer().space();
|
||||||
}
|
}
|
||||||
self.print_tt(tt);
|
self.print_tt(tt, convert_dollar_crate);
|
||||||
}
|
}
|
||||||
self.end();
|
self.end();
|
||||||
}
|
}
|
||||||
|
@ -744,21 +782,6 @@ pub trait PrintState<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nbsp(&mut self) { self.writer().word(" ") }
|
fn nbsp(&mut self) { self.writer().word(" ") }
|
||||||
|
|
||||||
// AST pretty-printer is used as a fallback for turning AST structures into token streams for
|
|
||||||
// proc macros. Additionally, proc macros may stringify their input and expect it survive the
|
|
||||||
// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
|
|
||||||
// So we need to somehow pretty-print `$crate` in paths in a way preserving at least some of
|
|
||||||
// its hygiene data, most importantly name of the crate it refers to.
|
|
||||||
// As a result we print `$crate` as `crate` if it refers to the local crate
|
|
||||||
// and as `::other_crate_name` if it refers to some other crate.
|
|
||||||
fn print_dollar_crate(&mut self, ident: ast::Ident) {
|
|
||||||
let name = ident.span.ctxt().dollar_crate_name();
|
|
||||||
if !ast::Ident::with_empty_ctxt(name).is_path_segment_keyword() {
|
|
||||||
self.writer().word("::");
|
|
||||||
}
|
|
||||||
self.writer().word(name.as_str().to_string())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrintState<'a> for State<'a> {
|
impl<'a> PrintState<'a> for State<'a> {
|
||||||
|
@ -2287,11 +2310,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn print_ident(&mut self, ident: ast::Ident) {
|
crate fn print_ident(&mut self, ident: ast::Ident) {
|
||||||
if ident.is_raw_guess() {
|
self.s.word(ident_to_string(ident, ident.is_raw_guess()));
|
||||||
self.s.word(format!("r#{}", ident));
|
|
||||||
} else {
|
|
||||||
self.s.word(ident.as_str().to_string());
|
|
||||||
}
|
|
||||||
self.ann.post(self, AnnNode::Ident(&ident))
|
self.ann.post(self, AnnNode::Ident(&ident))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2322,11 +2341,7 @@ impl<'a> State<'a> {
|
||||||
segment: &ast::PathSegment,
|
segment: &ast::PathSegment,
|
||||||
colons_before_params: bool) {
|
colons_before_params: bool) {
|
||||||
if segment.ident.name != kw::PathRoot {
|
if segment.ident.name != kw::PathRoot {
|
||||||
if segment.ident.name == kw::DollarCrate {
|
|
||||||
self.print_dollar_crate(segment.ident);
|
|
||||||
} else {
|
|
||||||
self.print_ident(segment.ident);
|
self.print_ident(segment.ident);
|
||||||
}
|
|
||||||
if let Some(ref args) = segment.args {
|
if let Some(ref args) = segment.args {
|
||||||
self.print_generic_args(args, colons_before_params);
|
self.print_generic_args(args, colons_before_params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ use crate::symbol::{kw, Symbol};
|
||||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use std::{fmt, mem};
|
use std::fmt;
|
||||||
|
|
||||||
/// A SyntaxContext represents a chain of macro expansions (represented by marks).
|
/// A SyntaxContext represents a chain of macro expansions (represented by marks).
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
|
||||||
|
@ -387,6 +387,23 @@ pub fn walk_chain(span: Span, to: SyntaxContext) -> Span {
|
||||||
HygieneData::with(|data| data.walk_chain(span, to))
|
HygieneData::with(|data| data.walk_chain(span, to))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symbol) {
|
||||||
|
// The new contexts that need updating are at the end of the list and have `$crate` as a name.
|
||||||
|
let (len, to_update) = HygieneData::with(|data| (
|
||||||
|
data.syntax_contexts.len(),
|
||||||
|
data.syntax_contexts.iter().rev()
|
||||||
|
.take_while(|scdata| scdata.dollar_crate_name == kw::DollarCrate).count()
|
||||||
|
));
|
||||||
|
// The callback must be called from outside of the `HygieneData` lock,
|
||||||
|
// since it will try to acquire it too.
|
||||||
|
let range_to_update = len - to_update .. len;
|
||||||
|
let names: Vec<_> =
|
||||||
|
range_to_update.clone().map(|idx| get_name(SyntaxContext::from_u32(idx as u32))).collect();
|
||||||
|
HygieneData::with(|data| range_to_update.zip(names.into_iter()).for_each(|(idx, name)| {
|
||||||
|
data.syntax_contexts[idx].dollar_crate_name = name;
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
impl SyntaxContext {
|
impl SyntaxContext {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn empty() -> Self {
|
pub const fn empty() -> Self {
|
||||||
|
@ -614,17 +631,6 @@ impl SyntaxContext {
|
||||||
pub fn dollar_crate_name(self) -> Symbol {
|
pub fn dollar_crate_name(self) -> Symbol {
|
||||||
HygieneData::with(|data| data.syntax_contexts[self.0 as usize].dollar_crate_name)
|
HygieneData::with(|data| data.syntax_contexts[self.0 as usize].dollar_crate_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_dollar_crate_name(self, dollar_crate_name: Symbol) {
|
|
||||||
HygieneData::with(|data| {
|
|
||||||
let prev_dollar_crate_name = mem::replace(
|
|
||||||
&mut data.syntax_contexts[self.0 as usize].dollar_crate_name, dollar_crate_name
|
|
||||||
);
|
|
||||||
assert!(dollar_crate_name == prev_dollar_crate_name ||
|
|
||||||
prev_dollar_crate_name == kw::DollarCrate,
|
|
||||||
"$crate name is reset for a syntax context");
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for SyntaxContext {
|
impl fmt::Debug for SyntaxContext {
|
||||||
|
|
|
@ -913,7 +913,10 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
|
||||||
GlobalValue::LinkageTypes NewLinkage) {
|
GlobalValue::LinkageTypes NewLinkage) {
|
||||||
ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
|
ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
|
||||||
};
|
};
|
||||||
#if LLVM_VERSION_GE(8, 0)
|
#if LLVM_VERSION_GE(9, 0)
|
||||||
|
thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
|
||||||
|
Ret->GUIDPreservedSymbols);
|
||||||
|
#elif LLVM_VERSION_GE(8, 0)
|
||||||
thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage);
|
thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage);
|
||||||
#else
|
#else
|
||||||
thinLTOResolveWeakForLinkerInIndex(Ret->Index, isPrevailing, recordNewLinkage);
|
thinLTOResolveWeakForLinkerInIndex(Ret->Index, isPrevailing, recordNewLinkage);
|
||||||
|
|
|
@ -237,6 +237,17 @@ extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
|
||||||
Call->getContext(), Index, B));
|
Call->getContext(), Index, B));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
|
||||||
|
LLVMTypeRef Ty) {
|
||||||
|
CallSite Call = CallSite(unwrap<Instruction>(Instr));
|
||||||
|
#if LLVM_VERSION_GE(9, 0)
|
||||||
|
Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
|
||||||
|
#else
|
||||||
|
Attribute Attr = Attribute::get(Call->getContext(), Attribute::ByVal);
|
||||||
|
#endif
|
||||||
|
Call.addAttribute(Index, Attr);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
|
extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
|
||||||
LLVMRustAttribute RustAttr) {
|
LLVMRustAttribute RustAttr) {
|
||||||
Function *A = unwrap<Function>(Fn);
|
Function *A = unwrap<Function>(Fn);
|
||||||
|
@ -271,6 +282,17 @@ extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
|
||||||
A->addAttributes(Index, B);
|
A->addAttributes(Index, B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
|
||||||
|
LLVMTypeRef Ty) {
|
||||||
|
Function *F = unwrap<Function>(Fn);
|
||||||
|
#if LLVM_VERSION_GE(9, 0)
|
||||||
|
Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
|
||||||
|
#else
|
||||||
|
Attribute Attr = Attribute::get(F->getContext(), Attribute::ByVal);
|
||||||
|
#endif
|
||||||
|
F->addAttribute(Index, Attr);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
|
extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
|
||||||
unsigned Index,
|
unsigned Index,
|
||||||
const char *Name,
|
const char *Name,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// compile-flags: -g -C no-prepopulate-passes
|
// compile-flags: -g -C no-prepopulate-passes
|
||||||
|
|
||||||
// CHECK-LABEL: @main
|
// CHECK-LABEL: @main
|
||||||
// CHECK: {{.*}}DISubprogram{{.*}}name: "main",{{.*}}DIFlagMainSubprogram{{.*}}
|
// CHECK: {{.*}}DISubprogram{{.*}}name: "main",{{.*}}DI{{(SP)?}}FlagMainSubprogram{{.*}}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#![feature(start)]
|
#![feature(start)]
|
||||||
|
|
||||||
// CHECK-LABEL: @main
|
// CHECK-LABEL: @main
|
||||||
// CHECK: {{.*}}DISubprogram{{.*}}name: "start",{{.*}}DIFlagMainSubprogram{{.*}}
|
// CHECK: {{.*}}DISubprogram{{.*}}name: "start",{{.*}}DI{{(SP)?}}FlagMainSubprogram{{.*}}
|
||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
fn start(_: isize, _: *const *const u8) -> isize {
|
fn start(_: isize, _: *const *const u8) -> isize {
|
||||||
|
|
|
@ -14,3 +14,9 @@ macro_rules! external {
|
||||||
struct D($crate::S);
|
struct D($crate::S);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! issue_62325 { () => {
|
||||||
|
#[print_attr]
|
||||||
|
struct B(identity!($crate::S));
|
||||||
|
}}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ;
|
PRINT-BANG INPUT (DISPLAY): struct M ( crate :: S ) ;
|
||||||
PRINT-BANG INPUT (DEBUG): TokenStream [
|
PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -39,7 +39,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): struct A(crate::S);
|
PRINT-ATTR INPUT (DISPLAY): struct A(crate::S);
|
||||||
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ;
|
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( crate :: S ) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
|
27
src/test/ui/proc-macro/dollar-crate-issue-62325.rs
Normal file
27
src/test/ui/proc-macro/dollar-crate-issue-62325.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// check-pass
|
||||||
|
// edition:2018
|
||||||
|
// aux-build:test-macros.rs
|
||||||
|
// aux-build:dollar-crate-external.rs
|
||||||
|
|
||||||
|
// Anonymize unstable non-dummy spans while still showing dummy spans `0..0`.
|
||||||
|
// normalize-stdout-test "bytes\([^0]\w*\.\.(\w+)\)" -> "bytes(LO..$1)"
|
||||||
|
// normalize-stdout-test "bytes\((\w+)\.\.[^0]\w*\)" -> "bytes($1..HI)"
|
||||||
|
|
||||||
|
#![feature(proc_macro_hygiene)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate test_macros;
|
||||||
|
extern crate dollar_crate_external;
|
||||||
|
|
||||||
|
type S = u8;
|
||||||
|
|
||||||
|
macro_rules! m { () => {
|
||||||
|
#[print_attr]
|
||||||
|
struct A(identity!($crate::S));
|
||||||
|
}}
|
||||||
|
|
||||||
|
m!();
|
||||||
|
|
||||||
|
dollar_crate_external::issue_62325!();
|
||||||
|
|
||||||
|
fn main() {}
|
112
src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
Normal file
112
src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
PRINT-ATTR INPUT (DISPLAY): struct A(identity!(crate :: S));
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( identity ! ( crate :: S ) ) ;
|
||||||
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
|
Ident {
|
||||||
|
ident: "struct",
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Ident {
|
||||||
|
ident: "A",
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Group {
|
||||||
|
delimiter: Parenthesis,
|
||||||
|
stream: TokenStream [
|
||||||
|
Ident {
|
||||||
|
ident: "identity",
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Punct {
|
||||||
|
ch: '!',
|
||||||
|
spacing: Alone,
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Group {
|
||||||
|
delimiter: Parenthesis,
|
||||||
|
stream: TokenStream [
|
||||||
|
Ident {
|
||||||
|
ident: "$crate",
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Punct {
|
||||||
|
ch: ':',
|
||||||
|
spacing: Joint,
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Punct {
|
||||||
|
ch: ':',
|
||||||
|
spacing: Alone,
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Ident {
|
||||||
|
ident: "S",
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Punct {
|
||||||
|
ch: ';',
|
||||||
|
spacing: Alone,
|
||||||
|
span: #2 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
PRINT-ATTR INPUT (DISPLAY): struct B(identity!(::dollar_crate_external :: S));
|
||||||
|
PRINT-ATTR RE-COLLECTED (DISPLAY): struct B ( identity ! ( ::dollar_crate_external :: S ) ) ;
|
||||||
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
|
Ident {
|
||||||
|
ident: "struct",
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Ident {
|
||||||
|
ident: "B",
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Group {
|
||||||
|
delimiter: Parenthesis,
|
||||||
|
stream: TokenStream [
|
||||||
|
Ident {
|
||||||
|
ident: "identity",
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Punct {
|
||||||
|
ch: '!',
|
||||||
|
spacing: Alone,
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Group {
|
||||||
|
delimiter: Parenthesis,
|
||||||
|
stream: TokenStream [
|
||||||
|
Ident {
|
||||||
|
ident: "$crate",
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Punct {
|
||||||
|
ch: ':',
|
||||||
|
spacing: Joint,
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Punct {
|
||||||
|
ch: ':',
|
||||||
|
spacing: Alone,
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Ident {
|
||||||
|
ident: "S",
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
Punct {
|
||||||
|
ch: ';',
|
||||||
|
spacing: Alone,
|
||||||
|
span: #7 bytes(LO..HI),
|
||||||
|
},
|
||||||
|
]
|
|
@ -1,4 +1,4 @@
|
||||||
PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ;
|
PRINT-BANG INPUT (DISPLAY): struct M ( crate :: S ) ;
|
||||||
PRINT-BANG INPUT (DEBUG): TokenStream [
|
PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -39,7 +39,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): struct A(crate::S);
|
PRINT-ATTR INPUT (DISPLAY): struct A(crate::S);
|
||||||
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ;
|
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( crate :: S ) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -80,7 +80,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-DERIVE INPUT (DISPLAY): struct D(crate::S);
|
PRINT-DERIVE INPUT (DISPLAY): struct D(crate::S);
|
||||||
PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( $crate :: S ) ;
|
PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( crate :: S ) ;
|
||||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -120,7 +120,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||||
span: #2 bytes(LO..HI),
|
span: #2 bytes(LO..HI),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ;
|
PRINT-BANG INPUT (DISPLAY): struct M ( ::dollar_crate_external :: S ) ;
|
||||||
PRINT-BANG INPUT (DEBUG): TokenStream [
|
PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -161,7 +161,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S);
|
PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S);
|
||||||
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ;
|
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( ::dollar_crate_external :: S ) ;
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
@ -202,7 +202,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S);
|
PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S);
|
||||||
PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( $crate :: S ) ;
|
PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( ::dollar_crate_external :: S ) ;
|
||||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||||
Ident {
|
Ident {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
|
|
Loading…
Reference in a new issue