diff options
| author | Cameron Hart <cameron.hart@gmail.com> | 2017-01-15 09:49:29 +1100 |
|---|---|---|
| committer | Cameron Hart <cameron.hart@gmail.com> | 2017-04-21 07:32:32 +1000 |
| commit | 4358e35fda66ab7a00215c7f9d50e7c6dc9b801b (patch) | |
| tree | a25741bc07d2a01d06a99d2135a776c61d42e3d5 /src/libsyntax | |
| parent | ddc5d7bd4b9ea3e8a8ccf82cb443e950be311d61 (diff) | |
| download | rust-4358e35fda66ab7a00215c7f9d50e7c6dc9b801b.tar.gz rust-4358e35fda66ab7a00215c7f9d50e7c6dc9b801b.zip | |
Implementation of repr struct alignment RFC 1358.
The main changes around rustc::ty::Layout::struct and rustc_trans:adt: * Added primitive_align field which stores alignment before repr align * Always emit field padding when generating the LLVM struct fields * Added methods for adjusting field indexes from the layout index to the LLVM struct field index The main user of this information is rustc_trans::adt::struct_llfields which determines the LLVM fields to be used by LLVM, including padding fields.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/attr.rs | 50 | ||||
| -rw-r--r-- | src/libsyntax/diagnostic_list.rs | 2 |
2 files changed, 45 insertions, 7 deletions
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 6f5f52ff1e9..442345ceb3c 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -147,6 +147,24 @@ impl NestedMetaItem { self.meta_item().and_then(|meta_item| meta_item.value_str()) } + /// Returns a name and single literal value tuple of the MetaItem. + pub fn name_value_literal(&self) -> Option<(Name, &Lit)> { + self.meta_item().and_then( + |meta_item| meta_item.meta_item_list().and_then( + |meta_item_list| { + if meta_item_list.len() == 1 { + let nested_item = &meta_item_list[0]; + if nested_item.is_literal() { + Some((meta_item.name(), nested_item.literal().unwrap())) + } else { + None + } + } + else { + None + }})) + } + /// Returns a MetaItem if self is a MetaItem with Kind Word. pub fn word(&self) -> Option<&MetaItem> { self.meta_item().and_then(|meta_item| if meta_item.is_word() { @@ -931,6 +949,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> continue } + let mut recognised = false; if let Some(mi) = item.word() { let word = &*mi.name().as_str(); let hint = match word { @@ -941,20 +960,38 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> _ => match int_type_of_word(word) { Some(ity) => Some(ReprInt(ity)), None => { - // Not a word we recognize - span_err!(diagnostic, item.span, E0552, - "unrecognized representation hint"); None } } }; if let Some(h) = hint { + recognised = true; acc.push(h); } - } else { - span_err!(diagnostic, item.span, E0553, - "unrecognized enum representation hint"); + } else if let Some((name, value)) = item.name_value_literal() { + if name == "align" { + recognised = true; + let mut valid_align = false; + if let ast::LitKind::Int(align, ast::LitIntType::Unsuffixed) = value.node { + if align.is_power_of_two() { + // rustc::ty::layout::Align restricts align to <= 32768 + if align <= 32768 { + acc.push(ReprAlign(align as u16)); + valid_align = true; + } + } + } + if !valid_align { + span_err!(diagnostic, item.span, E0589, + "align representation must be a u16 power of two"); + } + } + } + if !recognised { + // Not a word we recognize + span_err!(diagnostic, item.span, E0552, + "unrecognized representation hint"); } } } @@ -986,6 +1023,7 @@ pub enum ReprAttr { ReprExtern, ReprPacked, ReprSimd, + ReprAlign(u16), } #[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)] diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 2d59051ec4a..775775875a4 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -287,10 +287,10 @@ register_diagnostics! { E0550, // multiple deprecated attributes E0551, // incorrect meta item E0552, // unrecognized representation hint - E0553, // unrecognized enum representation hint E0554, // #[feature] may not be used on the [] release channel E0555, // malformed feature attribute, expected #![feature(...)] E0556, // malformed feature, expected just one word E0557, // feature has been removed E0584, // file for module `..` found at both .. and .. + E0589, // align representation must be a u16 power of two } |
