summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2008-09-02 05:19:23 +0000
committerEli Friedman <eli.friedman@gmail.com>2008-09-02 05:19:23 +0000
commit7c9ba6a1e356e29c4adee2c4a0442659ee14692a (patch)
tree109974f8077b2a2a06d8fa9134ef11724f7ec8d7
parente7175d83dcb3ec0837036a92200f565dad63b784 (diff)
downloadbcm5719-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.def3
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp29
-rw-r--r--clang/test/Sema/transparent-union-pointer.c14
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);
+}
+
OpenPOWER on IntegriCloud