blob: 39e9765c528205ee63bc294fe65ae4e03cbabbc8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
Pull in r199037 from upstream clang trunk (by Jakob Stokund Olesen):
SPARC passes non-trivial C++ objects indirectly like everybody else.
Introduced here: http://svnweb.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);
+}
|