From: Douglas Gregor Date: Mon, 29 Mar 2010 14:42:08 +0000 (+0000) Subject: Support __attribute__((packed)) (along with other attributes) at the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0b4c9b5834a0a5520d2cd32227a53cf7f73fedca;p=clang Support __attribute__((packed)) (along with other attributes) at the end of a struct/class/union in C++, from Justin Bogner! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99811 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index b79e698d50..59cc0d218c 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1761,7 +1761,8 @@ public: virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, DeclPtrTy TagDecl, SourceLocation LBrac, - SourceLocation RBrac) { + SourceLocation RBrac, + AttributeList *AttrList) { } //===---------------------------C++ Templates----------------------------===// diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 9e232cbf32..3dc6ad9b34 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1579,10 +1579,11 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // If attributes exist after class contents, parse them. llvm::OwningPtr AttrList; if (Tok.is(tok::kw___attribute)) - AttrList.reset(ParseGNUAttributes()); // FIXME: where should I put them? + AttrList.reset(ParseGNUAttributes()); Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl, - LBraceLoc, RBraceLoc); + LBraceLoc, RBraceLoc, + AttrList.get()); // C++ 9.2p2: Within the class member-specification, the class is regarded as // complete within function bodies, default arguments, diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index d0a4f7cbf6..9c661ba1b1 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2502,7 +2502,8 @@ public: virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, DeclPtrTy TagDecl, SourceLocation LBrac, - SourceLocation RBrac); + SourceLocation RBrac, + AttributeList *AttrList); virtual void ActOnReenterTemplateScope(Scope *S, DeclPtrTy Template); virtual void ActOnStartDelayedMemberDeclarations(Scope *S, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index b5dc730522..ee16b9c4b1 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2174,7 +2174,8 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, DeclPtrTy TagDecl, SourceLocation LBrac, - SourceLocation RBrac) { + SourceLocation RBrac, + AttributeList *AttrList) { if (!TagDecl) return; @@ -2182,7 +2183,7 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, ActOnFields(S, RLoc, TagDecl, (DeclPtrTy*)FieldCollector->getCurFields(), - FieldCollector->getCurNumFields(), LBrac, RBrac, 0); + FieldCollector->getCurNumFields(), LBrac, RBrac, AttrList); CheckCompletedCXXClass( dyn_cast_or_null(TagDecl.getAs())); diff --git a/test/Sema/struct-packed-align.c b/test/Sema/struct-packed-align.c index 60a9febafb..2b9456703c 100644 --- a/test/Sema/struct-packed-align.c +++ b/test/Sema/struct-packed-align.c @@ -37,6 +37,14 @@ struct __attribute__((packed)) packed_fas { extern int d1[sizeof(struct packed_fas) == 1 ? 1 : -1]; extern int d2[__alignof(struct packed_fas) == 1 ? 1 : -1]; +struct packed_after_fas { + char a; + int b[]; +} __attribute__((packed)); + +extern int d1_2[sizeof(struct packed_after_fas) == 1 ? 1 : -1]; +extern int d2_2[__alignof(struct packed_after_fas) == 1 ? 1 : -1]; + // Alignment struct __attribute__((aligned(8))) as1 { diff --git a/test/SemaCXX/class-layout.cpp b/test/SemaCXX/class-layout.cpp index 2b8d1d3210..f3c75f4b27 100644 --- a/test/SemaCXX/class-layout.cpp +++ b/test/SemaCXX/class-layout.cpp @@ -48,6 +48,13 @@ struct H : G { }; SA(6, sizeof(H) == 1); +struct I { + char b; + int a; +} __attribute__((packed)); + +SA(6_1, sizeof(I) == 5); + // PR5580 namespace PR5580 {