summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2014-10-29 13:23:20 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2014-10-29 13:23:20 +0000
commita094f0428b36eadd1b131aeb045abf6f4ab492db (patch)
treea71c26b632547302da8ef53bc784887e19e3f1db
parent7acc8a36c76fda537957441fa97e8e8f4ac3c23c (diff)
downloadbcm5719-llvm-a094f0428b36eadd1b131aeb045abf6f4ab492db.tar.gz
bcm5719-llvm-a094f0428b36eadd1b131aeb045abf6f4ab492db.zip
[PowerPC ABI] Bug 21398 - Consider C++ base classes in HA classification
As discussed in bug 21398, PowerPC ABI code needs to consider C++ base classes when classifying a class as homogeneous aggregate (or not) for ABI purposes. llvm-svn: 220852
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp16
-rw-r--r--clang/test/CodeGen/ppc64le-aggregates-cpp.cpp39
2 files changed, 55 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index ea62e4e409d..4fcfc79abd7 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -3208,6 +3208,22 @@ PPC64_SVR4_ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
return false;
Members = 0;
+
+ // If this is a C++ record, check the bases first.
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+ for (const auto &I : CXXRD->bases()) {
+ // Ignore empty records.
+ if (isEmptyRecord(getContext(), I.getType(), true))
+ continue;
+
+ uint64_t FldMembers;
+ if (!isHomogeneousAggregate(I.getType(), Base, FldMembers))
+ return false;
+
+ Members += FldMembers;
+ }
+ }
+
for (const auto *FD : RD->fields()) {
// Ignore (non-zero arrays of) empty records.
QualType FT = FD->getType();
diff --git a/clang/test/CodeGen/ppc64le-aggregates-cpp.cpp b/clang/test/CodeGen/ppc64le-aggregates-cpp.cpp
new file mode 100644
index 00000000000..7e7dde83f69
--- /dev/null
+++ b/clang/test/CodeGen/ppc64le-aggregates-cpp.cpp
@@ -0,0 +1,39 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// Test that C++ classes are correctly classified as homogeneous aggregates.
+
+struct Base1 {
+ int x;
+};
+struct Base2 {
+ double x;
+};
+struct Base3 {
+ double x;
+};
+struct D1 : Base1 { // non-homogeneous aggregate
+ double y, z;
+};
+struct D2 : Base2 { // homogeneous aggregate
+ double y, z;
+};
+struct D3 : Base1, Base2 { // non-homogeneous aggregate
+ double y, z;
+};
+struct D4 : Base2, Base3 { // homogeneous aggregate
+ double y, z;
+};
+
+// CHECK: define void @_Z7func_D12D1(%struct.D1* noalias sret %agg.result, [3 x i64] %x.coerce)
+D1 func_D1(D1 x) { return x; }
+
+// CHECK: define [3 x double] @_Z7func_D22D2([3 x double] %x.coerce)
+D2 func_D2(D2 x) { return x; }
+
+// CHECK: define void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, [4 x i64] %x.coerce)
+D3 func_D3(D3 x) { return x; }
+
+// CHECK: define [4 x double] @_Z7func_D42D4([4 x double] %x.coerce)
+D4 func_D4(D4 x) { return x; }
+
OpenPOWER on IntegriCloud