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")
|
"'%0' attribute invalid on this declaration, requires typedef or value")
|
||||||
DIAG(warn_attribute_nonnull_no_pointers, WARNING,
|
DIAG(warn_attribute_nonnull_no_pointers, WARNING,
|
||||||
"'nonnull' attribute applied to function with no pointer arguments")
|
"'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
|
// Clang-Specific Attributes
|
||||||
DIAG(err_attribute_iboutlet_non_ivar, ERROR,
|
DIAG(err_attribute_iboutlet_non_ivar, ERROR,
|
||||||
|
|
|
@ -725,19 +725,34 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDecl *decl = dyn_cast<TypeDecl>(d);
|
// FIXME: This shouldn't be restricted to typedefs
|
||||||
|
TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
|
||||||
if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) {
|
if (!TD || !TD->getUnderlyingType()->isUnionType()) {
|
||||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
|
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
|
||||||
"transparent_union", "union");
|
"transparent_union", "union");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//QualType QTy = Context.getTypeDeclType(decl);
|
RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
|
||||||
//const RecordType *Ty = QTy->getAsUnionType();
|
|
||||||
|
|
||||||
// FIXME
|
// FIXME: Should we do a check for RD->isDefinition()?
|
||||||
// Ty->addAttr(new TransparentUnionAttr());
|
|
||||||
|
// 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) {
|
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