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:
Eli Friedman 2008-09-02 05:19:23 +00:00
parent e7175d83dc
commit 7c9ba6a1e3
3 changed files with 39 additions and 7 deletions

View File

@ -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,

View File

@ -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) {

View File

@ -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);
}