summaryrefslogtreecommitdiff
path: root/compiler/rustc_abi/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_abi/src/lib.rs')
-rw-r--r--compiler/rustc_abi/src/lib.rs44
1 files changed, 44 insertions, 0 deletions
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index d01a9b00304..43db66a3c28 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1272,6 +1272,50 @@ impl Abi {
pub fn is_scalar(&self) -> bool {
matches!(*self, Abi::Scalar(_))
}
+
+ /// Returns the fixed alignment of this ABI, if any is mandated.
+ pub fn inherent_align<C: HasDataLayout>(&self, cx: &C) -> Option<AbiAndPrefAlign> {
+ Some(match *self {
+ Abi::Scalar(s) => s.align(cx),
+ Abi::ScalarPair(s1, s2) => s1.align(cx).max(s2.align(cx)),
+ Abi::Vector { element, count } => {
+ cx.data_layout().vector_align(element.size(cx) * count)
+ }
+ Abi::Uninhabited | Abi::Aggregate { .. } => return None,
+ })
+ }
+
+ /// Returns the fixed size of this ABI, if any is mandated.
+ pub fn inherent_size<C: HasDataLayout>(&self, cx: &C) -> Option<Size> {
+ Some(match *self {
+ Abi::Scalar(s) => {
+ // No padding in scalars.
+ s.size(cx)
+ }
+ Abi::ScalarPair(s1, s2) => {
+ // May have some padding between the pair.
+ let field2_offset = s1.size(cx).align_to(s2.align(cx).abi);
+ (field2_offset + s2.size(cx)).align_to(self.inherent_align(cx)?.abi)
+ }
+ Abi::Vector { element, count } => {
+ // No padding in vectors, except possibly for trailing padding
+ // to make the size a multiple of align (e.g. for vectors of size 3).
+ (element.size(cx) * count).align_to(self.inherent_align(cx)?.abi)
+ }
+ Abi::Uninhabited | Abi::Aggregate { .. } => return None,
+ })
+ }
+
+ /// Discard validity range information and allow undef.
+ pub fn to_union(&self) -> Self {
+ assert!(self.is_sized());
+ match *self {
+ Abi::Scalar(s) => Abi::Scalar(s.to_union()),
+ Abi::ScalarPair(s1, s2) => Abi::ScalarPair(s1.to_union(), s2.to_union()),
+ Abi::Vector { element, count } => Abi::Vector { element: element.to_union(), count },
+ Abi::Uninhabited | Abi::Aggregate { .. } => Abi::Aggregate { sized: true },
+ }
+ }
}
#[derive(PartialEq, Eq, Hash, Clone, Debug)]