forked from OSchip/llvm-project
An extremely hacky version of transparent_union support; it isn't
anywhere near correct in terms of missing cases and missing diagnostics, but it's good enough to handle the uses in the Linux system headers, which are currently a constant pain for compiling applications on Linux. llvm-svn: 55621
This commit is contained in:
parent
e7175d83dc
commit
7c9ba6a1e3
|
@ -694,6 +694,9 @@ DIAG(err_attr_wrong_decl, ERROR,
|
|||
"'%0' attribute invalid on this declaration, requires typedef or value")
|
||||
DIAG(warn_attribute_nonnull_no_pointers, WARNING,
|
||||
"'nonnull' attribute applied to function with no pointer arguments")
|
||||
DIAG(warn_transparent_union_nonpointer, WARNING,
|
||||
"'transparent_union' attribute support incomplete; only supported for"
|
||||
"pointer unions")
|
||||
|
||||
// Clang-Specific Attributes
|
||||
DIAG(err_attribute_iboutlet_non_ivar, ERROR,
|
||||
|
|
|
@ -725,19 +725,34 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
|
|||
return;
|
||||
}
|
||||
|
||||
TypeDecl *decl = dyn_cast<TypeDecl>(d);
|
||||
|
||||
if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) {
|
||||
// FIXME: This shouldn't be restricted to typedefs
|
||||
TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
|
||||
if (!TD || !TD->getUnderlyingType()->isUnionType()) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
|
||||
"transparent_union", "union");
|
||||
return;
|
||||
}
|
||||
|
||||
//QualType QTy = Context.getTypeDeclType(decl);
|
||||
//const RecordType *Ty = QTy->getAsUnionType();
|
||||
RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
|
||||
|
||||
// FIXME
|
||||
// Ty->addAttr(new TransparentUnionAttr());
|
||||
// FIXME: Should we do a check for RD->isDefinition()?
|
||||
|
||||
// FIXME: This isn't supposed to be restricted to pointers, but otherwise
|
||||
// we might silently generate incorrect code; see following code
|
||||
for (int i = 0; i < RD->getNumMembers(); i++) {
|
||||
if (!RD->getMember(i)->getType()->isPointerType()) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This is a complete hack; we should be properly propagating
|
||||
// transparent_union through Sema. That said, this is close enough to
|
||||
// correctly compile all the common cases of transparent_union without
|
||||
// errors or warnings
|
||||
QualType NewTy = S.Context.VoidPtrTy;
|
||||
NewTy.addConst();
|
||||
TD->setUnderlyingType(NewTy);
|
||||
}
|
||||
|
||||
static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// RUN: clang %s -fsyntax-only -verify
|
||||
|
||||
typedef union {
|
||||
union wait *__uptr;
|
||||
int *__iptr;
|
||||
} __WAIT_STATUS __attribute__ ((__transparent_union__));
|
||||
|
||||
extern int wait (__WAIT_STATUS __stat_loc);
|
||||
|
||||
void fastcgi_cleanup() {
|
||||
int status = 0;
|
||||
wait(&status);
|
||||
}
|
||||
|
Loading…
Reference in New Issue