diff options
| author | bors <bors@rust-lang.org> | 2014-08-21 17:30:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-08-21 17:30:57 +0000 |
| commit | f92015f71b3a49abd490e704a011d14786f6bf87 (patch) | |
| tree | 11b1e392547013ab52c249d511d3c0a3ae8180e0 /src/libsyntax | |
| parent | 4444aec1423b2f9431f30e1dc121d239c16ed71c (diff) | |
| parent | 01d2efaffe421b21f17dc7bd736d249fa1abbb0e (diff) | |
| download | rust-f92015f71b3a49abd490e704a011d14786f6bf87.tar.gz rust-f92015f71b3a49abd490e704a011d14786f6bf87.zip | |
auto merge of #16499 : cmr/rust/struct-undef-repr, r=pcwalton
r? @pcwalton
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/attr.rs | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 21252619d11..4b2a3073755 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -418,19 +418,14 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[Gc<MetaItem>]) { } -/// Fold this over attributes to parse #[repr(...)] forms. +/// Parse #[repr(...)] forms. /// /// Valid repr contents: any of the primitive integral type names (see -/// `int_type_of_word`, below) to specify the discriminant type; and `C`, to use -/// the same discriminant size that the corresponding C enum would. These are -/// not allowed on univariant or zero-variant enums, which have no discriminant. -/// -/// If a discriminant type is so specified, then the discriminant will be -/// present (before fields, if any) with that type; representation -/// optimizations which would remove it will not be done. -pub fn find_repr_attr(diagnostic: &SpanHandler, attr: &Attribute, acc: ReprAttr) - -> ReprAttr { - let mut acc = acc; +/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use +/// the same discriminant size that the corresponding C enum would or C +/// structure layout, and `packed` to remove padding. +pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAttr> { + let mut acc = Vec::new(); match attr.node.value.node { ast::MetaList(ref s, ref items) if s.equiv(&("repr")) => { mark_used(attr); @@ -439,28 +434,26 @@ pub fn find_repr_attr(diagnostic: &SpanHandler, attr: &Attribute, acc: ReprAttr) ast::MetaWord(ref word) => { let hint = match word.get() { // Can't use "extern" because it's not a lexical identifier. - "C" => ReprExtern, + "C" => Some(ReprExtern), + "packed" => Some(ReprPacked), _ => match int_type_of_word(word.get()) { - Some(ity) => ReprInt(item.span, ity), + Some(ity) => Some(ReprInt(item.span, ity)), None => { // Not a word we recognize diagnostic.span_err(item.span, "unrecognized representation hint"); - ReprAny + None } } }; - if hint != ReprAny { - if acc == ReprAny { - acc = hint; - } else if acc != hint { - diagnostic.span_warn(item.span, - "conflicting representation hint ignored") - } + + match hint { + Some(h) => acc.push(h), + None => { } } } // Not a word: - _ => diagnostic.span_err(item.span, "unrecognized representation hint") + _ => diagnostic.span_err(item.span, "unrecognized enum representation hint") } } } @@ -490,7 +483,8 @@ fn int_type_of_word(s: &str) -> Option<IntType> { pub enum ReprAttr { ReprAny, ReprInt(Span, IntType), - ReprExtern + ReprExtern, + ReprPacked, } impl ReprAttr { @@ -498,7 +492,8 @@ impl ReprAttr { match *self { ReprAny => false, ReprInt(_sp, ity) => ity.is_ffi_safe(), - ReprExtern => true + ReprExtern => true, + ReprPacked => false } } } @@ -523,7 +518,7 @@ impl IntType { SignedInt(ast::TyI16) | UnsignedInt(ast::TyU16) | SignedInt(ast::TyI32) | UnsignedInt(ast::TyU32) | SignedInt(ast::TyI64) | UnsignedInt(ast::TyU64) => true, - _ => false + SignedInt(ast::TyI) | UnsignedInt(ast::TyU) => false } } } |
