54 lines
1.7 KiB
Diff
54 lines
1.7 KiB
Diff
|
Pull in r199037 from upstream clang trunk (by Jakob Stokund Olesen):
|
||
|
|
||
|
SPARC passes non-trivial C++ objects indirectly like everybody else.
|
||
|
|
||
|
Introduced here: http://svn.freebsd.org/changeset/base/262262
|
||
|
|
||
|
Index: tools/clang/lib/CodeGen/TargetInfo.cpp
|
||
|
===================================================================
|
||
|
--- tools/clang/lib/CodeGen/TargetInfo.cpp
|
||
|
+++ tools/clang/lib/CodeGen/TargetInfo.cpp
|
||
|
@@ -5349,6 +5349,11 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned
|
||
|
if (!isAggregateTypeForABI(Ty))
|
||
|
return ABIArgInfo::getDirect();
|
||
|
|
||
|
+ // If a C++ object has either a non-trivial copy constructor or a non-trivial
|
||
|
+ // destructor, it is passed with an explicit indirect pointer / sret pointer.
|
||
|
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
|
||
|
+ return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
|
||
|
+
|
||
|
// This is a small aggregate type that should be passed in registers.
|
||
|
// Build a coercion type from the LLVM struct type.
|
||
|
llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
|
||
|
Index: tools/clang/test/CodeGenCXX/sparcv9-abi.cpp
|
||
|
===================================================================
|
||
|
--- tools/clang/test/CodeGenCXX/sparcv9-abi.cpp
|
||
|
+++ tools/clang/test/CodeGenCXX/sparcv9-abi.cpp
|
||
|
@@ -0,0 +1,26 @@
|
||
|
+// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
|
||
|
+
|
||
|
+struct pod {
|
||
|
+ int a, b;
|
||
|
+};
|
||
|
+
|
||
|
+void f0();
|
||
|
+void f1(struct pod);
|
||
|
+
|
||
|
+struct notpod {
|
||
|
+ int a, b;
|
||
|
+ ~notpod() { f0(); }
|
||
|
+};
|
||
|
+
|
||
|
+void f2(struct notpod);
|
||
|
+
|
||
|
+// CHECK-LABEL: caller
|
||
|
+// CHECK: call void @_Z2f13pod(i64
|
||
|
+// CHECK: call void @_Z2f26notpod(%struct.notpod*
|
||
|
+void caller()
|
||
|
+{
|
||
|
+ pod p1;
|
||
|
+ notpod p2;
|
||
|
+ f1(p1);
|
||
|
+ f2(p2);
|
||
|
+}
|