blob: 92ceb08e90e4e60519794e903cbdc02394bf7a98 [file] [log] [blame]
Tim Northover9bb857a2013-01-31 12:13:10 +00001// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s
Bradley Smith4da7dd82014-04-30 10:52:05 +00002// RUN: %clang_cc1 -triple arm64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s
Tim Northover9bb857a2013-01-31 12:13:10 +00003
4// Check differences between the generic Itanium ABI, the AArch32 version and
5// the AArch64 version.
6
7////////////////////////////////////////////////////////////////////////////////
8
9// The ABI says that the key function is the "textually first, non-inline,
10// non-pure, virtual member function". The generic version decides this after
11// the completion of the class definition; the AArch32 version decides this at
12// the end of the translation unit.
13
14// We construct a class which needs a VTable here under generic ABI, but not
15// AArch32.
16
17// (see next section for explanation of guard)
18// CHECK: @_ZGVZ15guard_variablesiE4mine = internal global i64 0
19
20// CHECK: @_ZTV16CheckKeyFunction =
21struct CheckKeyFunction {
22 virtual void foo();
23};
24
25// This is not inline when CheckKeyFunction is completed, so
26// CheckKeyFunction::foo is the key function. VTables should be emitted.
27inline void CheckKeyFunction::foo() {
28}
29
30////////////////////////////////////////////////////////////////////////////////
31
32// Guard variables only specify and use the low bit to determine status, rather
33// than the low byte as in the generic Itanium ABI. However, unlike 32-bit ARM,
34// they *are* 64-bits wide so check that in case confusion has occurred.
35
36class Guarded {
37public:
38 Guarded(int i);
39 ~Guarded();
40};
41
42void guard_variables(int a) {
43 static Guarded mine(a);
Justin Bogner0cbb6d82014-04-23 01:50:10 +000044// CHECK: [[GUARDBIT:%[0-9]+]] = and i8 {{%[0-9]+}}, 1
45// CHECK: icmp eq i8 [[GUARDBIT]], 0
Tim Northover9bb857a2013-01-31 12:13:10 +000046
47 // As guards are 64-bit, these helpers should take 64-bit pointers.
48// CHECK: call i32 @__cxa_guard_acquire(i64*
49// CHECK: call void @__cxa_guard_release(i64*
50}
51
52////////////////////////////////////////////////////////////////////////////////
53
54// Member function pointers use the adj field to distinguish between virtual and
55// nonvirtual members. As a result the adjustment is shifted (if ptr was used, a
56// mask would be expected instead).
57
58class C {
59 int a();
60 virtual int b();
61};
62
63
64int member_pointer(C &c, int (C::*func)()) {
65// CHECK: ashr i64 %[[MEMPTRADJ:[0-9a-z.]+]], 1
66// CHECK: %[[ISVIRTUAL:[0-9]+]] = and i64 %[[MEMPTRADJ]], 1
67// CHECK: icmp ne i64 %[[ISVIRTUAL]], 0
68 return (c.*func)();
69}
70
71////////////////////////////////////////////////////////////////////////////////
72
73// AArch64 PCS says that va_list type is based on "struct __va_list ..." in the
74// std namespace, which means it should mangle as "St9__va_list".
75
76// CHECK: @_Z7va_funcSt9__va_list
77void va_func(__builtin_va_list l) {
78}
79
80////////////////////////////////////////////////////////////////////////////////
81
82// AArch64 constructors (like generic Itanium, but unlike AArch32) do not return
83// "this".
84
85void test_constructor() {
86 Guarded g(42);
87// CHECK: call void @_ZN7GuardedC1Ei
88}
89
90////////////////////////////////////////////////////////////////////////////////
91
92// In principle the AArch32 ABI allows this to be accomplished via a call to
93// __aeabi_atexit instead of __cxa_atexit. Clang doesn't make use of this at the
94// moment, but it's definitely not allowed for AArch64.
95
96// CHECK: call i32 @__cxa_atexit
97Guarded g(42);