diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2008-09-02 05:19:23 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2008-09-02 05:19:23 +0000 |
commit | 7c9ba6a1e356e29c4adee2c4a0442659ee14692a (patch) | |
tree | 109974f8077b2a2a06d8fa9134ef11724f7ec8d7 | |
parent | e7175d83dcb3ec0837036a92200f565dad63b784 (diff) | |
download | bcm5719-llvm-7c9ba6a1e356e29c4adee2c4a0442659ee14692a.tar.gz bcm5719-llvm-7c9ba6a1e356e29c4adee2c4a0442659ee14692a.zip |
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
-rw-r--r-- | clang/include/clang/Basic/DiagnosticKinds.def | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 29 | ||||
-rw-r--r-- | clang/test/Sema/transparent-union-pointer.c | 14 |
3 files changed, 39 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 95d21126500..9c90306177c 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -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, diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index eb9888e9a28..b5737d8b3c6 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -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: 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 -// Ty->addAttr(new TransparentUnionAttr()); + // 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) { diff --git a/clang/test/Sema/transparent-union-pointer.c b/clang/test/Sema/transparent-union-pointer.c new file mode 100644 index 00000000000..58597b18096 --- /dev/null +++ b/clang/test/Sema/transparent-union-pointer.c @@ -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); +} + |