forked from OSchip/llvm-project
Allow attributes before union definition
permits typedef union __attribute__((transparent_union)) {...} Differential Revision: https://reviews.llvm.org/D28266 llvm-svn: 296518
This commit is contained in:
parent
318971880e
commit
2fe684bb14
|
@ -3122,6 +3122,8 @@ public:
|
|||
void ProcessPragmaWeak(Scope *S, Decl *D);
|
||||
// Decl attributes - this routine is the top level dispatcher.
|
||||
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
|
||||
// Helper for delayed proccessing of attributes.
|
||||
void ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList);
|
||||
void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
|
||||
bool IncludeCXX11Attributes = true);
|
||||
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
|
||||
|
|
|
@ -1887,6 +1887,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
|
||||
}
|
||||
|
||||
if (!TagOrTempResult.isInvalid())
|
||||
// Delayed proccessing of attributes.
|
||||
Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs.getList());
|
||||
|
||||
const char *PrevSpec = nullptr;
|
||||
unsigned DiagID;
|
||||
bool Result;
|
||||
|
|
|
@ -13637,9 +13637,6 @@ CreateNewDecl:
|
|||
if (Invalid)
|
||||
New->setInvalidDecl();
|
||||
|
||||
if (Attr)
|
||||
ProcessDeclAttributeList(S, New, Attr);
|
||||
|
||||
// Set the lexical context. If the tag has a C++ scope specifier, the
|
||||
// lexical context will be different from the semantic context.
|
||||
New->setLexicalDeclContext(CurContext);
|
||||
|
@ -13658,6 +13655,9 @@ CreateNewDecl:
|
|||
if (TUK == TUK_Definition)
|
||||
New->startDefinition();
|
||||
|
||||
if (Attr)
|
||||
ProcessDeclAttributeList(S, New, Attr);
|
||||
|
||||
// If this has an identifier, add it to the scope stack.
|
||||
if (TUK == TUK_Friend) {
|
||||
// We might be replacing an existing declaration in the lookup tables;
|
||||
|
|
|
@ -3193,8 +3193,9 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D,
|
|||
}
|
||||
|
||||
if (!RD->isCompleteDefinition()) {
|
||||
S.Diag(Attr.getLoc(),
|
||||
diag::warn_transparent_union_attribute_not_definition);
|
||||
if (!RD->isBeingDefined())
|
||||
S.Diag(Attr.getLoc(),
|
||||
diag::warn_transparent_union_attribute_not_definition);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6314,6 +6315,15 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
|
|||
}
|
||||
}
|
||||
|
||||
// Helper for delayed proccessing TransparentUnion attribute.
|
||||
void Sema::ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList) {
|
||||
for (const AttributeList *Attr = AttrList; Attr; Attr = Attr->getNext())
|
||||
if (Attr->getKind() == AttributeList::AT_TransparentUnion) {
|
||||
handleTransparentUnionAttr(*this, D, *Attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Annotation attributes are the only attributes allowed after an access
|
||||
// specifier.
|
||||
bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
|
||||
|
|
|
@ -3,10 +3,21 @@
|
|||
// RUN: %clang_cc1 -Werror -triple armv7-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM
|
||||
// RUN: %clang_cc1 -Werror -triple powerpc64le-linux -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -Werror -triple aarch64-linux -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -DINFRONT -Werror -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -DINFRONT -Werror -triple i386-linux -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -DINFRONT -Werror -triple armv7-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM
|
||||
// RUN: %clang_cc1 -DINFRONT -Werror -triple powerpc64le-linux -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -DINFRONT -Werror -triple aarch64-linux -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
#ifdef INFRONT
|
||||
typedef union __attribute__((transparent_union)) {
|
||||
void *f0;
|
||||
} transp_t0;
|
||||
#else
|
||||
typedef union {
|
||||
void *f0;
|
||||
} transp_t0 __attribute__((transparent_union));
|
||||
#endif
|
||||
|
||||
void f0(transp_t0 obj);
|
||||
|
||||
|
|
|
@ -54,11 +54,21 @@ typedef union {
|
|||
aligned_struct8 s8; // expected-warning{{alignment of field}}
|
||||
} TU1 __attribute__((transparent_union));
|
||||
|
||||
typedef union __attribute__((transparent_union)) {
|
||||
aligned_struct4 s4; // expected-note{{alignment of first field}}
|
||||
aligned_struct8 s8; // expected-warning{{alignment of field}}
|
||||
} TU1b ;
|
||||
|
||||
typedef union {
|
||||
char c; // expected-note{{size of first field is 8 bits}}
|
||||
int i; // expected-warning{{size of field}}
|
||||
} TU2 __attribute__((transparent_union));
|
||||
|
||||
typedef union __attribute__((transparent_union)){
|
||||
char c; // expected-note{{size of first field is 8 bits}}
|
||||
int i; // expected-warning{{size of field}}
|
||||
} TU2b;
|
||||
|
||||
typedef union {
|
||||
float f; // expected-warning{{floating}}
|
||||
} TU3 __attribute__((transparent_union));
|
||||
|
@ -98,3 +108,17 @@ union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-erro
|
|||
union pr30520s { struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
|
||||
|
||||
union pr30520s2 { int *v; struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
|
||||
|
||||
typedef union __attribute__((__transparent_union__)) {
|
||||
int *i;
|
||||
struct st *s;
|
||||
} TU6;
|
||||
|
||||
void bar(TU6);
|
||||
|
||||
void foo11(int *i) {
|
||||
bar(i);
|
||||
}
|
||||
void foo2(struct st *s) {
|
||||
bar(s);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue