summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/PR5050-constructor-conversion.cpp2
-rw-r--r--test/CodeGenCXX/PR5863-unreachable-block.cpp2
-rw-r--r--test/CodeGenCXX/anonymous-namespaces.cpp2
-rw-r--r--test/CodeGenCXX/anonymous-union-member-initializer.cpp35
-rw-r--r--test/CodeGenCXX/apple-kext-indirect-call-2.C77
-rw-r--r--test/CodeGenCXX/apple-kext-indirect-call.C14
-rw-r--r--test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp19
-rw-r--r--test/CodeGenCXX/apple-kext-linkage.C25
-rw-r--r--test/CodeGenCXX/apple-kext-no-staticinit-section.C20
-rw-r--r--test/CodeGenCXX/arm.cpp79
-rw-r--r--test/CodeGenCXX/array-construction.cpp2
-rw-r--r--test/CodeGenCXX/array-operator-delete-call.cpp2
-rw-r--r--test/CodeGenCXX/array-value-initialize.cpp2
-rw-r--r--test/CodeGenCXX/asm.cpp14
-rw-r--r--test/CodeGenCXX/attr-used.cpp9
-rw-r--r--test/CodeGenCXX/attr.cpp2
-rw-r--r--test/CodeGenCXX/block-byref-cxx-objc.cpp25
-rw-r--r--test/CodeGenCXX/blocks.cpp57
-rw-r--r--test/CodeGenCXX/builtins.cpp9
-rw-r--r--test/CodeGenCXX/c99-variable-length-array.cpp2
-rw-r--r--test/CodeGenCXX/call-arg-zero-temp.cpp2
-rw-r--r--test/CodeGenCXX/cast-conversion.cpp12
-rw-r--r--test/CodeGenCXX/class-layout.cpp24
-rw-r--r--test/CodeGenCXX/const-init.cpp12
-rw-r--r--test/CodeGenCXX/constructor-attr.cpp12
-rw-r--r--test/CodeGenCXX/constructor-conversion.cpp6
-rw-r--r--test/CodeGenCXX/constructor-convert.cpp2
-rw-r--r--test/CodeGenCXX/constructor-default-arg.cpp6
-rw-r--r--test/CodeGenCXX/constructor-direct-call.cpp60
-rw-r--r--test/CodeGenCXX/constructor-for-array-members.cpp2
-rw-r--r--test/CodeGenCXX/constructor-init.cpp34
-rw-r--r--test/CodeGenCXX/constructors.cpp20
-rw-r--r--test/CodeGenCXX/convert-to-fptr.cpp4
-rw-r--r--test/CodeGenCXX/copy-constructor-elim-2.cpp24
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis-2.cpp2
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis.cpp4
-rw-r--r--test/CodeGenCXX/cxx-block-objects.cpp33
-rw-r--r--test/CodeGenCXX/debug-info-ctor2.cpp15
-rw-r--r--test/CodeGenCXX/debug-info-large-constant.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-member.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-method.cpp6
-rw-r--r--test/CodeGenCXX/debug-info-namespace.cpp12
-rw-r--r--test/CodeGenCXX/debug-info-template.cpp15
-rw-r--r--test/CodeGenCXX/decl-ref-init.cpp4
-rw-r--r--test/CodeGenCXX/default-arg-temps.cpp2
-rw-r--r--test/CodeGenCXX/default-arguments.cpp4
-rw-r--r--test/CodeGenCXX/default-constructor-for-members.cpp2
-rw-r--r--test/CodeGenCXX/default-constructor-template-member.cpp2
-rw-r--r--test/CodeGenCXX/delete-two-arg.cpp70
-rw-r--r--test/CodeGenCXX/delete.cpp9
-rw-r--r--test/CodeGenCXX/derived-to-base-conv.cpp4
-rw-r--r--test/CodeGenCXX/derived-to-base.cpp11
-rw-r--r--test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp16
-rw-r--r--test/CodeGenCXX/destructors.cpp54
-rw-r--r--test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp51
-rw-r--r--test/CodeGenCXX/dyncast.cpp1
-rw-r--r--test/CodeGenCXX/eh.cpp88
-rw-r--r--test/CodeGenCXX/empty-classes.cpp13
-rw-r--r--test/CodeGenCXX/exceptions-no-rtti.cpp10
-rw-r--r--test/CodeGenCXX/exceptions.cpp303
-rw-r--r--test/CodeGenCXX/friend-redecl.cpp18
-rw-r--r--test/CodeGenCXX/global-init.cpp17
-rw-r--r--test/CodeGenCXX/gnu-conditional-scalar-ext.cpp62
-rw-r--r--test/CodeGenCXX/goto.cpp43
-rw-r--r--test/CodeGenCXX/implicit-copy-constructor.cpp2
-rw-r--r--test/CodeGenCXX/inline-functions.cpp32
-rw-r--r--test/CodeGenCXX/internal-linkage.cpp4
-rw-r--r--test/CodeGenCXX/key-function-vtable.cpp13
-rw-r--r--test/CodeGenCXX/mangle-abi-examples.cpp27
-rw-r--r--test/CodeGenCXX/mangle-local-class-vtables.cpp61
-rw-r--r--test/CodeGenCXX/mangle-local-classes-nested.cpp81
-rw-r--r--test/CodeGenCXX/mangle-ms.cpp8
-rw-r--r--test/CodeGenCXX/mangle-neon-vectors.cpp32
-rw-r--r--test/CodeGenCXX/mangle-ref-qualifiers.cpp16
-rw-r--r--test/CodeGenCXX/mangle-subst-std.cpp16
-rw-r--r--test/CodeGenCXX/mangle-template.cpp2
-rw-r--r--test/CodeGenCXX/mangle-unnamed.cpp21
-rw-r--r--test/CodeGenCXX/mangle-variadic-templates.cpp67
-rw-r--r--test/CodeGenCXX/mangle.cpp23
-rw-r--r--test/CodeGenCXX/member-functions.cpp4
-rw-r--r--test/CodeGenCXX/member-init-assignment.cpp2
-rw-r--r--test/CodeGenCXX/member-pointer-type-convert.cpp1
-rw-r--r--test/CodeGenCXX/member-templates.cpp4
-rw-r--r--test/CodeGenCXX/nrvo-noreturn.cc17
-rw-r--r--test/CodeGenCXX/nrvo.cpp15
-rw-r--r--test/CodeGenCXX/nullptr.cpp9
-rw-r--r--test/CodeGenCXX/pointers-to-data-members.cpp59
-rw-r--r--test/CodeGenCXX/pr9130.cpp14
-rw-r--r--test/CodeGenCXX/pragma-pack.cpp14
-rw-r--r--test/CodeGenCXX/pragma-visibility.cpp4
-rw-r--r--test/CodeGenCXX/predefined-expr.cpp106
-rw-r--r--test/CodeGenCXX/ptr-to-member-function.cpp4
-rw-r--r--test/CodeGenCXX/rtti-fundamental.cpp157
-rw-r--r--test/CodeGenCXX/rtti-linkage.cpp102
-rw-r--r--test/CodeGenCXX/rtti-visibility.cpp35
-rw-r--r--test/CodeGenCXX/rvalue-references.cpp85
-rw-r--r--test/CodeGenCXX/specialized-static-data-mem-init.cpp29
-rw-r--r--test/CodeGenCXX/static-data-member.cpp70
-rw-r--r--test/CodeGenCXX/static-init.cpp2
-rw-r--r--test/CodeGenCXX/stmtexpr.cpp75
-rw-r--r--test/CodeGenCXX/template-anonymous-types.cpp4
-rw-r--r--test/CodeGenCXX/template-dependent-bind-temporary.cpp24
-rw-r--r--test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp24
-rw-r--r--test/CodeGenCXX/template-instantiation.cpp51
-rw-r--r--test/CodeGenCXX/template-linkage.cpp2
-rw-r--r--test/CodeGenCXX/temporaries.cpp185
-rw-r--r--test/CodeGenCXX/threadsafe-statics-exceptions.cpp4
-rw-r--r--test/CodeGenCXX/throw-expressions.cpp7
-rw-r--r--test/CodeGenCXX/thunks-available-externally.cpp88
-rw-r--r--test/CodeGenCXX/thunks.cpp63
-rw-r--r--test/CodeGenCXX/value-init.cpp15
-rw-r--r--test/CodeGenCXX/variadic-templates.cpp12
-rw-r--r--test/CodeGenCXX/virt-dtor-gen.cpp2
-rw-r--r--test/CodeGenCXX/virt-dtor-key.cpp2
-rw-r--r--test/CodeGenCXX/virt-template-vtable.cpp8
-rw-r--r--test/CodeGenCXX/virtual-base-destructor-call.cpp12
-rw-r--r--test/CodeGenCXX/virtual-bases.cpp12
-rw-r--r--test/CodeGenCXX/virtual-destructor-calls.cpp6
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden.cpp46
-rw-r--r--test/CodeGenCXX/visibility.cpp331
-rw-r--r--test/CodeGenCXX/volatile-1.cpp352
-rw-r--r--test/CodeGenCXX/volatile.cpp2
-rw-r--r--test/CodeGenCXX/vtable-available-externally.cpp171
-rw-r--r--test/CodeGenCXX/vtable-debug-info.cpp318
-rw-r--r--test/CodeGenCXX/vtable-key-function.cpp2
-rw-r--r--test/CodeGenCXX/vtable-layout.cpp2
-rw-r--r--test/CodeGenCXX/vtable-linkage.cpp95
-rw-r--r--test/CodeGenCXX/vtable-pointer-initialization.cpp10
-rw-r--r--test/CodeGenCXX/vtt-layout.cpp8
-rw-r--r--test/CodeGenCXX/warn-padded-packed.cpp76
130 files changed, 4187 insertions, 464 deletions
diff --git a/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
index 9103b83..aa75ea4 100644
--- a/test/CodeGenCXX/PR5050-constructor-conversion.cpp
+++ b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
@@ -13,6 +13,6 @@ A f(const B &b) {
// CHECK-LP64: callq __ZN1AC1ERKS_i
-// CHECK-LP32: call L__ZN1AC1ERKS_i
+// CHECK-LP32: calll L__ZN1AC1ERKS_i
diff --git a/test/CodeGenCXX/PR5863-unreachable-block.cpp b/test/CodeGenCXX/PR5863-unreachable-block.cpp
index 7709615..4829b52 100644
--- a/test/CodeGenCXX/PR5863-unreachable-block.cpp
+++ b/test/CodeGenCXX/PR5863-unreachable-block.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only %s
+// RUN: %clang_cc1 -fexceptions -emit-llvm-only %s
// PR5863
class E { };
diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp
index 3ec7032..0198ed0 100644
--- a/test/CodeGenCXX/anonymous-namespaces.cpp
+++ b/test/CodeGenCXX/anonymous-namespaces.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - > %t
+// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin10 -emit-llvm %s -o - > %t
// RUN: FileCheck %s -check-prefix=1 < %t
// RUN: FileCheck %s -check-prefix=2 < %t
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index 9ba3805..d97a2ae 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -1,4 +1,18 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+// rdar://8818236
+namespace rdar8818236 {
+struct S {
+ char c2;
+ union {
+ char c;
+ int i;
+ };
+};
+
+// CHECK: @_ZN11rdar88182363fooE = global i64 4
+char S::*foo = &S::c;
+}
struct A {
union {
@@ -67,7 +81,7 @@ namespace test3 {
};
A::A() : callback(0), callback_value(0) {}
- // CHECK: define void @ZN5test31AC2Ev(
+ // CHECK: define void @_ZN5test31AC2Ev(
// CHECK: [[THIS:%.*]] = load
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = getelementptr inbounds {{.*}} [[UNION]], i32 0, i32 0
@@ -75,8 +89,8 @@ namespace test3 {
// CHECK-NEXT: store void (i8*)* null, void (i8*)** [[CALLBACK]]
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = getelementptr inbounds {{.*}} [[UNION]], i32 0, i32 0
- // CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
- // CHECK-NEXT: store i8* null, void i8** [[CVALUE]]
+ // CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1
+ // CHECK-NEXT: store i8* null, i8** [[CVALUE]]
}
struct S {
@@ -90,3 +104,16 @@ struct S {
};
};
} s;
+
+
+ //PR8760
+ template <typename T>
+ struct Foo {
+ Foo() : ptr(__nullptr) {}
+ union {
+ T *ptr;
+ };
+ };
+ Foo<int> f;
+
+
diff --git a/test/CodeGenCXX/apple-kext-indirect-call-2.C b/test/CodeGenCXX/apple-kext-indirect-call-2.C
new file mode 100644
index 0000000..7e25200
--- /dev/null
+++ b/test/CodeGenCXX/apple-kext-indirect-call-2.C
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @_ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null]
+// CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK4Base3abcEv to i8*), i8* null]
+// CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK8Derived23efgEv to i8*), i8* null]
+// CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK2D23abcEv to i8*), i8* null]
+
+struct A {
+ virtual const char* abc(void) const;
+};
+
+const char* A::abc(void) const {return "A"; };
+
+struct B : virtual A {
+ virtual void VF();
+};
+
+void B::VF() {}
+
+void FUNC(B* p) {
+// CHECK: [[T1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2)
+// CHECK-NEXT: [[T2:%.*]] = call i8* [[T1]]
+ const char* c = p->A::abc();
+}
+
+
+// Test2
+struct Base { virtual char* abc(void) const; };
+
+char* Base::abc() const { return 0; }
+
+struct Derived : public Base {
+};
+
+void FUNC1(Derived* p) {
+// CHECK: [[U1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.A*)**), i64 2)
+// CHECK-NEXT: [[U2:%.*]] = call i8* [[U1]]
+ char* c = p->Base::abc();
+}
+
+
+// Test3
+struct Base2 { };
+
+struct Derived2 : virtual Base2 {
+ virtual char* efg(void) const;
+};
+
+char* Derived2::efg(void) const { return 0; }
+
+void FUNC2(Derived2* p) {
+// CHECK: [[V1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.A*)**), i64 3)
+// CHECK-NEXT: [[V2:%.*]] = call i8* [[V1]]
+ char* c = p->Derived2::efg();
+}
+
+// Test4
+struct Base3 { };
+
+struct D1 : virtual Base3 {
+};
+
+struct D2 : virtual Base3 {
+ virtual char *abc(void) const;
+};
+
+struct Sub : D1, D2 {
+};
+
+char* D2::abc(void) const { return 0; }
+
+void FUNC3(Sub* p) {
+// CHECK: [[W1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.A*)**), i64 3)
+// CHECK-NEXT: [[W2:%.*]] = call i8* [[W1]]
+ char* c = p->D2::abc();
+}
+
diff --git a/test/CodeGenCXX/apple-kext-indirect-call.C b/test/CodeGenCXX/apple-kext-indirect-call.C
new file mode 100644
index 0000000..2dbb0b8
--- /dev/null
+++ b/test/CodeGenCXX/apple-kext-indirect-call.C
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s
+
+struct Base {
+ virtual void abc(void) const;
+};
+
+void Base::abc(void) const {}
+
+void FUNC(Base* p) {
+ p->Base::abc();
+}
+
+// CHECK: getelementptr inbounds (void (%struct.Base*)** bitcast ([3 x i8*]* @_ZTV4Base to void (%struct.Base*)**), i64 2)
+// CHECK-NOT: call void @_ZNK4Base3abcEv
diff --git a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
new file mode 100644
index 0000000..bd275f1
--- /dev/null
+++ b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: define void @_ZN2B1D0Ev
+// CHECK: [[T1:%.*]] = load void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
+// CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]])
+// CHECK: define void @_Z6DELETEP2B1
+// CHECK: [[T3:%.*]] = load void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2)
+// CHECK-NEXT: call void [[T3]](%struct.B1* [[T4:%.*]])
+
+
+struct B1 {
+ virtual ~B1();
+};
+
+B1::~B1() {}
+
+void DELETE(B1 *pb1) {
+ pb1->B1::~B1();
+}
diff --git a/test/CodeGenCXX/apple-kext-linkage.C b/test/CodeGenCXX/apple-kext-linkage.C
new file mode 100644
index 0000000..9df1151
--- /dev/null
+++ b/test/CodeGenCXX/apple-kext-linkage.C
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s
+
+struct Base {
+ virtual ~Base();
+} ;
+
+struct Derived : Base {
+ void operator delete(void *) { }
+ Derived();
+};
+
+void foo() {
+ Derived d1; // ok
+}
+
+inline unsigned f(unsigned n) { return n == 0 ? 0 : n + f(n-1); }
+
+unsigned g(unsigned n) { return f(n); }
+
+
+template <typename X> X ident(X x) { return x; }
+int foo(int n) { return ident(n); }
+
+// CHECK-NOT: define linkonce_odr
+// CHECK 5 : define internal
diff --git a/test/CodeGenCXX/apple-kext-no-staticinit-section.C b/test/CodeGenCXX/apple-kext-no-staticinit-section.C
new file mode 100644
index 0000000..0401d49
--- /dev/null
+++ b/test/CodeGenCXX/apple-kext-no-staticinit-section.C
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
+// rdar://8825235
+/**
+1) Normally, global object construction code ends up in __StaticInit segment of text section
+ .section __TEXT,__StaticInit,regular,pure_instructions
+ In kext mode, they end up in the __text segment.
+*/
+
+class foo {
+public:
+ foo();
+ virtual ~foo();
+};
+
+foo a;
+foo b;
+foo c;
+foo::~foo() {}
+
+// CHECK-NOT: __TEXT,__StaticInit,regular,pure_instructions
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
index 44c0aff..672ca01 100644
--- a/test/CodeGenCXX/arm.cpp
+++ b/test/CodeGenCXX/arm.cpp
@@ -1,5 +1,10 @@
// RUN: %clang_cc1 %s -triple=thumbv7-apple-darwin3.0.0-iphoneos -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - -fexceptions | FileCheck %s
+// CHECK: @_ZZN5test74testEvE1x = internal global i32 0, align 4
+// CHECK: @_ZGVZN5test74testEvE1x = internal global i32 0
+// CHECK: @_ZZN5test84testEvE1x = internal global [[TEST8A:.*]] zeroinitializer, align 1
+// CHECK: @_ZGVZN5test84testEvE1x = internal global i32 0
+
typedef typeof(sizeof(int)) size_t;
class foo {
@@ -39,7 +44,7 @@ namespace test1 {
a.bar();
}
- // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]*
+ // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* %this, i32 %i) unnamed_addr
// CHECK: [[RET:%.*]] = alloca [[A]]*, align 4
// CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
// CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
@@ -49,7 +54,7 @@ namespace test1 {
// CHECK: [[THIS2:%.*]] = load [[A]]** [[RET]]
// CHECK: ret [[A]]* [[THIS2]]
- // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]*
+ // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* %this) unnamed_addr
// CHECK: [[RET:%.*]] = alloca [[A]]*, align 4
// CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
// CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
@@ -277,6 +282,76 @@ namespace test6 {
}
}
+namespace test7 {
+ int foo();
+
+ // Static and guard tested at top of file
+
+ // CHECK: define void @_ZN5test74testEv()
+ void test() {
+ // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test74testEvE1x
+ // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+ // CHECK-NEXT: br i1 [[T2]]
+ // -> fallthrough, end
+ // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x)
+ // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
+ // CHECK-NEXT: br i1 [[T4]]
+ // -> fallthrough, end
+ // CHECK: [[INIT:%.*]] = invoke i32 @_ZN5test73fooEv()
+ // CHECK: store i32 [[INIT]], i32* @_ZZN5test74testEvE1x, align 4
+ // CHECK-NEXT: call void @__cxa_guard_release(i32* @_ZGVZN5test74testEvE1x)
+ // CHECK-NEXT: br label
+ // -> end
+ // end:
+ // CHECK: ret void
+ static int x = foo();
+
+ // CHECK: call i8* @llvm.eh.exception()
+ // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
+ // CHECK: call void @_Unwind_Resume_or_Rethrow
+ }
+}
+
+namespace test8 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ // Static and guard tested at top of file
+
+ // CHECK: define void @_ZN5test84testEv()
+ void test() {
+ // CHECK: [[T0:%.*]] = load i32* @_ZGVZN5test84testEvE1x
+ // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
+ // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+ // CHECK-NEXT: br i1 [[T2]]
+ // -> fallthrough, end
+ // CHECK: [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x)
+ // CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
+ // CHECK-NEXT: br i1 [[T4]]
+ // -> fallthrough, end
+ // CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x)
+
+ // FIXME: Here we register a global destructor that
+ // unconditionally calls the destructor. That's what we've always
+ // done for -fno-use-cxa-atexit here, but that's really not
+ // semantically correct at all.
+
+ // CHECK: call void @__cxa_guard_release(i32* @_ZGVZN5test84testEvE1x)
+ // CHECK-NEXT: br label
+ // -> end
+ // end:
+ // CHECK: ret void
+ static A x;
+
+ // CHECK: call i8* @llvm.eh.exception()
+ // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
+ // CHECK: call void @_Unwind_Resume_or_Rethrow
+ }
+}
+
// CHECK: define linkonce_odr [[C:%.*]]* @_ZTv0_n12_N5test21CD1Ev(
// CHECK: call [[C]]* @_ZN5test21CD1Ev(
// CHECK: ret [[C]]* undef
diff --git a/test/CodeGenCXX/array-construction.cpp b/test/CodeGenCXX/array-construction.cpp
index ab46be7..d044ac5 100644
--- a/test/CodeGenCXX/array-construction.cpp
+++ b/test/CodeGenCXX/array-construction.cpp
@@ -32,5 +32,5 @@ int main() {
// CHECK-LP64: callq __ZN4xptoC1Ev
-// CHECK-LP32: call L__ZN4xptoC1Ev
+// CHECK-LP32: calll L__ZN4xptoC1Ev
diff --git a/test/CodeGenCXX/array-operator-delete-call.cpp b/test/CodeGenCXX/array-operator-delete-call.cpp
index acb85d2..ad60cf6 100644
--- a/test/CodeGenCXX/array-operator-delete-call.cpp
+++ b/test/CodeGenCXX/array-operator-delete-call.cpp
@@ -59,5 +59,5 @@ COST c2;
// CHECK-LP64: callq __ZdaPv
-// CHECK-LP32: call L__ZdaPv
+// CHECK-LP32: calll L__ZdaPv
diff --git a/test/CodeGenCXX/array-value-initialize.cpp b/test/CodeGenCXX/array-value-initialize.cpp
index 8a3d5ff..27607c1 100644
--- a/test/CodeGenCXX/array-value-initialize.cpp
+++ b/test/CodeGenCXX/array-value-initialize.cpp
@@ -49,4 +49,4 @@ int main()
Stuff b = a;
return 0;
-} \ No newline at end of file
+}
diff --git a/test/CodeGenCXX/asm.cpp b/test/CodeGenCXX/asm.cpp
new file mode 100644
index 0000000..3b745a7
--- /dev/null
+++ b/test/CodeGenCXX/asm.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+struct A
+{
+ ~A();
+};
+int foo(A);
+
+void bar(A &a)
+{
+ // CHECK: call void asm
+ asm("" : : "r"(foo(a)) ); // rdar://8540491
+ // CHECK: call void @_ZN1AD1Ev
+}
diff --git a/test/CodeGenCXX/attr-used.cpp b/test/CodeGenCXX/attr-used.cpp
new file mode 100644
index 0000000..26109e7
--- /dev/null
+++ b/test/CodeGenCXX/attr-used.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// <rdar://problem/8684363>: clang++ not respecting __attribute__((used)) on destructors
+struct X0 {
+ // CHECK: define linkonce_odr void @_ZN2X0C1Ev
+ __attribute__((used)) X0() {}
+ // CHECK: define linkonce_odr void @_ZN2X0D1Ev
+ __attribute__((used)) ~X0() {}
+};
diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp
index d689a4f..9e8740e5 100644
--- a/test/CodeGenCXX/attr.cpp
+++ b/test/CodeGenCXX/attr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s
// CHECK: @test2 = alias i32 ()* @_Z5test1v
diff --git a/test/CodeGenCXX/block-byref-cxx-objc.cpp b/test/CodeGenCXX/block-byref-cxx-objc.cpp
new file mode 100644
index 0000000..a4fbd6c
--- /dev/null
+++ b/test/CodeGenCXX/block-byref-cxx-objc.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks | FileCheck %s
+// rdar://8594790
+
+struct A {
+ int x;
+ A(const A &);
+ A();
+ ~A();
+};
+
+int main()
+{
+ __block A BYREF_VAR;
+ ^{ BYREF_VAR.x = 1234; };
+ return 0;
+}
+
+// CHECK: define internal void @__Block_byref_object_copy_
+// CHECK: call void @_ZN1AC1ERKS_
+// CHECK: define internal void @__Block_byref_object_dispose_
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: define internal void @__copy_helper_block_
+// CHECK: call void @_Block_object_assign
+// CHECK: define internal void @__destroy_helper_block_
+// CHECK: call void @_Block_object_dispose
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
new file mode 100644
index 0000000..ea174b5
--- /dev/null
+++ b/test/CodeGenCXX/blocks.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+namespace test0 {
+ // CHECK: define void @_ZN5test04testEi(
+ // CHECK: define internal void @__test_block_invoke_{{.*}}(
+ // CHECK: define internal void @__block_global_{{.*}}(
+ void test(int x) {
+ ^{ ^{ (void) x; }; };
+ }
+}
+
+extern void (^out)();
+
+namespace test1 {
+ // Capturing const objects doesn't require a local block.
+ // CHECK: define void @_ZN5test15test1Ev()
+ // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out
+ void test1() {
+ const int NumHorsemen = 4;
+ out = ^{ (void) NumHorsemen; };
+ }
+
+ // That applies to structs too...
+ // CHECK: define void @_ZN5test15test2Ev()
+ // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out
+ struct loc { double x, y; };
+ void test2() {
+ const loc target = { 5, 6 };
+ out = ^{ (void) target; };
+ }
+
+ // ...unless they have mutable fields...
+ // CHECK: define void @_ZN5test15test3Ev()
+ // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]],
+ // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
+ // CHECK: store void ()* [[T0]], void ()** @out
+ struct mut { mutable int x; };
+ void test3() {
+ const mut obj = { 5 };
+ out = ^{ (void) obj; };
+ }
+
+ // ...or non-trivial destructors...
+ // CHECK: define void @_ZN5test15test4Ev()
+ // CHECK: [[OBJ:%.*]] = alloca
+ // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:%.*]],
+ // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
+ // CHECK: store void ()* [[T0]], void ()** @out
+ struct scope { int x; ~scope(); };
+ void test4() {
+ const scope obj = { 5 };
+ out = ^{ (void) obj; };
+ }
+
+ // ...or non-trivial copy constructors, but it's not clear how to do
+ // that and still have a constant initializer in '03.
+}
diff --git a/test/CodeGenCXX/builtins.cpp b/test/CodeGenCXX/builtins.cpp
new file mode 100644
index 0000000..0629c31
--- /dev/null
+++ b/test/CodeGenCXX/builtins.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// PR8839
+extern "C" char memmove();
+
+int main() {
+ // CHECK: call signext i8 @memmove()
+ return memmove();
+}
diff --git a/test/CodeGenCXX/c99-variable-length-array.cpp b/test/CodeGenCXX/c99-variable-length-array.cpp
index 66c14ff..76f99c7 100644
--- a/test/CodeGenCXX/c99-variable-length-array.cpp
+++ b/test/CodeGenCXX/c99-variable-length-array.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
struct X {
X();
~X();
diff --git a/test/CodeGenCXX/call-arg-zero-temp.cpp b/test/CodeGenCXX/call-arg-zero-temp.cpp
index ed8118e..88e7452 100644
--- a/test/CodeGenCXX/call-arg-zero-temp.cpp
+++ b/test/CodeGenCXX/call-arg-zero-temp.cpp
@@ -19,4 +19,4 @@ int main() {
// CHECK-LP64: callq __Z3foo3obj
-// CHECK-LP32: call __Z3foo3obj
+// CHECK-LP32: calll __Z3foo3obj
diff --git a/test/CodeGenCXX/cast-conversion.cpp b/test/CodeGenCXX/cast-conversion.cpp
index 6dc6de6..27e34b9 100644
--- a/test/CodeGenCXX/cast-conversion.cpp
+++ b/test/CodeGenCXX/cast-conversion.cpp
@@ -24,9 +24,9 @@ int main () {
// CHECK-LP64: callq __ZN1AC1Ei
// CHECK-LP64: callq __ZN1BC1E1A
-// CHECK-LP32: call L__ZN1AC1Ei
-// CHECK-LP32: call L__ZN1BC1E1A
-// CHECK-LP32: call L__ZN1AC1Ei
-// CHECK-LP32: call L__ZN1BC1E1A
-// CHECK-LP32: call L__ZN1AC1Ei
-// CHECK-LP32: call L__ZN1BC1E1A
+// CHECK-LP32: calll L__ZN1AC1Ei
+// CHECK-LP32: calll L__ZN1BC1E1A
+// CHECK-LP32: calll L__ZN1AC1Ei
+// CHECK-LP32: calll L__ZN1BC1E1A
+// CHECK-LP32: calll L__ZN1AC1Ei
+// CHECK-LP32: calll L__ZN1BC1E1A
diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp
index 9303bda..6675b49 100644
--- a/test/CodeGenCXX/class-layout.cpp
+++ b/test/CodeGenCXX/class-layout.cpp
@@ -1,13 +1,19 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
// An extra byte should be allocated for an empty class.
-// CHECK: %struct.A = type { i8 }
-struct A { } a;
+namespace Test1 {
+ // CHECK: %"struct.Test1::A" = type { i8 }
+ struct A { } *a;
+}
-// No need to add tail padding here.
-// CHECK: %struct.B = type { i8*, i32 }
-struct B { void *a; int b; } b;
+namespace Test2 {
+ // No need to add tail padding here.
+ // CHECK: %"struct.Test2::A" = type { i8*, i32 }
+ struct A { void *a; int b; } *a;
+}
-// C should have a vtable pointer.
-// CHECK: %struct.C = type { i32 (...)**, i32 }
-struct C { virtual void f(); int a; } *c;
+namespace Test3 {
+ // C should have a vtable pointer.
+ // CHECK: %"struct.Test3::A" = type { i32 (...)**, i32 }
+ struct A { virtual void f(); int a; } *a;
+}
diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp
index 9cfce7a..a8c6f30 100644
--- a/test/CodeGenCXX/const-init.cpp
+++ b/test/CodeGenCXX/const-init.cpp
@@ -24,3 +24,15 @@ public:
// CHECK: @_ZN6PR55812g0E = global %1 { i32 1 }
C g0 = { C::e1 };
}
+
+namespace test2 {
+ struct A {
+ static const double d = 1.0;
+ static const float f = d / 2;
+ };
+
+ // CHECK: @_ZN5test22t0E = global double {{1\.0+e\+0+}}, align 8
+ // CHECK: @_ZN5test22t1E = global [2 x double] [double {{1\.0+e\+0+}}, double {{5\.0+e-0*}}1], align 16
+ double t0 = A::d;
+ double t1[] = { A::d, A::f };
+}
diff --git a/test/CodeGenCXX/constructor-attr.cpp b/test/CodeGenCXX/constructor-attr.cpp
new file mode 100644
index 0000000..691795f
--- /dev/null
+++ b/test/CodeGenCXX/constructor-attr.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @llvm.global_ctors
+
+// PR6521
+void bar();
+struct Foo {
+ // CHECK: define linkonce_odr void @_ZN3Foo3fooEv
+ static void foo() __attribute__((constructor)) {
+ bar();
+ }
+};
diff --git a/test/CodeGenCXX/constructor-conversion.cpp b/test/CodeGenCXX/constructor-conversion.cpp
index f135da5..405bba6 100644
--- a/test/CodeGenCXX/constructor-conversion.cpp
+++ b/test/CodeGenCXX/constructor-conversion.cpp
@@ -49,6 +49,6 @@ int main() {
// CHECK-LP64: callq __ZN1XC1EPKci
// CHECK-LP64: callq __ZN1XC1Ev
-// CHECK-LP32: call L__ZN1XC1Ei
-// CHECK-LP32: call L__ZN1XC1EPKci
-// CHECK-LP32: call L__ZN1XC1Ev
+// CHECK-LP32: calll L__ZN1XC1Ei
+// CHECK-LP32: calll L__ZN1XC1EPKci
+// CHECK-LP32: calll L__ZN1XC1Ev
diff --git a/test/CodeGenCXX/constructor-convert.cpp b/test/CodeGenCXX/constructor-convert.cpp
index 338febb..9122dae 100644
--- a/test/CodeGenCXX/constructor-convert.cpp
+++ b/test/CodeGenCXX/constructor-convert.cpp
@@ -5,7 +5,7 @@ class Twine {
Twine(const char *Str) { }
};
-static void error(const Twine &Message);
+static void error(const Twine &Message) {}
template<typename>
struct opt_storage {
diff --git a/test/CodeGenCXX/constructor-default-arg.cpp b/test/CodeGenCXX/constructor-default-arg.cpp
index ec0b8da..0c08c76 100644
--- a/test/CodeGenCXX/constructor-default-arg.cpp
+++ b/test/CodeGenCXX/constructor-default-arg.cpp
@@ -34,6 +34,6 @@ int main() {
// CHECK-LP64: callq __ZN1XC1ERKS_iii
// CHECK-LP64: callq __ZN1XC1ERKS_iii
-// CHECK-LP32: call L__ZN1XC1ERKS_iii
-// CHECK-LP32: call L__ZN1XC1ERKS_iii
-// CHECK-LP32: call L__ZN1XC1ERKS_iii
+// CHECK-LP32: calll L__ZN1XC1ERKS_iii
+// CHECK-LP32: calll L__ZN1XC1ERKS_iii
+// CHECK-LP32: calll L__ZN1XC1ERKS_iii
diff --git a/test/CodeGenCXX/constructor-direct-call.cpp b/test/CodeGenCXX/constructor-direct-call.cpp
new file mode 100644
index 0000000..75e6f21
--- /dev/null
+++ b/test/CodeGenCXX/constructor-direct-call.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s
+
+class Test1 {
+public:
+ int a;
+};
+
+void f1() {
+ Test1 var;
+ var.Test1::Test1();
+
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 4, i32 4, i1 false)
+ var.Test1::Test1(var);
+}
+
+class Test2 {
+public:
+ Test2() { a = 10; b = 10; }
+ int a;
+ int b;
+};
+
+void f2() {
+ // CHECK: %var = alloca %class.Test2, align 4
+ // CHECK-NEXT: call void @_ZN5Test2C1Ev(%class.Test2* %var)
+ Test2 var;
+
+ // CHECK-NEXT: call void @_ZN5Test2C1Ev(%class.Test2* %var)
+ var.Test2::Test2();
+
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 8, i32 4, i1 false)
+ var.Test2::Test2(var);
+}
+
+
+
+
+class Test3 {
+public:
+ Test3() { a = 10; b = 15; c = 20; }
+ Test3(const Test3& that) { a = that.a; b = that.b; c = that.c; }
+ int a;
+ int b;
+ int c;
+};
+
+void f3() {
+ // CHECK: call void @_ZN5Test3C1Ev(%class.Test3* %var)
+ Test3 var;
+
+ // CHECK-NEXT: call void @_ZN5Test3C1Ev(%class.Test3* %var2)
+ Test3 var2;
+
+ // CHECK-NEXT: call void @_ZN5Test3C1Ev(%class.Test3* %var)
+ var.Test3::Test3();
+
+ // CHECK-NEXT: call void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* %var2)
+ var.Test3::Test3(var2);
+}
+
diff --git a/test/CodeGenCXX/constructor-for-array-members.cpp b/test/CodeGenCXX/constructor-for-array-members.cpp
index b981da4..fd6dc6d 100644
--- a/test/CodeGenCXX/constructor-for-array-members.cpp
+++ b/test/CodeGenCXX/constructor-for-array-members.cpp
@@ -40,4 +40,4 @@ int main() {
// CHECK-LP64: callq __ZN1SC1Ev
-// CHECK-LP32: call L__ZN1SC1Ev
+// CHECK-LP32: calll L__ZN1SC1Ev
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
index 284b8b5..47e3b7b 100644
--- a/test/CodeGenCXX/constructor-init.cpp
+++ b/test/CodeGenCXX/constructor-init.cpp
@@ -81,6 +81,38 @@ void f() {
// CHECK: ret void
}
+// Make sure we initialize the vtable pointer if it's required by a
+// base initializer.
+namespace InitVTable {
+ struct A { A(int); };
+ struct B : A {
+ virtual int foo();
+ B();
+ B(int);
+ };
+
+ // CHECK: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr
+ // CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i8***
+ // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
+ // CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)*** {{%.*}}
+ // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)** [[VTBL]], i64 0
+ // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)** [[FNP]]
+ // CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]])
+ // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]])
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i8***
+ // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
+ // CHECK-NEXT: ret void
+ B::B() : A(foo()) {}
+
+ // CHECK: define void @_ZN10InitVTable1BC2Ei(%"struct.InitVTable::B"* %this, i32 %x) unnamed_addr
+ // CHECK: [[ARG:%.*]] = add nsw i32 {{%.*}}, 5
+ // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]])
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i8***
+ // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]]
+ // CHECK-NEXT: ret void
+ B::B(int x) : A(x + 5) {}
+}
+
template<typename T>
struct X {
X(const X &);
@@ -93,7 +125,7 @@ template<typename T> struct X;
// Make sure that the instantiated constructor initializes start and
// end properly.
-// CHECK: define linkonce_odr void @_ZN1XIiEC2ERKS0_
+// CHECK: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* %other) unnamed_addr
// CHECK: {{store.*null}}
// CHECK: {{store.*null}}
// CHECK: ret
diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp
index a8dc7fc..75588ce 100644
--- a/test/CodeGenCXX/constructors.cpp
+++ b/test/CodeGenCXX/constructors.cpp
@@ -21,18 +21,18 @@ struct A {
A::A(struct Undeclared &ref) : mem(0) {}
// Check that delegation works.
-// CHECK: define void @_ZN1AC1ER10Undeclared(
+// CHECK: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
// CHECK: call void @_ZN1AC2ER10Undeclared(
-// CHECK: define void @_ZN1AC2ER10Undeclared(
+// CHECK: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
// CHECK: call void @_ZN6MemberC1Ei(
A::A(ValueClass v) : mem(v.y - v.x) {}
-// CHECK: define void @_ZN1AC1E10ValueClass(
+// CHECK: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
// CHECK: call void @_ZN1AC2E10ValueClass(
-// CHECK: define void @_ZN1AC2E10ValueClass(
+// CHECK: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
// CHECK: call void @_ZN6MemberC1Ei(
@@ -44,10 +44,10 @@ struct B : A {
B::B(struct Undeclared &ref) : A(ref), mem(1) {}
-// CHECK: define void @_ZN1BC1ER10Undeclared(
+// CHECK: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
// CHECK: call void @_ZN1BC2ER10Undeclared(
-// CHECK: define void @_ZN1BC2ER10Undeclared(
+// CHECK: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
// CHECK: call void @_ZN1AC2ER10Undeclared(
// CHECK: call void @_ZN6MemberC1Ei(
@@ -64,12 +64,12 @@ struct C : virtual A {
};
C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {}
-// CHECK: define void @_ZN1CC1Ei(
+// CHECK: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr
// CHECK: call void @_ZN10ValueClassC1Eii(
// CHECK: call void @_ZN1AC2E10ValueClass(
// CHECK: call void @_ZN6MemberC1Ei(
-// CHECK: define void @_ZN1CC2Ei(
+// CHECK: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr
// CHECK: call void @_ZN6MemberC1Ei(
@@ -83,12 +83,12 @@ struct D : A {
D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
-// CHECK: define void @_ZN1DC1Eiz(
+// CHECK: define void @_ZN1DC1Eiz(%struct.B* %this, i32 %x, ...) unnamed_addr
// CHECK: call void @_ZN10ValueClassC1Eii(
// CHECK: call void @_ZN1AC2E10ValueClass(
// CHECK: call void @_ZN6MemberC1Ei(
-// CHECK: define void @_ZN1DC2Eiz(
+// CHECK: define void @_ZN1DC2Eiz(%struct.B* %this, i32 %x, ...) unnamed_addr
// CHECK: call void @_ZN10ValueClassC1Eii(
// CHECK: call void @_ZN1AC2E10ValueClass(
// CHECK: call void @_ZN6MemberC1Ei(
diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp
index dc49401..f895dbc 100644
--- a/test/CodeGenCXX/convert-to-fptr.cpp
+++ b/test/CodeGenCXX/convert-to-fptr.cpp
@@ -41,6 +41,6 @@ int main()
// CHECK-LP64: callq __ZN1AcvPFiiEEv
// CHECK-LP64: callq __ZN1BcvRFiiEEv
-// CHECK-LP32: call L__ZN1AcvPFiiEEv
-// CHECK-LP32: call L__ZN1BcvRFiiEEv
+// CHECK-LP32: calll L__ZN1AcvPFiiEEv
+// CHECK-LP32: calll L__ZN1BcvRFiiEEv
diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp
index 73e9b94..4f4a8e9 100644
--- a/test/CodeGenCXX/copy-constructor-elim-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -21,7 +21,7 @@ namespace no_elide_base {
Derived(const Other &O);
};
- // CHECK: define void @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE
+ // CHECK: define void @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* %this, %"struct.PR8683::A"* %O) unnamed_addr
Derived::Derived(const Other &O)
// CHECK: call void @_ZNK13no_elide_base5OthercvNS_4BaseEEv
// CHECK: call void @_ZN13no_elide_base4BaseC2ERKS0_
@@ -31,3 +31,25 @@ namespace no_elide_base {
// CHECK: ret void
}
}
+
+// PR8683.
+
+namespace PR8683 {
+
+struct A {
+ A();
+ A(const A&);
+ A& operator=(const A&);
+};
+
+struct B {
+ A a;
+};
+
+void f() {
+ // Verify that we don't mark the copy constructor in this expression as elidable.
+ // CHECK: call void @_ZN6PR86831AC1ERKS0_
+ A a = (B().a);
+}
+
+}
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
index 2f7c79b..a556679 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -3,5 +3,5 @@
struct A { virtual void a(); };
A x(A& y) { return y; }
-// CHECK: define linkonce_odr void @_ZN1AC1ERKS_(
+// CHECK: define linkonce_odr void @_ZN1AC1ERKS_(%struct.A* %this, %struct.A*) unnamed_addr
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp
index 9cafd0a..68f6805 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -21,7 +21,7 @@ struct P {
};
-// CHECK: define linkonce_odr void @_ZN1XC1ERKS_
+// CHECK: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X*) unnamed_addr
struct X : M, N, P { // ...
X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd),
au_i1(1234), au1_4("MASKED") {}
@@ -136,7 +136,7 @@ void f(B b1) {
B b2 = b1;
}
-// CHECK: define linkonce_odr void @_ZN6PR66281BC2ERKS0_
+// CHECK: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"*) unnamed_addr
// CHECK: call void @_ZN6PR66281TC1Ev
// CHECK: call void @_ZN6PR66281TC1Ev
// CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_
diff --git a/test/CodeGenCXX/cxx-block-objects.cpp b/test/CodeGenCXX/cxx-block-objects.cpp
new file mode 100644
index 0000000..b989065
--- /dev/null
+++ b/test/CodeGenCXX/cxx-block-objects.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+// rdar://8594790
+
+extern "C" {
+extern "C" void *_Block_copy(const void *aBlock);
+extern "C" void _Block_release(const void *aBlock);
+}
+
+class A {
+public:
+ int x;
+ A(const A &o);
+ A();
+ virtual ~A();
+ void hello() const;
+};
+
+int
+main()
+{
+ A a;
+ void (^c)(void) = ((__typeof(^{ a.hello(); }))_Block_copy((const void *)(^{ a.hello(); })));
+ c();
+ _Block_release((const void *)(c));
+ return 0;
+}
+
+// CHECK: define internal void @__copy_helper_block_
+// CHECK: call void @_ZN1AC1ERKS_
+
+
+// CHECK:define internal void @__destroy_helper_block_
+// CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenCXX/debug-info-ctor2.cpp b/test/CodeGenCXX/debug-info-ctor2.cpp
new file mode 100644
index 0000000..19bd64b
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-ctor2.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang -fverbose-asm -g -S %s -o - | grep AT_explicit
+
+
+class MyClass
+{
+public:
+ explicit MyClass (int i) :
+ m_i (i)
+ {}
+private:
+ int m_i;
+};
+
+MyClass m(1);
+
diff --git a/test/CodeGenCXX/debug-info-large-constant.cpp b/test/CodeGenCXX/debug-info-large-constant.cpp
new file mode 100644
index 0000000..2daa189
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-large-constant.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -g -triple=x86_64-apple-darwin %s -o /dev/null
+// PR 8913
+
+typedef __uint128_t word128;
+static const word128 m126 = 0xffffffffffffffffULL;
+word128 foo() {
+ return m126;
+}
diff --git a/test/CodeGenCXX/debug-info-member.cpp b/test/CodeGenCXX/debug-info-member.cpp
new file mode 100644
index 0000000..5052a6c
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-member.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang -fverbose-asm -cc1 -g -S %s -o - | grep DW_ACCESS_public
+class A {
+public:
+ int x;
+};
+A a;
diff --git a/test/CodeGenCXX/debug-info-method.cpp b/test/CodeGenCXX/debug-info-method.cpp
new file mode 100644
index 0000000..5935727
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-method.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang -fverbose-asm -cc1 -g -S %s -o - | grep DW_ACCESS_protected
+class A {
+protected:
+ int foo();
+};
+A a;
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp
new file mode 100644
index 0000000..2e0a96d
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-namespace.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang -g -S %s -o - | FileCheck %s
+
+// CHECK: TAG_namespace
+namespace A {
+ enum numbers {
+ ZERO,
+ ONE
+ };
+}
+
+using namespace A;
+numbers n;
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
index 233090c..0ddfc24 100644
--- a/test/CodeGenCXX/debug-info-template.cpp
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -1,4 +1,8 @@
-// RUN: %clang_cc1 -emit-llvm-only -g -S %s -o - | grep "TC<int>"
+// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s
+
+//CHECK: TC<int>
+//CHECK: DW_TAG_template_type_parameter
+
template<typename T>
class TC {
public:
@@ -7,3 +11,12 @@ public:
};
TC<int> tci;
+
+//CHECK: TU<2>
+//CHECK: DW_TAG_template_value_parameter
+template<unsigned >
+class TU {
+ int b;
+};
+
+TU<2> u2;
diff --git a/test/CodeGenCXX/decl-ref-init.cpp b/test/CodeGenCXX/decl-ref-init.cpp
index c215b1b..58fdeda 100644
--- a/test/CodeGenCXX/decl-ref-init.cpp
+++ b/test/CodeGenCXX/decl-ref-init.cpp
@@ -26,5 +26,5 @@ int main() {
// CHECK-LP64: callq __ZN1BcvR1AEv
// CHECK-LP64: callq __ZN1BcvR1AEv
-// CHECK-LP32: call L__ZN1BcvR1AEv
-// CHECK-LP32: call L__ZN1BcvR1AEv
+// CHECK-LP32: calll L__ZN1BcvR1AEv
+// CHECK-LP32: calll L__ZN1BcvR1AEv
diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp
index c441985..3d741d5 100644
--- a/test/CodeGenCXX/default-arg-temps.cpp
+++ b/test/CodeGenCXX/default-arg-temps.cpp
@@ -61,7 +61,7 @@ namespace test1 {
C c;
A a;
- // CHECK: define linkonce_odr void @_ZN5test11DC2Ev(
+ // CHECK: define linkonce_odr void @_ZN5test11DC2Ev(%"struct.test1::D"* %this) unnamed_addr
// CHECK: call void @_ZN5test11BC1Ev(
// CHECK-NEXT: call void @_ZN5test11CC1ERKNS_1BE(
// CHECK-NEXT: call void @_ZN5test11BD1Ev(
diff --git a/test/CodeGenCXX/default-arguments.cpp b/test/CodeGenCXX/default-arguments.cpp
index 2ed1567..6560d35 100644
--- a/test/CodeGenCXX/default-arguments.cpp
+++ b/test/CodeGenCXX/default-arguments.cpp
@@ -42,10 +42,10 @@ struct C {
C();
};
-// CHECK: define void @_ZN1CC1Ev(
+// CHECK: define void @_ZN1CC1Ev(%struct.C* %this) unnamed_addr
// CHECK: call void @_ZN1CC2Ev(
-// CHECK: define void @_ZN1CC2Ev(
+// CHECK: define void @_ZN1CC2Ev(%struct.C* %this) unnamed_addr
// CHECK: call void @_ZN2A1C1Ev(
// CHECK: call void @_ZN2A2C1Ev(
// CHECK: call void @_ZN1BC1ERK2A1RK2A2(
diff --git a/test/CodeGenCXX/default-constructor-for-members.cpp b/test/CodeGenCXX/default-constructor-for-members.cpp
index 1f17746..a97764d 100644
--- a/test/CodeGenCXX/default-constructor-for-members.cpp
+++ b/test/CodeGenCXX/default-constructor-for-members.cpp
@@ -20,4 +20,4 @@ int main() {
// CHECK-LP64: callq __ZN1SC1Ev
-// CHECK-LP32: call L__ZN1SC1Ev
+// CHECK-LP32: calll L__ZN1SC1Ev
diff --git a/test/CodeGenCXX/default-constructor-template-member.cpp b/test/CodeGenCXX/default-constructor-template-member.cpp
index e74fb6d..422cc09 100644
--- a/test/CodeGenCXX/default-constructor-template-member.cpp
+++ b/test/CodeGenCXX/default-constructor-template-member.cpp
@@ -6,5 +6,5 @@ void a() {
B b;
}
// CHECK: call void @_ZN1BC1Ev
-// CHECK: define linkonce_odr void @_ZN1BC1Ev
+// CHECK: define linkonce_odr void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
// CHECK: call void @_ZN1AIiEC1Ev
diff --git a/test/CodeGenCXX/delete-two-arg.cpp b/test/CodeGenCXX/delete-two-arg.cpp
index 5358747..b82e9ba 100644
--- a/test/CodeGenCXX/delete-two-arg.cpp
+++ b/test/CodeGenCXX/delete-two-arg.cpp
@@ -1,6 +1,70 @@
// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s
-struct A { void operator delete(void*,__typeof(sizeof(int))); int x; };
-void a(A* x) { delete x; }
+typedef __typeof(sizeof(int)) size_t;
-// CHECK: call void @_ZN1AdlEPvj(i8* %{{.*}}, i32 4)
+namespace test1 {
+ struct A { void operator delete(void*,size_t); int x; };
+
+ // CHECK: define void @_ZN5test11aEPNS_1AE(
+ void a(A *x) {
+ // CHECK: load
+ // CHECK-NEXT: icmp eq {{.*}}, null
+ // CHECK-NEXT: br i1
+ // CHECK: call void @_ZN5test11AdlEPvj(i8* %{{.*}}, i32 4)
+ delete x;
+ }
+}
+
+// Check that we make cookies for the two-arg delete even when using
+// the global allocator and deallocator.
+namespace test2 {
+ struct A {
+ int x;
+ void *operator new[](size_t);
+ void operator delete[](void *, size_t);
+ };
+
+ // CHECK: define [[A:%.*]]* @_ZN5test24testEv()
+ A *test() {
+ // CHECK: [[NEW:%.*]] = call noalias i8* @_Znaj(i32 44)
+ // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[NEW]] to i32*
+ // CHECK-NEXT: store i32 10, i32* [[T0]]
+ // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[NEW]], i64 4
+ // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[A]]*
+ // CHECK-NEXT: ret [[A]]* [[T2]]
+ return ::new A[10];
+ }
+
+ // CHECK: define void @_ZN5test24testEPNS_1AE(
+ void test(A *p) {
+ // CHECK: [[P:%.*]] = alloca [[A]]*, align 4
+ // CHECK-NEXT: store [[A]]* {{%.*}}, [[A]]** [[P]], align 4
+ // CHECK-NEXT: [[T0:%.*]] = load [[A]]** [[P]], align 4
+ // CHECK-NEXT: [[T1:%.*]] = icmp eq [[A]]* [[T0]], null
+ // CHECK-NEXT: br i1 [[T1]],
+ // CHECK: [[T2:%.*]] = bitcast [[A]]* [[T0]] to i8*
+ // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 -4
+ // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i32*
+ // CHECK-NEXT: [[T5:%.*]] = load i32* [[T4]]
+ // CHECK-NEXT: call void @_ZdaPv(i8* [[T3]])
+ // CHECK-NEXT: br label
+ ::delete[] p;
+ }
+}
+
+// rdar://problem/8913519
+namespace test3 {
+ struct A {
+ int x;
+ void operator delete[](void *, size_t);
+ };
+ struct B : A {};
+
+ // CHECK: define void @_ZN5test34testEv()
+ void test() {
+ // CHECK: call noalias i8* @_Znaj(i32 24)
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: store i32 5
+ (void) new B[5];
+ }
+}
diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp
index 1f52a78..ddc7bb8 100644
--- a/test/CodeGenCXX/delete.cpp
+++ b/test/CodeGenCXX/delete.cpp
@@ -54,7 +54,7 @@ namespace test0 {
delete a;
}
- // CHECK: define linkonce_odr void @_ZN5test01AD1Ev
+ // CHECK: define linkonce_odr void @_ZN5test01AD1Ev(%class.A* %this) unnamed_addr
// CHECK: define linkonce_odr void @_ZN5test01AdlEPv
}
@@ -105,3 +105,10 @@ namespace test2 {
delete [] b;
}
}
+
+namespace test3 {
+ void f(int a[10][20]) {
+ // CHECK: call void @_ZdaPv(i8*
+ delete a;
+ }
+}
diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp
index f2835b7..006f264 100644
--- a/test/CodeGenCXX/derived-to-base-conv.cpp
+++ b/test/CodeGenCXX/derived-to-base-conv.cpp
@@ -78,7 +78,7 @@ void test(Derived bb)
// CHECK-LP64: callq __ZN1XcvR1BEv
// CHECK-LP64: callq __ZN1AC1ERKS_
-// CHECK-LP32: call L__ZN1XcvR1BEv
-// CHECK-LP32: call L__ZN1AC1ERKS_
+// CHECK-LP32: calll L__ZN1XcvR1BEv
+// CHECK-LP32: calll L__ZN1AC1ERKS_
diff --git a/test/CodeGenCXX/derived-to-base.cpp b/test/CodeGenCXX/derived-to-base.cpp
index e44fdc5..76b79fc 100644
--- a/test/CodeGenCXX/derived-to-base.cpp
+++ b/test/CodeGenCXX/derived-to-base.cpp
@@ -34,3 +34,14 @@ A *f(B* b) {
}
+// Don't crash on a derived-to-base conversion of an r-value
+// aggregate.
+namespace test3 {
+ struct A {};
+ struct B : A {};
+
+ void foo(A a);
+ void test() {
+ foo(B());
+ }
+}
diff --git a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
new file mode 100644
index 0000000..e332f40
--- /dev/null
+++ b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+struct A { int i; };
+struct B { int j; };
+struct C : A, B { int k; };
+
+struct D final : virtual C {
+ D();
+ virtual void f();
+};
+
+// CHECK: define %struct.B* @_Z1fR1D
+B &f(D &d) {
+ // CHECK-NOT: load i8**
+ return d;
+}
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index 2eba30f..f382413 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -40,11 +40,11 @@ namespace PR7526 {
struct allocator_derived : allocator { };
- // CHECK: define void @_ZN6PR75269allocatorD2Ev
+ // CHECK: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR5529::A"* %this) unnamed_addr
// CHECK: call void @__cxa_call_unexpected
allocator::~allocator() throw() { foo(); }
- // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev
+ // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev(%"struct.PR5529::A"* %this) unnamed_addr
// CHECK-NOT: call void @__cxa_call_unexpected
// CHECK: }
void foo() {
@@ -93,7 +93,7 @@ namespace test0 {
// complete destructor alias tested above
-// CHECK: define void @_ZN5test01AD2Ev
+// CHECK: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr
// CHECK: invoke void @_ZN5test06MemberD1Ev
// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
// CHECK: invoke void @_ZN5test04BaseD2Ev
@@ -106,7 +106,7 @@ namespace test0 {
B::~B() try { } catch (int i) {}
// It will suppress the delegation optimization here, though.
-// CHECK: define void @_ZN5test01BD1Ev
+// CHECK: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
// CHECK: invoke void @_ZN5test06MemberD1Ev
// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
// CHECK: invoke void @_ZN5test04BaseD2Ev
@@ -114,7 +114,7 @@ namespace test0 {
// CHECK: invoke void @_ZN5test05VBaseD2Ev
// CHECK: unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]]
-// CHECK: define void @_ZN5test01BD2Ev
+// CHECK: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr
// CHECK: invoke void @_ZN5test06MemberD1Ev
// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
// CHECK: invoke void @_ZN5test04BaseD2Ev
@@ -142,24 +142,24 @@ namespace test1 {
O::~O() {} // alias tested above
struct P : NonEmpty, A { ~P(); };
- P::~P() {} // CHECK: define void @_ZN5test11PD2Ev
+ P::~P() {} // CHECK: define void @_ZN5test11PD2Ev(%"struct.test1::P"* %this) unnamed_addr
struct Q : A, B { ~Q(); };
- Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev
+ Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev(%"struct.test1::M"* %this) unnamed_addr
struct R : A { ~R(); };
- R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev
+ R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev(%"struct.test1::M"* %this) unnamed_addr
struct S : A { ~S(); int x; };
S::~S() {} // alias tested above
struct T : A { ~T(); B x; };
- T::~T() {} // CHECK: define void @_ZN5test11TD2Ev
+ T::~T() {} // CHECK: define void @_ZN5test11TD2Ev(%"struct.test1::T"* %this) unnamed_addr
// The VTT parameter prevents this. We could still make this work
// for calling conventions that are safe against extra parameters.
struct U : A, virtual B { ~U(); };
- U::~U() {} // CHECK: define void @_ZN5test11UD2Ev
+ U::~U() {} // CHECK: define void @_ZN5test11UD2Ev(%"struct.test1::U"* %this, i8** %vtt) unnamed_addr
}
// PR6471
@@ -168,7 +168,7 @@ namespace test2 {
struct B : A { ~B(); };
B::~B() {}
- // CHECK: define void @_ZN5test21BD2Ev
+ // CHECK: define void @_ZN5test21BD2Ev(%"struct.test1::M"* %this) unnamed_addr
// CHECK: call void @_ZN5test21AD2Ev
}
@@ -273,7 +273,7 @@ namespace test6 {
};
C::C() { opaque(); }
- // CHECK: define void @_ZN5test61CC1Ev
+ // CHECK: define void @_ZN5test61CC1Ev(%"struct.test6::C"* %this) unnamed_addr
// CHECK: call void @_ZN5test61BILj2EEC2Ev
// CHECK: invoke void @_ZN5test61BILj3EEC2Ev
// CHECK: invoke void @_ZN5test61BILj0EEC2Ev
@@ -283,7 +283,7 @@ namespace test6 {
// FIXME: way too much EH cleanup code follows
C::~C() { opaque(); }
- // CHECK: define void @_ZN5test61CD1Ev
+ // CHECK: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr
// CHECK: invoke void @_ZN5test61CD2Ev
// CHECK: invoke void @_ZN5test61BILj3EED2Ev
// CHECK: call void @_ZN5test61BILj2EED2Ev
@@ -291,7 +291,7 @@ namespace test6 {
// CHECK: invoke void @_ZN5test61BILj3EED2Ev
// CHECK: invoke void @_ZN5test61BILj2EED2Ev
- // CHECK: define void @_ZN5test61CD2Ev
+ // CHECK: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr
// CHECK: invoke void @_ZN5test66opaqueEv
// CHECK: invoke void @_ZN5test61AD1Ev
// CHECK: invoke void @_ZN5test61AD1Ev
@@ -306,9 +306,29 @@ namespace test6 {
// CHECK: invoke void @_ZN5test61BILj0EED2Ev
}
+// PR 9197
+namespace test7 {
+ struct D { ~D(); };
+
+ struct A { ~A(); };
+ A::~A() { }
+
+ struct B : public A {
+ ~B();
+ D arr[1];
+ };
+
+ // Verify that this doesn't get emitted as an alias
+ // CHECK: define void @_ZN5test71BD2Ev(
+ // CHECK: invoke void @_ZN5test71DD1Ev(
+ // CHECK: call void @_ZN5test71AD2Ev(
+ B::~B() {}
+
+}
+
// Checks from test3:
- // CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(
+ // CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::<anonymous namespace>::D"* %this) unnamed_addr
// CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev(
// CHECK: call void @_ZdlPv({{.*}}) nounwind
// CHECK: ret void
@@ -330,7 +350,7 @@ namespace test6 {
// CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev(
// CHECK: ret void
- // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(
+ // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::<anonymous namespace>::C"* %this) unnamed_addr
// CHECK: invoke void @_ZN5test31BD2Ev(
// CHECK: call void @_ZN5test31AD2Ev(
// CHECK: ret void
@@ -338,7 +358,7 @@ namespace test6 {
// CHECK: declare void @_ZN5test31BD2Ev(
// CHECK: declare void @_ZN5test31AD2Ev(
- // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(
+ // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::<anonymous namespace>::C"* %this) unnamed_addr
// CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD1Ev(
// CHECK: call void @_ZdlPv({{.*}}) nounwind
// CHECK: ret void
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
new file mode 100644
index 0000000..3de75ed
--- /dev/null
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+namespace Test1 {
+ struct A {
+ virtual int f() final;
+ };
+
+ // CHECK: define i32 @_ZN5Test11fEPNS_1AE
+ int f(A *a) {
+ // CHECK: call i32 @_ZN5Test11A1fEv
+ return a->f();
+ }
+}
+
+namespace Test2 {
+ struct A final {
+ virtual int f();
+ };
+
+ // CHECK: define i32 @_ZN5Test21fEPNS_1AE
+ int f(A *a) {
+ // CHECK: call i32 @_ZN5Test21A1fEv
+ return a->f();
+ }
+}
+
+namespace Test3 {
+ struct A {
+ virtual int f();
+ };
+
+ struct B final : A { };
+
+ // CHECK: define i32 @_ZN5Test31fEPNS_1BE
+ int f(B *b) {
+ // CHECK: call i32 @_ZN5Test31A1fEv
+ return b->f();
+ }
+
+ // CHECK: define i32 @_ZN5Test31fERNS_1BE
+ int f(B &b) {
+ // CHECK: call i32 @_ZN5Test31A1fEv
+ return b.f();
+ }
+
+ // CHECK: define i32 @_ZN5Test31fEPv
+ int f(void *v) {
+ // CHECK: call i32 @_ZN5Test31A1fEv
+ return static_cast<B*>(v)->f();
+ }
+}
diff --git a/test/CodeGenCXX/dyncast.cpp b/test/CodeGenCXX/dyncast.cpp
index 723e12b..7fd5899 100644
--- a/test/CodeGenCXX/dyncast.cpp
+++ b/test/CodeGenCXX/dyncast.cpp
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 -I%S -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll
// RUN: FileCheck -check-prefix LL --input-file=%t.ll %s
-// XFAIL: win32
#include <typeinfo>
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index 0960ec3..5ae65cc 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -10,16 +10,10 @@ void test1() {
}
// CHECK: define void @_Z5test1v()
-// CHECK: [[FREEVAR:%.*]] = alloca i1
-// CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8*
-// CHECK-NEXT: store i1 false, i1* [[FREEVAR]]
-// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
-// CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
-// CHECK-NEXT: store i1 true, i1* [[FREEVAR]]
+// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
// CHECK-NEXT: [[EXN2:%.*]] = bitcast [[DSTAR]] [[EXN]] to i8*
// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXN2]], i8* bitcast ([[DSTAR]] @d1 to i8*), i64 8, i32 8, i1 false)
-// CHECK-NEXT: store i1 false, i1* [[FREEVAR]]
// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn
// CHECK-NEXT: unreachable
@@ -36,20 +30,14 @@ void test2() {
}
// CHECK: define void @_Z5test2v()
-// CHECK: [[FREEVAR:%.*]] = alloca i1
-// CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8*
-// CHECK-NEXT: [[EXNSLOTVAR:%.*]] = alloca i8*
+// CHECK: [[EXNSLOTVAR:%.*]] = alloca i8*
// CHECK-NEXT: [[CLEANUPDESTVAR:%.*]] = alloca i32
-// CHECK-NEXT: store i1 false, i1* [[FREEVAR]]
// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
-// CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
-// CHECK-NEXT: store i1 true, i1* [[FREEVAR]]
// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
// CHECK-NEXT: invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2)
// CHECK-NEXT: to label %[[CONT:.*]] unwind label %{{.*}}
// : [[CONT]]: (can't check this in Release-Asserts builds)
-// CHECK: store i1 false, i1* [[FREEVAR]]
-// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%{{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn
+// CHECK: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%{{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn
// CHECK-NEXT: unreachable
@@ -64,15 +52,9 @@ void test3() {
}
// CHECK: define void @_Z5test3v()
-// CHECK: [[FREEVAR:%.*]] = alloca i1
-// CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8*
-// CHECK-NEXT: store i1 false, i1* [[FREEVAR]]
-// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
-// CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
-// CHECK-NEXT: store i1 true, i1* [[FREEVAR]]
-// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSS:%[^*]*\*]]*
-// CHECK-NEXT: store [[DSS]] null, [[DSS]]* [[EXN]]
-// CHECK-NEXT: store i1 false, i1* [[FREEVAR]]
+// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8)
+// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[D:%[^*]+]]**
+// CHECK-NEXT: store [[D]]* null, [[D]]** [[EXN]]
// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn
// CHECK-NEXT: unreachable
@@ -121,20 +103,14 @@ namespace test6 {
namespace test7 {
// CHECK: define i32 @_ZN5test73fooEv()
int foo() {
-// CHECK: [[FREEEXNOBJ:%.*]] = alloca i1
-// CHECK-NEXT: [[EXNALLOCVAR:%.*]] = alloca i8*
-// CHECK-NEXT: [[CAUGHTEXNVAR:%.*]] = alloca i8*
+// CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8*
// CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32
// CHECK-NEXT: [[EHCLEANUPDESTVAR:%.*]] = alloca i32
-// CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]]
try {
try {
// CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception
-// CHECK-NEXT: store i8* [[EXNALLOC]], i8** [[EXNALLOCVAR]]
-// CHECK-NEXT: store i1 true, i1* [[FREEEXNOBJ]]
// CHECK-NEXT: bitcast i8* [[EXNALLOC]] to i32*
// CHECK-NEXT: store i32 1, i32*
-// CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]]
// CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null
throw 1;
}
@@ -197,11 +173,11 @@ namespace test9 {
struct A { A(); };
- // CHECK: define void @_ZN5test91AC1Ev
+ // CHECK: define void @_ZN5test91AC1Ev(%"struct.test10::A"* %this) unnamed_addr
// CHECK: call void @_ZN5test91AC2Ev
// CHECK-NEXT: ret void
- // CHECK: define void @_ZN5test91AC2Ev(
+ // CHECK: define void @_ZN5test91AC2Ev(%"struct.test10::A"* %this) unnamed_addr
A::A() try {
// CHECK: invoke void @_ZN5test96opaqueEv()
opaque();
@@ -414,3 +390,49 @@ namespace test15 {
// CHECK: call void @_ZN6test151AD1Ev
}
}
+
+namespace test16 {
+ struct A { A(); ~A(); };
+ struct B { int x; B(const A &); ~B(); };
+ void foo();
+ bool cond();
+
+ // CHECK: define void @_ZN6test163barEv()
+ void bar() {
+ // CHECK: [[EXN_SAVE:%.*]] = alloca i8*
+ // CHECK-NEXT: [[EXN_ACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: [[TEMP:%.*]] = alloca [[A:%.*]],
+ // CHECK-NEXT: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[EHDEST:%.*]] = alloca i32
+ // CHECK-NEXT: [[TEMP_ACTIVE:%.*]] = alloca i1
+
+ cond() ? throw B(A()) : foo();
+
+ // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN6test164condEv()
+ // CHECK-NEXT: store i1 false, i1* [[EXN_ACTIVE]]
+ // CHECK-NEXT: store i1 false, i1* [[TEMP_ACTIVE]]
+ // CHECK-NEXT: br i1 [[COND]],
+
+ // CHECK: [[EXN:%.*]] = call i8* @__cxa_allocate_exception(i64 4)
+ // CHECK-NEXT: store i8* [[EXN]], i8** [[EXN_SAVE]]
+ // CHECK-NEXT: store i1 true, i1* [[EXN_ACTIVE]]
+ // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[EXN]] to [[B:%.*]]*
+ // CHECK-NEXT: invoke void @_ZN6test161AC1Ev([[A]]* [[TEMP]])
+ // CHECK: store i1 true, i1* [[TEMP_ACTIVE]]
+ // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* [[T0]], [[A]]* [[TEMP]])
+ // CHECK: store i1 false, i1* [[EXN_ACTIVE]]
+ // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXN]],
+
+ // CHECK: invoke void @_ZN6test163fooEv()
+ // CHECK: br label
+
+ // CHECK: invoke void @_ZN6test161AD1Ev([[A]]* [[TEMP]])
+ // CHECK: ret void
+
+ // CHECK: [[T0:%.*]] = load i1* [[EXN_ACTIVE]]
+ // CHECK-NEXT: br i1 [[T0]]
+ // CHECK: [[T1:%.*]] = load i8** [[EXN_SAVE]]
+ // CHECK-NEXT: call void @__cxa_free_exception(i8* [[T1]])
+ // CHECK-NEXT: br label
+ }
+}
diff --git a/test/CodeGenCXX/empty-classes.cpp b/test/CodeGenCXX/empty-classes.cpp
index 59124e3..1ce1dad 100644
--- a/test/CodeGenCXX/empty-classes.cpp
+++ b/test/CodeGenCXX/empty-classes.cpp
@@ -53,6 +53,19 @@ int f() {
return 0;
}
+namespace PR8796 {
+ struct FreeCell {
+ };
+ union ThingOrCell {
+ FreeCell t;
+ FreeCell cell;
+ };
+ struct Things {
+ ThingOrCell things;
+ };
+ Things x;
+}
+
#ifdef HARNESS
extern "C" void printf(const char *, ...);
diff --git a/test/CodeGenCXX/exceptions-no-rtti.cpp b/test/CodeGenCXX/exceptions-no-rtti.cpp
index 66b4c4a..bbbc1b8 100644
--- a/test/CodeGenCXX/exceptions-no-rtti.cpp
+++ b/test/CodeGenCXX/exceptions-no-rtti.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -fno-rtti -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
-// CHECK: @_ZTIN5test11AE = weak_odr constant
-// CHECK: @_ZTIN5test11BE = weak_odr constant
-// CHECK: @_ZTIN5test11CE = weak_odr constant
-// CHECK: @_ZTIN5test11DE = weak_odr constant
-// CHECK: @_ZTIPN5test11DE = weak_odr constant {{.*}} @_ZTIN5test11DE
+// CHECK: @_ZTIN5test11AE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTIN5test11BE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTIN5test11CE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTIN5test11DE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTIPN5test11DE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN5test11DE
// PR6974: this shouldn't crash
namespace test0 {
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
index 4d8fb80..84d55c8 100644
--- a/test/CodeGenCXX/exceptions.cpp
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -1,18 +1,295 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fexceptions
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fexceptions | FileCheck %s
-struct allocator {
- allocator();
- allocator(const allocator&);
- ~allocator();
-};
+typedef typeof(sizeof(0)) size_t;
-void f();
-void g(bool b, bool c) {
- if (b) {
- if (!c)
- throw allocator();
+// This just shouldn't crash.
+namespace test0 {
+ struct allocator {
+ allocator();
+ allocator(const allocator&);
+ ~allocator();
+ };
- return;
+ void f();
+ void g(bool b, bool c) {
+ if (b) {
+ if (!c)
+ throw allocator();
+
+ return;
+ }
+ f();
+ }
+}
+
+namespace test1 {
+ struct A { A(int); A(int, int); ~A(); void *p; };
+
+ A *a() {
+ // CHECK: define [[A:%.*]]* @_ZN5test11aEv()
+ // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 5)
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: call void @_ZdlPv(i8* [[NEW]])
+ return new A(5);
+ }
+
+ A *b() {
+ // CHECK: define [[A:%.*]]* @_ZN5test11bEv()
+ // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv()
+ // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[FOO]])
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: call void @_ZdlPv(i8* [[NEW]])
+ extern int foo();
+ return new A(foo());
+ }
+
+ struct B { B(); ~B(); operator int(); int x; };
+ B makeB();
+
+ A *c() {
+ // CHECK: define [[A:%.*]]* @_ZN5test11cEv()
+ // CHECK: [[ACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
+ // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
+ // CHECK: [[T1:%.*]] = getelementptr inbounds [[B]]* [[T0]], i32 0, i32 0
+ // CHECK-NEXT: [[T2:%.*]] = load i32* [[T1]], align 4
+ // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]])
+ // CHECK: store i1 false, i1* [[ACTIVE]]
+ // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: call void @_ZdlPv(i8* [[NEW]])
+ return new A(B().x);
+ }
+
+ A *d() {
+ // CHECK: define [[A:%.*]]* @_ZN5test11dEv()
+ // CHECK: [[ACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
+ // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
+ // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
+ // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
+ // CHECK: store i1 false, i1* [[ACTIVE]]
+ // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: call void @_ZdlPv(i8* [[NEW]])
+ return new A(B());
+ }
+
+ A *e() {
+ // CHECK: define [[A:%.*]]* @_ZN5test11eEv()
+ // CHECK: [[ACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
+ // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
+ // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
+ // CHECK: invoke void @_ZN5test11BC1Ev([[B]]* [[T2:%.*]])
+ // CHECK: [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T2]])
+ // CHECK: invoke void @_ZN5test11AC1Eii([[A]]* [[CAST]], i32 [[T1]], i32 [[T3]])
+ // CHECK: store i1 false, i1* [[ACTIVE]]
+ // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
+ // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: call void @_ZdlPv(i8* [[NEW]])
+ return new A(B(), B());
+ }
+ A *f() {
+ return new A(makeB().x);
+ }
+ A *g() {
+ return new A(makeB());
+ }
+ A *h() {
+ return new A(makeB(), makeB());
+ }
+
+ A *i() {
+ // CHECK: define [[A:%.*]]* @_ZN5test11iEv()
+ // CHECK: [[X:%.*]] = alloca [[A]]*, align 8
+ // CHECK: [[ACTIVE:%.*]] = alloca i1
+ // CHECK: store i1 true, i1* [[ACTIVE]]
+ // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T0:%.*]])
+ // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
+ // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
+ // CHECK: store i1 false, i1* [[ACTIVE]]
+ // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8
+ // CHECK: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]])
+ // CHECK: [[RET:%.*]] = load [[A]]** [[X]], align 8
+ // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
+ // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
+ // CHECK: ret [[A]]* [[RET]]
+ // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: call void @_ZdlPv(i8* [[NEW]])
+ A *x;
+ return (x = new A(makeB()), makeB(), x);
+ }
+}
+
+namespace test2 {
+ struct A {
+ A(int); A(int, int); ~A();
+ void *p;
+ void *operator new(size_t);
+ void operator delete(void*, size_t);
+ };
+
+ A *a() {
+ // CHECK: define [[A:%.*]]* @_ZN5test21aEv()
+ // CHECK: [[NEW:%.*]] = call i8* @_ZN5test21AnwEm(i64 8)
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test21AC1Ei([[A]]* [[CAST]], i32 5)
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
+ // CHECK: call void @_ZSt9terminatev()
+ return new A(5);
+ }
+}
+
+namespace test3 {
+ struct A {
+ A(int); A(int, int); A(const A&); ~A();
+ void *p;
+ void *operator new(size_t, void*, double);
+ void operator delete(void*, void*, double);
+ };
+
+ void *foo();
+ double bar();
+ A makeA(), *makeAPtr();
+
+ A *a() {
+ // CHECK: define [[A:%.*]]* @_ZN5test31aEv()
+ // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
+ // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv()
+ // CHECK: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[BAR]])
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5)
+ // CHECK: ret [[A]]* [[CAST]]
+ // CHECK: invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
+ // CHECK: call void @_ZSt9terminatev()
+ return new(foo(),bar()) A(5);
+ }
+
+ // rdar://problem/8439196
+ A *b(bool cond) {
+
+ // CHECK: define [[A:%.*]]* @_ZN5test31bEb(i1 zeroext
+ // CHECK: [[SAVED0:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8
+ // CHECK: [[TMPACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
+
+ // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
+ // CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]]
+ // CHECK-NEXT: br i1 [[COND]]
+ return (cond ?
+
+ // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[CONST:.*]])
+ // CHECK-NEXT: store i8* [[NEW]], i8** [[SAVED0]]
+ // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]]
+ // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]]
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[TMP]])
+ // CHECK: store i1 true, i1* [[TMPACTIVE]]
+ // CHECK-NEXT: invoke void @_ZN5test31AC1ERKS0_([[A]]* [[CAST]], [[A]]* [[TMP]])
+ // CHECK: store i1 false, i1* [[CLEANUPACTIVE]]
+ // CHECK-NEXT: br label
+ // -> cond.end
+ new(foo(),10.0) A(makeA()) :
+
+ // CHECK: [[MAKE:%.*]] = invoke [[A]]* @_ZN5test38makeAPtrEv()
+ // CHECK: br label
+ // -> cond.end
+ makeAPtr());
+
+ // cond.end:
+ // CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
+ // CHECK-NEXT: [[ISACTIVE:%.*]] = load i1* [[TMPACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: invoke void @_ZN5test31AD1Ev
+ // CHECK: ret [[A]]* [[RESULT]]
+
+ // in the EH path:
+ // CHECK: [[ISACTIVE:%.*]] = load i1* [[CLEANUPACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: [[V0:%.*]] = load i8** [[SAVED0]]
+ // CHECK-NEXT: [[V1:%.*]] = load i8** [[SAVED1]]
+ // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
+ }
+}
+
+namespace test4 {
+ struct A {
+ A(int); A(int, int); ~A();
+ void *p;
+ void *operator new(size_t, void*, void*);
+ void operator delete(void*, size_t, void*, void*); // not a match
+ };
+
+ A *a() {
+ // CHECK: define [[A:%.*]]* @_ZN5test41aEv()
+ // CHECK: [[FOO:%.*]] = call i8* @_ZN5test43fooEv()
+ // CHECK-NEXT: [[BAR:%.*]] = call i8* @_ZN5test43barEv()
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test41AnwEmPvS1_(i64 8, i8* [[FOO]], i8* [[BAR]])
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: call void @_ZN5test41AC1Ei([[A]]* [[CAST]], i32 5)
+ // CHECK-NEXT: ret [[A]]* [[CAST]]
+ extern void *foo(), *bar();
+
+ return new(foo(),bar()) A(5);
+ }
+}
+
+// PR7908
+namespace test5 {
+ struct T { T(); ~T(); };
+
+ struct A {
+ A(const A &x, const T &t = T());
+ ~A();
+ };
+
+ void foo();
+
+ // CHECK: define void @_ZN5test54testEv()
+ // CHECK: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
+ // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
+ // CHECK-NEXT: alloca i32
+ // CHECK-NEXT: invoke void @_ZN5test53fooEv()
+ // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]]
+ // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]])
+ // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]*
+ // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]])
+ // CHECK: invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* [[SRC]], [[T_T]]* [[T]])
+ // CHECK: invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]])
+ // CHECK: call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind
+ // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]])
+ // CHECK: call void @__cxa_end_catch()
+ void test() {
+ try {
+ foo();
+ } catch (A a) {
+ }
}
- f();
}
diff --git a/test/CodeGenCXX/friend-redecl.cpp b/test/CodeGenCXX/friend-redecl.cpp
new file mode 100644
index 0000000..18292cd
--- /dev/null
+++ b/test/CodeGenCXX/friend-redecl.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// PR8864
+
+struct Foo {
+ friend bool TryFoo(Foo *f2) { return TryFoo(0, f2); }
+
+// CHECK: define{{.*}}Z6TryFooP3Foo
+// CHECK-NOT: ret
+// CHECK: call{{.*}}Z6TryFooiP3Foo
+// CHECK: ret
+
+ friend bool TryFoo(int, Foo *f3);
+};
+bool TryFoo(Foo *f5);
+int main(void) {
+ Foo f;
+ TryFoo(&f);
+}
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index 6ff9598..6003270 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -12,11 +12,17 @@ struct C { void *field; };
struct D { ~D(); };
+// CHECK: @__dso_handle = external unnamed_addr global i8*
// CHECK: @c = global %struct.C zeroinitializer, align 8
// It's okay if we ever implement the IR-generation optimization to remove this.
// CHECK: @_ZN5test3L3varE = internal constant i8* getelementptr inbounds ([7 x i8]*
+// PR6205: The casts should not require global initializers
+// CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C"
+// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to %"struct.PR5974::A"*), align 8
+// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::A"* bitcast (i8* getelementptr (%"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0, i64 4) to %"struct.PR5974::A"*), align 8
+
// CHECK: call void @_ZN1AC1Ev(%struct.A* @a)
// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
A a;
@@ -64,6 +70,17 @@ namespace test3 {
const char *test() { return var; }
}
+namespace PR5974 {
+ struct A { int a; };
+ struct B { int b; };
+ struct C : A, B { int c; };
+
+ extern C c;
+
+ // These should not require global initializers.
+ A* a = &c;
+ B* b = &c;
+}
// CHECK: define internal void [[TEST1_Z_INIT:@.*]]()
// CHECK: load i32* @_ZN5test1L1yE
// CHECK-NEXT: xor
diff --git a/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp b/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp
new file mode 100644
index 0000000..fea8364
--- /dev/null
+++ b/test/CodeGenCXX/gnu-conditional-scalar-ext.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+// rdar: // 8353567
+// pr7726
+
+extern "C" int printf(...);
+
+void test0() {
+// CHECK: call i32 (...)* @printf({{.*}}, i8* inttoptr (i64 3735928559 to i8*))
+ printf("%p\n", (void *)0xdeadbeef ? : (void *)0xaaaaaa);
+}
+
+// rdar://8446940
+namespace radar8446940 {
+extern "C" void abort();
+
+int main () {
+ char x[1];
+ char *y = x ? : 0;
+
+ if (x != y)
+ abort();
+}
+}
+
+namespace radar8453812 {
+extern "C" void abort();
+_Complex int getComplex(_Complex int val) {
+ static int count;
+ if (count++)
+ abort();
+ return val;
+}
+
+_Complex int cmplx() {
+ _Complex int cond;
+ _Complex int rhs;
+
+ return getComplex(1+2i) ? : rhs;
+}
+
+// lvalue test
+void foo (int& lv) {
+ ++lv;
+}
+
+int global = 1;
+
+int &cond() {
+ static int count;
+ if (count++)
+ abort();
+ return global;
+}
+
+
+int main() {
+ cmplx();
+ int rhs = 10;
+ foo (cond()? : rhs);
+ return global-2;
+}
+}
diff --git a/test/CodeGenCXX/goto.cpp b/test/CodeGenCXX/goto.cpp
new file mode 100644
index 0000000..938d4e1
--- /dev/null
+++ b/test/CodeGenCXX/goto.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fexceptions -emit-llvm -o - | FileCheck %s
+
+// Reduced from a crash on boost::interprocess's node_allocator_test.cpp.
+namespace test0 {
+ struct A { A(); ~A(); };
+ struct V { V(const A &a = A()); ~V(); };
+
+ // CHECK: define linkonce_odr i32 @_ZN5test04testILi0EEEii
+ template<int X> int test(int x) {
+ // CHECK: [[RET:%.*]] = alloca i32
+ // CHECK-NEXT: [[X:%.*]] = alloca i32
+ // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]],
+ // CHECK-NEXT: [[Z:%.*]] = alloca [[A]]
+ // CHECK-NEXT: [[EXN:%.*]] = alloca i8*
+ // CHECK-NEXT: alloca i32
+ // CHECK-NEXT: [[V:%.*]] = alloca [[V:%.*]]*,
+ // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]
+ // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
+ // CHECK: store i1 true, i1* [[CLEANUPACTIVE]]
+ // CHECK: call void @_ZN5test01AC1Ev([[A]]* [[Y]])
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[Z]])
+ // CHECK: [[NEW:%.*]] = invoke noalias i8* @_Znwm(i64 1)
+ // CHECK: [[NEWCAST:%.*]] = bitcast i8* [[NEW]] to [[V]]*
+ // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[TMP]])
+ // CHECK: invoke void @_ZN5test01VC1ERKNS_1AE([[V]]* [[NEWCAST]], [[A]]* [[TMP]])
+ // CHECK: store i1 false, i1* [[CLEANUPACTIVE]]
+ // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[TMP]])
+ A y;
+ try {
+ A z;
+ V *v = new V();
+
+ if (x) return 1;
+ } catch (int ex) {
+ return 1;
+ }
+ return 0;
+ }
+
+ int test() {
+ return test<0>(5);
+ }
+}
diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp
index a343dd1..5008601 100644
--- a/test/CodeGenCXX/implicit-copy-constructor.cpp
+++ b/test/CodeGenCXX/implicit-copy-constructor.cpp
@@ -40,7 +40,7 @@ void f(D d) {
D d2(d);
}
-// CHECK: define linkonce_odr void @_ZN1DC1ERS_
+// CHECK: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D*) unnamed_addr
// CHECK: call void @_ZN1AC1Ev
// CHECK: call void @_ZN1CC2ERS_1A
// CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenCXX/inline-functions.cpp b/test/CodeGenCXX/inline-functions.cpp
index 8d046a2..69dfe0d 100644
--- a/test/CodeGenCXX/inline-functions.cpp
+++ b/test/CodeGenCXX/inline-functions.cpp
@@ -21,3 +21,35 @@ void B<char>::f() { }
// CHECK: define void @_Z1fv
void f() { }
+
+// <rdar://problem/8740363>
+inline void f1(int);
+
+// CHECK: define linkonce_odr void @_Z2f1i
+void f1(int) { }
+
+void test_f1() { f1(17); }
+
+// PR8789
+namespace test1 {
+ template <typename T> class ClassTemplate {
+ private:
+ friend void T::func();
+ void g() {}
+ };
+
+ // CHECK: define linkonce_odr void @_ZN5test11C4funcEv(
+
+ class C {
+ public:
+ void func() {
+ ClassTemplate<C> ct;
+ ct.g();
+ }
+ };
+
+ void f() {
+ C c;
+ c.func();
+ }
+}
diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp
index 9fdb727..39bce85 100644
--- a/test/CodeGenCXX/internal-linkage.cpp
+++ b/test/CodeGenCXX/internal-linkage.cpp
@@ -1,11 +1,11 @@
// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
struct Global { Global(); };
-template<typename T> struct X { X(); };
+template<typename T> struct X { X() {} };
namespace {
- struct Anon { Anon(); };
+ struct Anon { Anon() {} };
// CHECK: @_ZN12_GLOBAL__N_15anon0E = internal global
Global anon0;
diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp
index 15c058d..8e474bd 100644
--- a/test/CodeGenCXX/key-function-vtable.cpp
+++ b/test/CodeGenCXX/key-function-vtable.cpp
@@ -30,6 +30,7 @@ void testf::a() {}
namespace {
struct testg { virtual void a(); };
}
+void testg::a() {}
testg *testgvar = new testg;
struct X0 { virtual ~X0(); };
@@ -43,9 +44,9 @@ void use_X1(X1 *x1) { x1->f(); }
// FIXME: The checks are extremely difficult to get right when the globals
// aren't alphabetized
-// CHECK: @_ZTV2X1 = weak_odr constant
-// CHECK: @_ZTV5testa = constant [3 x i8*] [i8* null
-// CHECK: @_ZTV5testc = weak_odr constant [3 x i8*] [i8* null
-// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal constant [3 x i8*] [i8* null
-// CHECK: @_ZTV5teste = weak_odr constant [3 x i8*] [i8* null
-// CHECK: @_ZTV5testb = weak_odr constant [3 x i8*] [i8* null
+// CHECK: @_ZTV2X1 = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTV5testa = unnamed_addr constant [3 x i8*] [i8* null
+// CHECK: @_ZTV5testc = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
+// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant [3 x i8*] [i8* null
+// CHECK: @_ZTV5teste = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
+// CHECK: @_ZTV5testb = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
diff --git a/test/CodeGenCXX/mangle-abi-examples.cpp b/test/CodeGenCXX/mangle-abi-examples.cpp
new file mode 100644
index 0000000..7124078
--- /dev/null
+++ b/test/CodeGenCXX/mangle-abi-examples.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTVZ3foovEN1C1DE =
+// CHECK: @_ZTVZN1A3fooEiE1B =
+// CHECK: define {{.*}} @_ZZZ3foovEN1C3barEvEN1E3bazEv(
+
+// Itanium C++ ABI examples.
+struct A {
+ void foo (int) {
+ struct B { virtual ~B() {} };
+ B();
+ }
+};
+void foo () {
+ struct C {
+ struct D { virtual ~D() {} };
+ void bar () {
+ struct E {
+ void baz() { }
+ };
+ E().baz();
+ }
+ };
+ A().foo(0);
+ C::D();
+ C().bar();
+}
diff --git a/test/CodeGenCXX/mangle-local-class-vtables.cpp b/test/CodeGenCXX/mangle-local-class-vtables.cpp
new file mode 100644
index 0000000..d9d3afe
--- /dev/null
+++ b/test/CodeGenCXX/mangle-local-class-vtables.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTVZN1J1KEvE1C = {{.*}} @_ZTIZN1J1KEvE1C {{.*}} @_ZZN1J1KEvENK1C1FEv
+// CHECK: @_ZTIZN1J1KEvE1C = {{.*}} @_ZTSZN1J1KEvE1C
+// CHECK: @_ZTVZ1GvE1C_1 = {{.*}} @_ZTIZ1GvE1C_1 {{.*}} @_ZZ1GvENK1C1FE_1v
+// CHECK: @_ZTIZ1GvE1C_1 = {{.*}} @_ZTSZ1GvE1C_1
+// CHECK: @_ZTVZ1GvE1C_0 = {{.*}} @_ZTIZ1GvE1C_0 {{.*}} @_ZZ1GvENK1C1FE_0v
+// CHECK: @_ZTIZ1GvE1C_0 = {{.*}} @_ZTSZ1GvE1C_0
+// CHECK: @_ZTVZ1GvE1C = {{.*}} @_ZTIZ1GvE1C {{.*}} @_ZZ1GvENK1C1FEv
+// CHECK: @_ZTIZ1GvE1C = {{.*}} @_ZTSZ1GvE1C
+
+// CHECK: define {{.*}} @_ZZN1J1KEvEN1CC2Ev(
+// CHECK: define {{.*}} @_ZZN1J1KEvENK1C1FEv(
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_1v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_1v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1HE_1v(
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_0v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_0v(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1GE_0v(
+// CHECK: define {{.*}} @_ZZ1GvEN1CC2Ev(
+// CHECK: define {{.*}} @_ZZ1GvENK1C1FEv(
+
+struct I {
+ virtual void F() const = 0;
+};
+
+void Go(const I &i);
+
+void G() {
+ {
+ struct C : I {
+ void F() const {}
+ };
+ Go(C());
+ }
+ {
+ struct C : I {
+ void F() const { G(); }
+ void G() const {}
+ };
+ Go(C());
+ }
+ {
+ struct C : I {
+ void F() const { H(); }
+ void H() const {}
+ };
+ Go(C());
+ }
+}
+
+struct J {
+ void K();
+};
+
+void J::K() {
+ struct C : I {
+ void F() const {}
+ };
+ Go(C());
+}
diff --git a/test/CodeGenCXX/mangle-local-classes-nested.cpp b/test/CodeGenCXX/mangle-local-classes-nested.cpp
new file mode 100644
index 0000000..fafa5d4
--- /dev/null
+++ b/test/CodeGenCXX/mangle-local-classes-nested.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZTVZZ1HvEN1S1IEvE1S =
+
+// CHECK: define {{.*}} @_Z2L1v(
+// CHECK: define {{.*}} @_ZZ2L1vEN1S2L2Ev(
+// CHECK: define {{.*}} @_ZZ2L1vEN1S2L2E_0v(
+// CHECK: define {{.*}} @_ZZ1FvEN1S1T1S1T1GEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3cEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3dE_0v(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3aEv(
+// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3bE_0v(
+
+void L1() {
+ {
+ struct S {
+ void L2() {
+ {
+ struct S {
+ void L3a() {}
+ };
+ S().L3a();
+ }
+ {
+ struct S {
+ void L3b() {}
+ };
+ S().L3b();
+ }
+ }
+ };
+ S().L2();
+ }
+ {
+ struct S {
+ void L2() {
+ {
+ struct S {
+ void L3c() {}
+ };
+ S().L3c();
+ }
+ {
+ struct S {
+ void L3d() {}
+ };
+ S().L3d();
+ }
+ }
+ };
+ S().L2();
+ }
+}
+
+void F() {
+ struct S {
+ struct T {
+ struct S {
+ struct T {
+ void G() {}
+ };
+ };
+ };
+ };
+ S::T::S::T().G();
+}
+
+struct B { virtual void Foo() = 0; };
+void G(const B &);
+
+void H() {
+ struct S {
+ void I() {
+ struct S : B {
+ virtual void Foo() {}
+ };
+ G(S());
+ }
+ };
+ S().I();
+}
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index 61f8a59..d8d75b7 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
// CHECK: @"\01?a@@3HA"
// CHECK: @"\01?b@N@@3HA"
@@ -11,7 +11,7 @@
// CHECK: @"\01?i@@3PAY0BE@HA"
// CHECK: @"\01?j@@3P6GHCE@ZA"
// CHECK: @"\01?k@@3PTfoo@@DA"
-// CHECK: @"\01?l@@3P8foo@@AAHH@ZA"
+// CHECK: @"\01?l@@3P8foo@@AEHH@ZA"
int a;
@@ -46,10 +46,8 @@ enum quux {
qthree
};
-// NOTE: The calling convention is supposed to be __thiscall by default,
-// but that needs to be fixed in Sema/AST.
int foo::operator+(int a) {return a;}
-// CHECK: @"\01??Hfoo@@QAAHH@Z"
+// CHECK: @"\01??Hfoo@@QAEHH@Z"
const short foo::d = 0;
volatile long foo::e;
diff --git a/test/CodeGenCXX/mangle-neon-vectors.cpp b/test/CodeGenCXX/mangle-neon-vectors.cpp
new file mode 100644
index 0000000..3723deb
--- /dev/null
+++ b/test/CodeGenCXX/mangle-neon-vectors.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+
+typedef float float32_t;
+typedef signed char poly8_t;
+typedef short poly16_t;
+typedef unsigned long long uint64_t;
+
+typedef __attribute__((neon_vector_type(2))) int int32x2_t;
+typedef __attribute__((neon_vector_type(4))) int int32x4_t;
+typedef __attribute__((neon_vector_type(1))) uint64_t uint64x1_t;
+typedef __attribute__((neon_vector_type(2))) uint64_t uint64x2_t;
+typedef __attribute__((neon_vector_type(2))) float32_t float32x2_t;
+typedef __attribute__((neon_vector_type(4))) float32_t float32x4_t;
+typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t;
+typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t;
+
+// CHECK: 16__simd64_int32_t
+void f1(int32x2_t v) { }
+// CHECK: 17__simd128_int32_t
+void f2(int32x4_t v) { }
+// CHECK: 17__simd64_uint64_t
+void f3(uint64x1_t v) { }
+// CHECK: 18__simd128_uint64_t
+void f4(uint64x2_t v) { }
+// CHECK: 18__simd64_float32_t
+void f5(float32x2_t v) { }
+// CHECK: 19__simd128_float32_t
+void f6(float32x4_t v) { }
+// CHECK: 17__simd128_poly8_t
+void f7(poly8x16_t v) { }
+// CHECK: 18__simd128_poly16_t
+void f8(poly16x8_t v) { }
diff --git a/test/CodeGenCXX/mangle-ref-qualifiers.cpp b/test/CodeGenCXX/mangle-ref-qualifiers.cpp
new file mode 100644
index 0000000..b3f37d7
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ref-qualifiers.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+struct X {
+ int f() &;
+ int g() &&;
+ int h() const &&;
+};
+
+// CHECK: define i32 @_ZNR1X1fEv
+int X::f() & { return 0; }
+// CHECK: define i32 @_ZNO1X1gEv
+int X::g() && { return 0; }
+// CHECK: define i32 @_ZNKO1X1hEv
+int X::h() const && { return 0; }
+
+// CHECK: define void @_Z1fM1XRFivEMS_OFivEMS_KOFivE
+void f(int (X::*)() &, int (X::*)() &&, int (X::*)() const&&) { }
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
index 9c1e978..8d79988 100644
--- a/test/CodeGenCXX/mangle-subst-std.cpp
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -3,19 +3,19 @@
// Check mangling of Vtables, VTTs, and construction vtables that
// involve standard substitutions.
-// CHECK: @_ZTVSd = weak_odr constant
+// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant
// CHECK: @_ZTCSd0_Si = internal constant
// CHECK: @_ZTCSd16_So = internal constant
-// CHECK: @_ZTTSd = weak_odr constant
-// CHECK: @_ZTVSo = weak_odr constant
-// CHECK: @_ZTTSo = weak_odr constant
-// CHECK: @_ZTVSi = weak_odr constant
-// CHECK: @_ZTTSi = weak_odr constant
+// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant
namespace std {
struct A { A(); };
- // CHECK: define void @_ZNSt1AC1Ev
- // CHECK: define void @_ZNSt1AC2Ev
+ // CHECK: define void @_ZNSt1AC1Ev(%"struct.N::std::A"* %this) unnamed_addr
+ // CHECK: define void @_ZNSt1AC2Ev(%"struct.N::std::A"* %this) unnamed_addr
A::A() { }
};
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
index 6a29944..463f15d 100644
--- a/test/CodeGenCXX/mangle-template.cpp
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -82,7 +82,7 @@ namespace test7 {
X(U*, typename int_c<(meta<T>::value + meta<U>::value)>::type *) { }
};
- // CHECK: define weak_odr void @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsrNS6_IS3_EE5valueEE4typeE
+ // CHECK: define weak_odr void @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsrNS6_IS3_EE5valueEE4typeE(%"class.test1::T"* %this, double*, float*) unnamed_addr
template X<int>::X(double*, float*);
}
diff --git a/test/CodeGenCXX/mangle-unnamed.cpp b/test/CodeGenCXX/mangle-unnamed.cpp
index 83b46d6..53f381c 100644
--- a/test/CodeGenCXX/mangle-unnamed.cpp
+++ b/test/CodeGenCXX/mangle-unnamed.cpp
@@ -69,3 +69,24 @@ int f7() {
// CHECK: _ZZ2f7vE1a
return a.b;
}
+
+// This used to cause an assert because the typedef-for-anonymous-tag
+// code was trying to claim the enum for the template.
+enum { T8 };
+template <class T> struct Test8 {
+ typedef T type;
+ Test8(type t) {} // tested later
+};
+template <class T> void make_test8(T value) { Test8<T> t(value); }
+void test8() { make_test8(T8); }
+
+// CHECK: define internal void @"_ZNV3$_35test9Ev"(
+typedef volatile struct {
+ void test9() volatile {}
+} Test9;
+void test9() {
+ Test9 a;
+ a.test9();
+}
+
+// CHECK: define internal void @"_ZN5Test8I3$_2EC1ES0_"(
diff --git a/test/CodeGenCXX/mangle-variadic-templates.cpp b/test/CodeGenCXX/mangle-variadic-templates.cpp
new file mode 100644
index 0000000..a987b49
--- /dev/null
+++ b/test/CodeGenCXX/mangle-variadic-templates.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++0x -emit-llvm -triple=x86_64-apple-darwin9 -o - %s | FileCheck %s
+
+template<unsigned I, typename ...Types>
+struct X { };
+
+template<typename T> struct identity { };
+template<typename T> struct add_reference;
+template<typename ...Types> struct tuple { };
+template<int ...Values> struct int_tuple { };
+template<template<typename> class ...Templates> struct template_tuple { };
+
+// CHECK: define weak_odr void @_Z2f0IJEEv1XIXsZT_EJDpRT_EE
+template<typename ...Types>
+void f0(X<sizeof...(Types), Types&...>) { }
+
+template void f0(X<0>);
+
+// CHECK: define weak_odr void @_Z2f0IJifdEEv1XIXsZT_EJDpRT_EE
+template void f0<int, float, double>(X<3, int&, float&, double&>);
+
+// Mangling for template argument packs
+template<typename ...Types> void f1() {}
+// CHECK: define weak_odr void @_Z2f1IJEEvv
+template void f1<>();
+// CHECK: define weak_odr void @_Z2f1IJiEEvv
+template void f1<int>();
+// CHECK: define weak_odr void @_Z2f1IJifEEvv
+template void f1<int, float>();
+
+// Mangling function parameter packs
+template<typename ...Types> void f2(Types...) {}
+// CHECK: define weak_odr void @_Z2f2IJEEvDpT_
+template void f2<>();
+// CHECK: define weak_odr void @_Z2f2IJiEEvDpT_
+template void f2<int>(int);
+// CHECK: define weak_odr void @_Z2f2IJifEEvDpT_
+template void f2<int, float>(int, float);
+
+// Mangling non-trivial function parameter packs
+template<typename ...Types> void f3(const Types *...) {}
+// CHECK: define weak_odr void @_Z2f3IJEEvDpPKT_
+template void f3<>();
+// CHECK: define weak_odr void @_Z2f3IJiEEvDpPKT_
+template void f3<int>(const int*);
+// CHECK: define weak_odr void @_Z2f3IJifEEvDpPKT_
+template void f3<int, float>(const int*, const float*);
+
+// Mangling of type pack expansions in a template argument
+template<typename ...Types> tuple<Types...> f4() {}
+// CHECK: define weak_odr void @_Z2f4IJifdEE5tupleIJDpT_EEv
+template tuple<int, float, double> f4();
+
+// Mangling of type pack expansions in a function type
+template<typename R, typename ...ArgTypes> identity<R(ArgTypes...)> f5() {}
+// CHECK: define weak_odr void @_Z2f5IiJifdEE8identityIFT_DpT0_EEv
+template identity<int(int, float, double)> f5();
+
+// Mangling of non-type template argument expansions
+template<int ...Values> int_tuple<Values...> f6() {}
+// CHECK: define weak_odr void @_Z2f6IJLi1ELi2ELi3EEE9int_tupleIJXspT_EEEv
+template int_tuple<1, 2, 3> f6();
+
+// Mangling of template template argument expansions
+template<template<typename> class ...Templates>
+template_tuple<Templates...> f7() {}
+// CHECK: define weak_odr void @_Z2f7IJ8identity13add_referenceEE14template_tupleIJDpT_EEv
+template template_tuple<identity, add_reference> f7();
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 55357c7..ec496fe 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -624,3 +624,26 @@ namespace test20 {
template <class T> void test1(decltype(f<>(T()))) {}
template void test1<int>(decltype(f<>(int())));
}
+
+// rdar:// 8620510
+namespace test21 {
+ // CHECK: define void @_ZN6test2112vla_arg_funcEiPA_i(
+ void vla_arg_func(int X, int a[X][X]) {}
+}
+
+namespace test22 {
+ // CHECK: define void @_ZN6test221fEDn(
+ void f(decltype(nullptr)) { }
+}
+
+// rdar://problem/8913416
+namespace test23 {
+ typedef void * const vpc;
+
+ // CHECK: define void @_ZN6test231fERA10_KPv(
+ void f(vpc (&)[10]) {}
+
+ typedef vpc vpca5[5];
+ void f(vpca5 volatile (&)[10]) {}
+ // CHECK: define void @_ZN6test231fERA10_A5_VKPv(
+}
diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp
index a60d24a..b95763c 100644
--- a/test/CodeGenCXX/member-functions.cpp
+++ b/test/CodeGenCXX/member-functions.cpp
@@ -20,9 +20,9 @@ void test1() {
struct S {
- // RUN: grep "define linkonce_odr void @_ZN1SC1Ev" %t
+ // RUN: grep "define linkonce_odr void @_ZN1SC1Ev.*unnamed_addr" %t
inline S() { }
- // RUN: grep "define linkonce_odr void @_ZN1SC1Ev" %t
+ // RUN: grep "define linkonce_odr void @_ZN1SC1Ev.*unnamed_addr" %t
inline ~S() { }
diff --git a/test/CodeGenCXX/member-init-assignment.cpp b/test/CodeGenCXX/member-init-assignment.cpp
index 57ab7eb..128cb88 100644
--- a/test/CodeGenCXX/member-init-assignment.cpp
+++ b/test/CodeGenCXX/member-init-assignment.cpp
@@ -10,7 +10,7 @@ struct Foo {
Foo::Foo(unsigned arg) : file_id(arg = 42)
{ }
-// CHECK: define void @_ZN3FooC2Ej
+// CHECK: define void @_ZN3FooC2Ej(%struct.Foo* %this, i32 %arg) unnamed_addr
// CHECK: [[ARG:%.*]] = alloca i32
// CHECK: store i32 42, i32* [[ARG]]
// CHECK: store i32 42, i32* %{{.*}}
diff --git a/test/CodeGenCXX/member-pointer-type-convert.cpp b/test/CodeGenCXX/member-pointer-type-convert.cpp
index 16c1469..2970a2e 100644
--- a/test/CodeGenCXX/member-pointer-type-convert.cpp
+++ b/test/CodeGenCXX/member-pointer-type-convert.cpp
@@ -6,5 +6,6 @@ struct {
const char *name;
param_t par;
} *ptr;
+void test_ptr() { (void) ptr; } // forced use
// CHECK: type { i8*, {{i..}} }
diff --git a/test/CodeGenCXX/member-templates.cpp b/test/CodeGenCXX/member-templates.cpp
index bcf1187..7e4bdca 100644
--- a/test/CodeGenCXX/member-templates.cpp
+++ b/test/CodeGenCXX/member-templates.cpp
@@ -15,8 +15,8 @@ struct B {
template<typename T> B::B(T) {}
-// CHECK: define weak_odr void @_ZN1BC1IiEET_(%struct.B* %this, i32)
-// CHECK: define weak_odr void @_ZN1BC2IiEET_(%struct.B* %this, i32)
+// CHECK: define weak_odr void @_ZN1BC1IiEET_(%struct.B* %this, i32) unnamed_addr
+// CHECK: define weak_odr void @_ZN1BC2IiEET_(%struct.B* %this, i32) unnamed_addr
template B::B(int);
template<typename T>
diff --git a/test/CodeGenCXX/nrvo-noreturn.cc b/test/CodeGenCXX/nrvo-noreturn.cc
new file mode 100644
index 0000000..a8259ca
--- /dev/null
+++ b/test/CodeGenCXX/nrvo-noreturn.cc
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+// PR9178
+
+void abort() __attribute__((__noreturn__));
+struct CoinModelLink {
+ CoinModelLink();
+ ~CoinModelLink();
+};
+class CoinModel {
+ CoinModelLink firstInQuadraticColumn();
+};
+CoinModelLink CoinModel::firstInQuadraticColumn() {
+ abort();
+ CoinModelLink x;
+ return x;
+}
+
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index 8d19b1e..d03b21bac 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -131,3 +131,18 @@ X test4(bool B) {
// CHECK: tail call void @exit(i32 1)
exit(1);
}
+
+#ifdef __EXCEPTIONS
+// CHECK-EH: define void @_Z5test5
+void may_throw();
+X test5() {
+ try {
+ may_throw();
+ } catch (X x) {
+ // CHECK-EH: invoke void @_ZN1XC1ERKS_
+ // CHECK-EH: call void @__cxa_end_catch()
+ // CHECK-EH: ret void
+ return x;
+ }
+}
+#endif
diff --git a/test/CodeGenCXX/nullptr.cpp b/test/CodeGenCXX/nullptr.cpp
index ab63b43..1ea23ec 100644
--- a/test/CodeGenCXX/nullptr.cpp
+++ b/test/CodeGenCXX/nullptr.cpp
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -I%S -emit-llvm -o - %s | FileCheck %s
+#include <typeinfo>
+
+// CHECK: @_ZTIDn = external constant i8*
int* a = nullptr;
void f() {
@@ -15,3 +18,7 @@ void g() {
// CHECK: call i8* @_Z11get_nullptrv()
int (X::*pmf)(int) = get_nullptr();
}
+
+const std::type_info& f2() {
+ return typeid(nullptr_t);
+}
diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp
index 38c7d28..40723a8 100644
--- a/test/CodeGenCXX/pointers-to-data-members.cpp
+++ b/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -1,40 +1,47 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s
-// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 -O3 | FileCheck --check-prefix=CHECK-O3 %s
+// RUN: %clang_cc1 %s -emit-llvm -o %t.ll -triple=x86_64-apple-darwin10
+// RUN: FileCheck %s < %t.ll
+// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s < %t.ll
+// RUN: %clang_cc1 %s -emit-llvm -o %t-opt.ll -triple=x86_64-apple-darwin10 -O3
+// RUN: FileCheck --check-prefix=CHECK-O3 %s < %t-opt.ll
+
struct A { int a; int b; };
struct B { int b; };
struct C : B, A { };
// Zero init.
namespace ZeroInit {
- // CHECK: @_ZN8ZeroInit1aE = global i64 -1
+ // CHECK-GLOBAL: @_ZN8ZeroInit1aE = global i64 -1
int A::* a;
- // CHECK: @_ZN8ZeroInit2aaE = global [2 x i64] [i64 -1, i64 -1]
+ // CHECK-GLOBAL: @_ZN8ZeroInit2aaE = global [2 x i64] [i64 -1, i64 -1]
int A::* aa[2];
- // CHECK: @_ZN8ZeroInit3aaaE = global [2 x [2 x i64]] {{\[}}[2 x i64] [i64 -1, i64 -1], [2 x i64] [i64 -1, i64 -1]]
+ // CHECK-GLOBAL: @_ZN8ZeroInit3aaaE = global [2 x [2 x i64]] {{\[}}[2 x i64] [i64 -1, i64 -1], [2 x i64] [i64 -1, i64 -1]]
int A::* aaa[2][2];
- // CHECK: @_ZN8ZeroInit1bE = global i64 -1,
+ // CHECK-GLOBAL: @_ZN8ZeroInit1bE = global i64 -1,
int A::* b = 0;
- // CHECK: @_ZN8ZeroInit2saE = global %struct.anon { i64 -1 }
+ // CHECK-GLOBAL: @_ZN8ZeroInit2saE = internal global %struct.anon { i64 -1 }
struct {
int A::*a;
} sa;
+ void test_sa() { (void) sa; } // force emission
- // CHECK: @_ZN8ZeroInit3ssaE =
- // CHECK: [2 x i64] [i64 -1, i64 -1]
+ // CHECK-GLOBAL: @_ZN8ZeroInit3ssaE = internal
+ // CHECK-GLOBAL: [2 x i64] [i64 -1, i64 -1]
struct {
int A::*aa[2];
} ssa[2];
+ void test_ssa() { (void) ssa; }
- // CHECK: @_ZN8ZeroInit2ssE = global %1 { %struct.anon { i64 -1 } }
+ // CHECK-GLOBAL: @_ZN8ZeroInit2ssE = internal global %1 { %struct.anon { i64 -1 } }
struct {
struct {
int A::*pa;
} s;
} ss;
+ void test_ss() { (void) ss; }
struct A {
int A::*a;
@@ -48,13 +55,13 @@ namespace ZeroInit {
};
struct C : A, B { int j; };
- // CHECK: @_ZN8ZeroInit1cE = global %"struct.ZeroInit::C" { [16 x i8] c"\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00", [176 x i8] c"\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF", i32 0, [4 x i8] zeroinitializer }
+ // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} { [16 x i8] c"\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00", [176 x i8] c"\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF", i32 0, [4 x i8] zeroinitializer }
C c;
}
// PR5674
namespace PR5674 {
- // CHECK: @_ZN6PR56742pbE = global i64 4
+ // CHECK-GLOBAL: @_ZN6PR56742pbE = global i64 4
int A::*pb = &A::b;
}
@@ -117,7 +124,7 @@ struct A {
A();
};
-// CHECK: define void @_ZN9ValueInit1AC2Ev
+// CHECK: define void @_ZN9ValueInit1AC2Ev(%"struct.ValueInit::A"* %this) unnamed_addr
// CHECK: store i64 -1, i64*
// CHECK: ret void
A::A() : a() {}
@@ -165,15 +172,15 @@ struct A {
int A::*i;
};
-// FIXME: A::i should be initialized to -1 here.
+// CHECK-GLOBAL: @_ZN12VirtualBases1bE = global {{%.*}} { i32 (...)** null, [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF" }
struct B : virtual A { };
B b;
-// FIXME: A::i should be initialized to -1 here.
+// CHECK-GLOBAL: @_ZN12VirtualBases1cE = global {{%.*}} { i32 (...)** null, i64 -1, [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF" }
struct C : virtual A { int A::*i; };
C c;
-// FIXME: C::A::i should be initialized to -1 here.
+ // CHECK-GLOBAL: @_ZN12VirtualBases1dE = global {{%.*}} { [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF", i64 -1, [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF" }
struct D : C { int A::*i; };
D d;
@@ -203,3 +210,23 @@ namespace BoolPtrToMember {
return x.*member;
}
}
+
+namespace PR8507 {
+
+struct S;
+void f(S* p, double S::*pm) {
+ if (0 < p->*pm) {
+ }
+}
+
+}
+
+namespace test4 {
+ struct A { int A_i; };
+ struct B : virtual A { int A::*B_p; };
+ struct C : virtual B { int *C_p; };
+ struct D : C { int *D_p; };
+
+ // CHECK-GLOBAL: @_ZN5test41dE = global {{%.*}} { [16 x i8] zeroinitializer, i32* null, [16 x i8] c"\00\00\00\00\00\00\00\00\FF\FF\FF\FF\FF\FF\FF\FF", [4 x i8] zeroinitializer }
+ D d;
+}
diff --git a/test/CodeGenCXX/pr9130.cpp b/test/CodeGenCXX/pr9130.cpp
new file mode 100644
index 0000000..b28f394
--- /dev/null
+++ b/test/CodeGenCXX/pr9130.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+class nsOggCodecState {
+ virtual int StartTime() {
+ return -1;
+ }
+};
+class nsVorbisState : public nsOggCodecState {
+ virtual ~nsVorbisState();
+};
+nsVorbisState::~nsVorbisState() {
+}
+
+// CHECK: define linkonce_odr i32 @_ZN15nsOggCodecState9StartTimeEv
diff --git a/test/CodeGenCXX/pragma-pack.cpp b/test/CodeGenCXX/pragma-pack.cpp
new file mode 100644
index 0000000..c0ddb1d
--- /dev/null
+++ b/test/CodeGenCXX/pragma-pack.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Base {
+ virtual ~Base();
+ int x;
+};
+
+#pragma pack(1)
+struct Sub : virtual Base {
+ char c;
+};
+
+// CHECK: %struct.Sub = type <{ i32 (...)**, i8, [8 x i8] }>
+void f(Sub*) { }
diff --git a/test/CodeGenCXX/pragma-visibility.cpp b/test/CodeGenCXX/pragma-visibility.cpp
index 05de786..2dc8bcc 100644
--- a/test/CodeGenCXX/pragma-visibility.cpp
+++ b/test/CodeGenCXX/pragma-visibility.cpp
@@ -63,10 +63,12 @@ namespace n __attribute((visibility("default"))) {
#pragma GCC visibility pop
}
+// We used to test this, but it's insane, so unless it happens in
+// headers, we should not support it.
namespace n __attribute((visibility("hidden"))) {
extern int foofoo; // FIXME: Shouldn't be necessary, but otherwise the pragma
// gets to Sema before the namespace!
#pragma GCC visibility pop
void h() {}
- // CHECK: define void @_ZN1n1hEv
+ // CHECK disabled: define void @_ZN1n1hEv
}
diff --git a/test/CodeGenCXX/predefined-expr.cpp b/test/CodeGenCXX/predefined-expr.cpp
index f5e5ca9..56270b5 100644
--- a/test/CodeGenCXX/predefined-expr.cpp
+++ b/test/CodeGenCXX/predefined-expr.cpp
@@ -1,82 +1,82 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
-// CHECK: private constant [15 x i8] c"externFunction\00"
-// CHECK: private constant [26 x i8] c"void NS::externFunction()\00"
+// CHECK: private unnamed_addr constant [15 x i8] c"externFunction\00"
+// CHECK: private unnamed_addr constant [26 x i8] c"void NS::externFunction()\00"
-// CHECK: private constant [22 x i8] c"classTemplateFunction\00"
-// CHECK: private constant [60 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction()\00"
-// CHECK: private constant [53 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction()\00"
+// CHECK: private unnamed_addr constant [22 x i8] c"classTemplateFunction\00"
+// CHECK: private unnamed_addr constant [60 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction()\00"
+// CHECK: private unnamed_addr constant [53 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction()\00"
-// CHECK: private constant [18 x i8] c"functionTemplate1\00"
-// CHECK: private constant [45 x i8] c"void NS::Base::functionTemplate1(NS::Base *)\00"
-// CHECK: private constant [38 x i8] c"void NS::Base::functionTemplate1(int)\00"
+// CHECK: private unnamed_addr constant [18 x i8] c"functionTemplate1\00"
+// CHECK: private unnamed_addr constant [45 x i8] c"void NS::Base::functionTemplate1(NS::Base *)\00"
+// CHECK: private unnamed_addr constant [38 x i8] c"void NS::Base::functionTemplate1(int)\00"
-// CHECK: private constant [23 x i8] c"anonymousUnionFunction\00"
-// CHECK: private constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous union>::anonymousUnionFunction()\00"
+// CHECK: private unnamed_addr constant [23 x i8] c"anonymousUnionFunction\00"
+// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous union>::anonymousUnionFunction()\00"
-// CHECK: private constant [24 x i8] c"anonymousStructFunction\00"
-// CHECK: private constant [85 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous struct>::anonymousStructFunction()\00"
+// CHECK: private unnamed_addr constant [24 x i8] c"anonymousStructFunction\00"
+// CHECK: private unnamed_addr constant [85 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous struct>::anonymousStructFunction()\00"
-// CHECK: private constant [23 x i8] c"anonymousClassFunction\00"
-// CHECK: private constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous class>::anonymousClassFunction()\00"
+// CHECK: private unnamed_addr constant [23 x i8] c"anonymousClassFunction\00"
+// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous class>::anonymousClassFunction()\00"
-// CHECK: private constant [12 x i8] c"~Destructor\00"
-// CHECK: private constant [30 x i8] c"NS::Destructor::~Destructor()\00"
+// CHECK: private unnamed_addr constant [12 x i8] c"~Destructor\00"
+// CHECK: private unnamed_addr constant [30 x i8] c"NS::Destructor::~Destructor()\00"
-// CHECK: private constant [12 x i8] c"Constructor\00"
-// CHECK: private constant [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00"
-// CHECK: private constant [34 x i8] c"NS::Constructor::Constructor(int)\00"
-// CHECK: private constant [31 x i8] c"NS::Constructor::Constructor()\00"
+// CHECK: private unnamed_addr constant [12 x i8] c"Constructor\00"
+// CHECK: private unnamed_addr constant [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00"
+// CHECK: private unnamed_addr constant [34 x i8] c"NS::Constructor::Constructor(int)\00"
+// CHECK: private unnamed_addr constant [31 x i8] c"NS::Constructor::Constructor()\00"
-// CHECK: private constant [16 x i8] c"virtualFunction\00"
-// CHECK: private constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00"
+// CHECK: private unnamed_addr constant [16 x i8] c"virtualFunction\00"
+// CHECK: private unnamed_addr constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00"
-// CHECK: private constant [22 x i8] c"constVolatileFunction\00"
-// CHECK: private constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00"
+// CHECK: private unnamed_addr constant [22 x i8] c"constVolatileFunction\00"
+// CHECK: private unnamed_addr constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00"
-// CHECK: private constant [17 x i8] c"volatileFunction\00"
-// CHECK: private constant [43 x i8] c"void NS::Base::volatileFunction() volatile\00"
+// CHECK: private unnamed_addr constant [17 x i8] c"volatileFunction\00"
+// CHECK: private unnamed_addr constant [43 x i8] c"void NS::Base::volatileFunction() volatile\00"
-// CHECK: private constant [14 x i8] c"constFunction\00"
-// CHECK: private constant [37 x i8] c"void NS::Base::constFunction() const\00"
+// CHECK: private unnamed_addr constant [14 x i8] c"constFunction\00"
+// CHECK: private unnamed_addr constant [37 x i8] c"void NS::Base::constFunction() const\00"
-// CHECK: private constant [26 x i8] c"functionReturingTemplate2\00"
-// CHECK: private constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00"
+// CHECK: private unnamed_addr constant [26 x i8] c"functionReturingTemplate2\00"
+// CHECK: private unnamed_addr constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00"
-// CHECK: private constant [26 x i8] c"functionReturingTemplate1\00"
-// CHECK: private constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00"
+// CHECK: private unnamed_addr constant [26 x i8] c"functionReturingTemplate1\00"
+// CHECK: private unnamed_addr constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00"
-// CHECK: private constant [23 x i8] c"withTemplateParameter2\00"
-// CHECK: private constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00"
+// CHECK: private unnamed_addr constant [23 x i8] c"withTemplateParameter2\00"
+// CHECK: private unnamed_addr constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00"
-// CHECK: private constant [23 x i8] c"withTemplateParameter1\00"
-// CHECK: private constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00"
+// CHECK: private unnamed_addr constant [23 x i8] c"withTemplateParameter1\00"
+// CHECK: private unnamed_addr constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00"
-// CHECK: private constant [23 x i8] c"functionReturningClass\00"
-// CHECK: private constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00"
+// CHECK: private unnamed_addr constant [23 x i8] c"functionReturningClass\00"
+// CHECK: private unnamed_addr constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00"
-// CHECK: private constant [23 x i8] c"functionWithParameters\00"
-// CHECK: private constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00"
+// CHECK: private unnamed_addr constant [23 x i8] c"functionWithParameters\00"
+// CHECK: private unnamed_addr constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00"
-// CHECK: private constant [17 x i8] c"variadicFunction\00"
-// CHECK: private constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00"
+// CHECK: private unnamed_addr constant [17 x i8] c"variadicFunction\00"
+// CHECK: private unnamed_addr constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00"
-// CHECK: private constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00"
+// CHECK: private unnamed_addr constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00"
-// CHECK: private constant [15 x i8] c"inlineFunction\00"
-// CHECK: private constant [32 x i8] c"void NS::Base::inlineFunction()\00"
+// CHECK: private unnamed_addr constant [15 x i8] c"inlineFunction\00"
+// CHECK: private unnamed_addr constant [32 x i8] c"void NS::Base::inlineFunction()\00"
-// CHECK: private constant [15 x i8] c"staticFunction\00"
-// CHECK: private constant [39 x i8] c"static void NS::Base::staticFunction()\00"
+// CHECK: private unnamed_addr constant [15 x i8] c"staticFunction\00"
+// CHECK: private unnamed_addr constant [39 x i8] c"static void NS::Base::staticFunction()\00"
-// CHECK: private constant [26 x i8] c"topLevelNamespaceFunction\00"
-// CHECK: private constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
+// CHECK: private unnamed_addr constant [26 x i8] c"topLevelNamespaceFunction\00"
+// CHECK: private unnamed_addr constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
-// CHECK: private constant [27 x i8] c"anonymousNamespaceFunction\00"
-// CHECK: private constant [84 x i8] c"void <anonymous namespace>::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00"
+// CHECK: private unnamed_addr constant [27 x i8] c"anonymousNamespaceFunction\00"
+// CHECK: private unnamed_addr constant [84 x i8] c"void <anonymous namespace>::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00"
-// CHECK: private constant [19 x i8] c"localClassFunction\00"
-// CHECK: private constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00"
+// CHECK: private unnamed_addr constant [19 x i8] c"localClassFunction\00"
+// CHECK: private unnamed_addr constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00"
int printf(const char * _Format, ...);
diff --git a/test/CodeGenCXX/ptr-to-member-function.cpp b/test/CodeGenCXX/ptr-to-member-function.cpp
index e3912fe..89db142 100644
--- a/test/CodeGenCXX/ptr-to-member-function.cpp
+++ b/test/CodeGenCXX/ptr-to-member-function.cpp
@@ -66,5 +66,5 @@ int main()
// CHECK-LP64: callq __ZN1XcvM1BFvvEEv
// CHECK-LP64: callq __Z1gM1CFvvE
-// CHECK-LP32: call L__ZN1XcvM1BFvvEEv
-// CHECK-LP32: call __Z1gM1CFvvE
+// CHECK-LP32: calll L__ZN1XcvM1BFvvEEv
+// CHECK-LP32: calll __Z1gM1CFvvE
diff --git a/test/CodeGenCXX/rtti-fundamental.cpp b/test/CodeGenCXX/rtti-fundamental.cpp
index 7f80d99..2495e96 100644
--- a/test/CodeGenCXX/rtti-fundamental.cpp
+++ b/test/CodeGenCXX/rtti-fundamental.cpp
@@ -14,60 +14,103 @@ namespace __cxxabiv1 {
__fundamental_type_info::~__fundamental_type_info() { }
}
-// CHECK: @_ZTIv = constant
-// CHECK: @_ZTIPv = constant
-// CHECK: @_ZTIPKv = constant
-// CHECK: @_ZTIDi = constant
-// CHECK: @_ZTIPDi = constant
-// CHECK: @_ZTIPKDi = constant
-// CHECK: @_ZTIDs = constant
-// CHECK: @_ZTIPDs = constant
-// CHECK: @_ZTIPKDs = constant
-// CHECK: @_ZTIy = constant
-// CHECK: @_ZTIPy = constant
-// CHECK: @_ZTIPKy = constant
-// CHECK: @_ZTIx = constant
-// CHECK: @_ZTIPx = constant
-// CHECK: @_ZTIPKx = constant
-// CHECK: @_ZTIw = constant
-// CHECK: @_ZTIPw = constant
-// CHECK: @_ZTIPKw = constant
-// CHECK: @_ZTIt = constant
-// CHECK: @_ZTIPt = constant
-// CHECK: @_ZTIPKt = constant
-// CHECK: @_ZTIs = constant
-// CHECK: @_ZTIPs = constant
-// CHECK: @_ZTIPKs = constant
-// CHECK: @_ZTIm = constant
-// CHECK: @_ZTIPm = constant
-// CHECK: @_ZTIPKm = constant
-// CHECK: @_ZTIl = constant
-// CHECK: @_ZTIPl = constant
-// CHECK: @_ZTIPKl = constant
-// CHECK: @_ZTIj = constant
-// CHECK: @_ZTIPj = constant
-// CHECK: @_ZTIPKj = constant
-// CHECK: @_ZTIi = constant
-// CHECK: @_ZTIPi = constant
-// CHECK: @_ZTIPKi = constant
-// CHECK: @_ZTIh = constant
-// CHECK: @_ZTIPh = constant
-// CHECK: @_ZTIPKh = constant
-// CHECK: @_ZTIf = constant
-// CHECK: @_ZTIPf = constant
-// CHECK: @_ZTIPKf = constant
-// CHECK: @_ZTIe = constant
-// CHECK: @_ZTIPe = constant
-// CHECK: @_ZTIPKe = constant
-// CHECK: @_ZTId = constant
-// CHECK: @_ZTIPd = constant
-// CHECK: @_ZTIPKd = constant
-// CHECK: @_ZTIc = constant
-// CHECK: @_ZTIPc = constant
-// CHECK: @_ZTIPKc = constant
-// CHECK: @_ZTIb = constant
-// CHECK: @_ZTIPb = constant
-// CHECK: @_ZTIPKb = constant
-// CHECK: @_ZTIa = constant
-// CHECK: @_ZTIPa = constant
-// CHECK: @_ZTIPKa = constant
+// void
+// CHECK: @_ZTIv = unnamed_addr constant
+// CHECK: @_ZTIPv = unnamed_addr constant
+// CHECK: @_ZTIPKv = unnamed_addr constant
+
+// std::nullptr_t
+// CHECK: @_ZTIDn = unnamed_addr constant
+// CHECK: @_ZTIPDn = unnamed_addr constant
+// CHECK: @_ZTIPKDn = unnamed_addr constant
+
+// bool
+// CHECK: @_ZTIb = unnamed_addr constant
+// CHECK: @_ZTIPb = unnamed_addr constant
+// CHECK: @_ZTIPKb = unnamed_addr constant
+
+// wchar_t
+// CHECK: @_ZTIw = unnamed_addr constant
+// CHECK: @_ZTIPw = unnamed_addr constant
+// CHECK: @_ZTIPKw = unnamed_addr constant
+
+// char
+// CHECK: @_ZTIc = unnamed_addr constant
+// CHECK: @_ZTIPc = unnamed_addr constant
+// CHECK: @_ZTIPKc = unnamed_addr constant
+
+// unsigned char
+// CHECK: @_ZTIh = unnamed_addr constant
+// CHECK: @_ZTIPh = unnamed_addr constant
+// CHECK: @_ZTIPKh = unnamed_addr constant
+
+// signed char
+// CHECK: @_ZTIa = unnamed_addr constant
+// CHECK: @_ZTIPa = unnamed_addr constant
+// CHECK: @_ZTIPKa = unnamed_addr constant
+
+// short
+// CHECK: @_ZTIs = unnamed_addr constant
+// CHECK: @_ZTIPs = unnamed_addr constant
+// CHECK: @_ZTIPKs = unnamed_addr constant
+
+// unsigned short
+// CHECK: @_ZTIt = unnamed_addr constant
+// CHECK: @_ZTIPt = unnamed_addr constant
+// CHECK: @_ZTIPKt = unnamed_addr constant
+
+// int
+// CHECK: @_ZTIi = unnamed_addr constant
+// CHECK: @_ZTIPi = unnamed_addr constant
+// CHECK: @_ZTIPKi = unnamed_addr constant
+
+// unsigned int
+// CHECK: @_ZTIj = unnamed_addr constant
+// CHECK: @_ZTIPj = unnamed_addr constant
+// CHECK: @_ZTIPKj = unnamed_addr constant
+
+// long
+// CHECK: @_ZTIl = unnamed_addr constant
+// CHECK: @_ZTIPl = unnamed_addr constant
+// CHECK: @_ZTIPKl = unnamed_addr constant
+
+// unsigned long
+// CHECK: @_ZTIm = unnamed_addr constant
+// CHECK: @_ZTIPm = unnamed_addr constant
+// CHECK: @_ZTIPKm = unnamed_addr constant
+
+// long long
+// CHECK: @_ZTIx = unnamed_addr constant
+// CHECK: @_ZTIPx = unnamed_addr constant
+// CHECK: @_ZTIPKx = unnamed_addr constant
+
+// unsigned long long
+// CHECK: @_ZTIy = unnamed_addr constant
+// CHECK: @_ZTIPy = unnamed_addr constant
+// CHECK: @_ZTIPKy = unnamed_addr constant
+
+// float
+// CHECK: @_ZTIf = unnamed_addr constant
+// CHECK: @_ZTIPf = unnamed_addr constant
+// CHECK: @_ZTIPKf = unnamed_addr constant
+
+// double
+// CHECK: @_ZTId = unnamed_addr constant
+// CHECK: @_ZTIPd = unnamed_addr constant
+// CHECK: @_ZTIPKd = unnamed_addr constant
+
+// long double
+// CHECK: @_ZTIe = unnamed_addr constant
+// CHECK: @_ZTIPe = unnamed_addr constant
+// CHECK: @_ZTIPKe = unnamed_addr constant
+
+// char16_t
+// CHECK: @_ZTIDs = unnamed_addr constant
+// CHECK: @_ZTIPDs = unnamed_addr constant
+// CHECK: @_ZTIPKDs = unnamed_addr constant
+
+// char32_t
+// CHECK: @_ZTIDi = unnamed_addr constant
+// CHECK: @_ZTIPDi = unnamed_addr constant
+// CHECK: @_ZTIPKDi = unnamed_addr constant
+
diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp
index efa336d..42fe435 100644
--- a/test/CodeGenCXX/rtti-linkage.cpp
+++ b/test/CodeGenCXX/rtti-linkage.cpp
@@ -1,60 +1,60 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o - | sort | FileCheck %s
-
-// FIXME: Fails on Win32, dunno why.
-// XFAIL: win32
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fvisibility hidden -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITH-HIDDEN %s
#include <typeinfo>
+// CHECK-WITH-HIDDEN: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
+// CHECK-WITH-HIDDEN: @_ZTSPK2T4 = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTS2T4 = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTI2T4 = linkonce_odr hidden unnamed_addr constant
+// CHECK-WITH-HIDDEN: @_ZTIPK2T4 = linkonce_odr hidden unnamed_addr constant
-
-// CHECK: _ZTIN12_GLOBAL__N_11DE to
-
-
-
-// CHECK: _ZTI1A = weak_odr hidden constant
-// CHECK: _ZTI1B = constant
-// CHECK: _ZTI1C = internal constant
-// CHECK: _ZTI1TILj0EE = weak_odr constant
-// CHECK: _ZTI1TILj1EE = weak_odr constant
-// CHECK: _ZTI1TILj2EE = external constant
-// CHECK: _ZTIA10_i = weak_odr hidden constant
-// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal constant
-// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal constant
-// CHECK: _ZTIFvvE = weak_odr hidden constant
-// CHECK: _ZTIM1A1C = internal constant
-// CHECK: _ZTIM1AP1C = internal constant
-// CHECK: _ZTIM1CPS_ = internal constant
-// CHECK: _ZTIM1CS_ = internal constant
-// CHECK: _ZTIM1Ci = internal constant
-// CHECK: _ZTIN12_GLOBAL__N_11DE = internal constant
-// CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
-// CHECK: _ZTIP1C = internal constant
-// CHECK: _ZTIPFvvE = weak_odr hidden constant
-// CHECK: _ZTIPM1Ci = internal constant
-// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal constant
-// CHECK: _ZTIPP1C = internal constant
-// CHECK: _ZTS1A = weak_odr constant
-// CHECK: _ZTS1B = constant
+// CHECK: _ZTSP1C = internal constant
// CHECK: _ZTS1C = internal constant
-// CHECK: _ZTS1F = weak_odr constant
-// CHECK: _ZTSA10_i = weak_odr constant
-// CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
-// CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
-// CHECK: _ZTSFvvE = weak_odr constant
+// CHECK: _ZTI1C = internal unnamed_addr constant
+// CHECK: _ZTIP1C = internal unnamed_addr constant
+// CHECK: _ZTSPP1C = internal constant
+// CHECK: _ZTIPP1C = internal unnamed_addr constant
+// CHECK: _ZTSM1Ci = internal constant
+// CHECK: _ZTIM1Ci = internal unnamed_addr constant
+// CHECK: _ZTSPM1Ci = internal constant
+// CHECK: _ZTIPM1Ci = internal unnamed_addr constant
+// CHECK: _ZTSM1CS_ = internal constant
+// CHECK: _ZTIM1CS_ = internal unnamed_addr constant
+// CHECK: _ZTSM1CPS_ = internal constant
+// CHECK: _ZTIM1CPS_ = internal unnamed_addr constant
// CHECK: _ZTSM1A1C = internal constant
+// CHECK: _ZTS1A = linkonce_odr constant
+// CHECK: _ZTI1A = linkonce_odr hidden unnamed_addr constant
+// CHECK: _ZTIM1A1C = internal unnamed_addr constant
// CHECK: _ZTSM1AP1C = internal constant
-// CHECK: _ZTSM1CPS_ = internal constant
-// CHECK: _ZTSM1CS_ = internal constant
-// CHECK: _ZTSM1Ci = internal constant
+// CHECK: _ZTIM1AP1C = internal unnamed_addr constant
// CHECK: _ZTSN12_GLOBAL__N_11DE = internal constant
-// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
-// CHECK: _ZTSP1C = internal constant
-// CHECK: _ZTSPFvvE = weak_odr constant
-// CHECK: _ZTSPM1Ci = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_11DE = internal unnamed_addr constant
// CHECK: _ZTSPN12_GLOBAL__N_11DE = internal constant
-// CHECK: _ZTSPP1C = internal constant
+// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal unnamed_addr constant
+// CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
+// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal unnamed_addr constant
+// CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
+// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal unnamed_addr constant
+// CHECK: _ZTSPFvvE = linkonce_odr constant
+// CHECK: _ZTSFvvE = linkonce_odr constant
+// CHECK: _ZTIFvvE = linkonce_odr hidden unnamed_addr constant
+// CHECK: _ZTIPFvvE = linkonce_odr hidden unnamed_addr constant
+// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_11EE = internal unnamed_addr constant
+// CHECK: _ZTSA10_i = linkonce_odr constant
+// CHECK: _ZTIA10_i = linkonce_odr hidden unnamed_addr constant
+// CHECK: _ZTI1TILj0EE = linkonce_odr unnamed_addr constant
+// CHECK: _ZTI1TILj1EE = weak_odr unnamed_addr constant
+// CHECK: _ZTI1TILj2EE = external constant
+// CHECK: _ZTS1B = constant
+// CHECK: _ZTI1B = unnamed_addr constant
+// CHECK: _ZTS1F = linkonce_odr constant
-// A has no key function, so its RTTI data should be weak_odr.
+// CHECK: _ZTIN12_GLOBAL__N_11DE to
+
+// A has no key function, so its RTTI data should be linkonce_odr.
struct A { };
// B has a key function defined in the translation unit, so the RTTI data should
@@ -90,7 +90,7 @@ namespace {
};
// F has a key function defined in the translation unit, but it is inline so the RTTI
-// data should be emitted with weak_odr linkage.
+// data should be emitted with linkonce_odr linkage.
struct F {
virtual void f();
};
@@ -132,3 +132,9 @@ void t3() {
(void) typeid(T<1>);
(void) typeid(T<2>);
}
+
+// rdar://problem/8778973
+struct T4 {};
+void t4(const T4 *ptr) {
+ const void *value = &typeid(ptr);
+}
diff --git a/test/CodeGenCXX/rtti-visibility.cpp b/test/CodeGenCXX/rtti-visibility.cpp
new file mode 100644
index 0000000..40cee06
--- /dev/null
+++ b/test/CodeGenCXX/rtti-visibility.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o %t.hidden
+// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-TEST2-HIDDEN %s < %t.hidden
+
+#include <typeinfo>
+
+namespace Test1 {
+ // A is explicitly marked hidden, so all RTTI data should also be marked hidden.
+ // CHECK-TEST1: @_ZTSN5Test11AE = linkonce_odr hidden constant
+ // CHECK-TEST1: @_ZTIN5Test11AE = linkonce_odr hidden unnamed_addr constant
+ // CHECK-TEST1: @_ZTSPN5Test11AE = linkonce_odr hidden constant
+ // CHECK-TEST1: @_ZTIPN5Test11AE = linkonce_odr hidden unnamed_addr constant
+ struct __attribute__((visibility("hidden"))) A { };
+
+ void f() {
+ (void)typeid(A);
+ (void)typeid(A *);
+ }
+}
+
+namespace Test2 {
+ // A is weak, so its linkage should be linkoce_odr, but not marked hidden.
+ // CHECK-TEST2: @_ZTSN5Test21AE = linkonce_odr constant
+ // CHECK-TEST2: @_ZTIN5Test21AE = linkonce_odr unnamed_addr constant
+ struct A { };
+
+ // With -fhidden-weak-vtables, the typeinfo for A is marked hidden, but not its name.
+ // CHECK-TEST2-HIDDEN: _ZTSN5Test21AE = linkonce_odr constant
+ // CHECK-TEST2-HIDDEN: @_ZTIN5Test21AE = linkonce_odr hidden unnamed_addr constant
+ void f() {
+ (void)typeid(A);
+ }
+}
diff --git a/test/CodeGenCXX/rvalue-references.cpp b/test/CodeGenCXX/rvalue-references.cpp
new file mode 100644
index 0000000..e151723
--- /dev/null
+++ b/test/CodeGenCXX/rvalue-references.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+
+struct Spacer { int x; };
+struct A { double array[2]; };
+struct B : Spacer, A { };
+
+B &getB();
+
+// CHECK: define %struct.A* @_Z4getAv()
+// CHECK: call %struct.B* @_Z4getBv()
+// CHECK-NEXT: bitcast %struct.B*
+// CHECK-NEXT: getelementptr i8*
+// CHECK-NEXT: bitcast i8* {{.*}} to %struct.A*
+// CHECK-NEXT: ret %struct.A*
+A &&getA() { return static_cast<A&&>(getB()); }
+
+int &getIntLValue();
+int &&getIntXValue();
+int getIntPRValue();
+
+// CHECK: define i32* @_Z2f0v()
+// CHECK: call i32* @_Z12getIntLValuev()
+// CHECK-NEXT: ret i32*
+int &&f0() { return static_cast<int&&>(getIntLValue()); }
+
+// CHECK: define i32* @_Z2f1v()
+// CHECK: call i32* @_Z12getIntXValuev()
+// CHECK-NEXT: ret i32*
+int &&f1() { return static_cast<int&&>(getIntXValue()); }
+
+// CHECK: define i32* @_Z2f2v
+// CHECK: call i32 @_Z13getIntPRValuev()
+// CHECK-NEXT: store i32 {{.*}}, i32*
+// CHECK-NEXT: ret i32*
+int &&f2() { return static_cast<int&&>(getIntPRValue()); }
+
+bool ok;
+
+class C
+{
+ int* state_;
+
+ C(const C&) = delete;
+ C& operator=(const C&) = delete;
+public:
+ C(int state) : state_(new int(state)) { }
+
+ C(C&& a) {
+ state_ = a.state_;
+ a.state_ = 0;
+ }
+
+ ~C() {
+ delete state_;
+ state_ = 0;
+ }
+};
+
+C test();
+
+// CHECK: define void @_Z15elide_copy_initv
+void elide_copy_init() {
+ ok = false;
+ // CHECK: call void @_Z4testv
+ C a = test();
+ // CHECK-NEXT: call void @_ZN1CD1Ev
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @_Z16test_move_returnv
+C test_move_return() {
+ // CHECK: call void @_ZN1CC1Ei
+ C a1(3);
+ // CHECK: call void @_ZN1CC1Ei
+ C a2(4);
+ if (ok)
+ // CHECK: call void @_ZN1CC1EOS_
+ return a1;
+ // CHECK: call void @_ZN1CC1EOS_
+ return a2;
+ // CHECK: call void @_ZN1CD1Ev
+ // CHECK: call void @_ZN1CD1Ev
+ //CHECK: ret void
+}
diff --git a/test/CodeGenCXX/specialized-static-data-mem-init.cpp b/test/CodeGenCXX/specialized-static-data-mem-init.cpp
new file mode 100644
index 0000000..8f5765b
--- /dev/null
+++ b/test/CodeGenCXX/specialized-static-data-mem-init.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// rdar: // 8562966
+// pr8409
+
+// CHECK: @_ZN1CIiE11needs_guardE = weak global
+// CHECK: @_ZGVN1CIiE11needs_guardE = weak global
+
+struct K
+{
+ K();
+ K(const K &);
+ ~K();
+ void PrintNumK();
+};
+
+template<typename T>
+struct C
+{
+ void Go() { needs_guard.PrintNumK(); }
+ static K needs_guard;
+};
+
+template<typename T> K C<T>::needs_guard;
+
+void F()
+{
+ C<int>().Go();
+}
+
diff --git a/test/CodeGenCXX/static-data-member.cpp b/test/CodeGenCXX/static-data-member.cpp
index b3a2af2..64fca2e 100644
--- a/test/CodeGenCXX/static-data-member.cpp
+++ b/test/CodeGenCXX/static-data-member.cpp
@@ -1,18 +1,66 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
-// CHECK: @_ZN1A1aE = constant i32 10
+// CHECK: @_ZN5test11A1aE = constant i32 10, align 4
+// CHECK: @_ZN5test212_GLOBAL__N_11AIiE1xE = internal global i32 0, align 4
+// CHECK: @_ZN5test31AIiE1xE = weak global i32 0, align 4
+// CHECK: @_ZGVN5test31AIiE1xE = weak global i64 0
// PR5564.
-struct A {
- static const int a = 10;
-};
+namespace test1 {
+ struct A {
+ static const int a = 10;
+ };
-const int A::a;
+ const int A::a;
-struct S {
- static int i;
-};
+ struct S {
+ static int i;
+ };
-void f() {
- int a = S::i;
+ void f() {
+ int a = S::i;
+ }
+}
+
+// Test that we don't use guards for initializing template static data
+// members with internal linkage.
+namespace test2 {
+ int foo();
+
+ namespace {
+ template <class T> struct A {
+ static int x;
+ };
+
+ template <class T> int A<T>::x = foo();
+ template struct A<int>;
+ }
+
+ // CHECK: define internal void @__cxx_global_var_init()
+ // CHECK: [[TMP:%.*]] = call i32 @_ZN5test23fooEv()
+ // CHECK-NEXT: store i32 [[TMP]], i32* @_ZN5test212_GLOBAL__N_11AIiE1xE, align 4
+ // CHECK-NEXT: ret void
+}
+
+// Test that we don't use threadsafe statics when initializing
+// template static data members.
+namespace test3 {
+ int foo();
+
+ template <class T> struct A {
+ static int x;
+ };
+
+ template <class T> int A<T>::x = foo();
+ template struct A<int>;
+
+ // CHECK: define internal void @__cxx_global_var_init1()
+ // CHECK: [[GUARDBYTE:%.*]] = load i8* bitcast (i64* @_ZGVN5test31AIiE1xE to i8*)
+ // CHECK-NEXT: [[UNINITIALIZED:%.*]] = icmp eq i8 [[GUARDBYTE]], 0
+ // CHECK-NEXT: br i1 [[UNINITIALIZED]]
+ // CHECK: [[TMP:%.*]] = call i32 @_ZN5test33fooEv()
+ // CHECK-NEXT: store i32 [[TMP]], i32* @_ZN5test31AIiE1xE, align 4
+ // CHECK-NEXT: store i64 1, i64* @_ZGVN5test31AIiE1xE
+ // CHECK-NEXT: br label
+ // CHECK: ret void
}
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index 09b398a..dd9ed61 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -14,8 +14,8 @@ struct A {
void f() {
// CHECK: call i32 @__cxa_guard_acquire
// CHECK: call void @_ZN1AC1Ev
- // CHECK: call void @__cxa_guard_release
// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+ // CHECK: call void @__cxa_guard_release
static A a;
}
diff --git a/test/CodeGenCXX/stmtexpr.cpp b/test/CodeGenCXX/stmtexpr.cpp
new file mode 100644
index 0000000..0828d59
--- /dev/null
+++ b/test/CodeGenCXX/stmtexpr.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -Wno-unused-value -emit-llvm -o - %s | FileCheck %s
+// rdar: //8540501
+extern "C" int printf(...);
+extern "C" void abort();
+
+struct A
+{
+ int i;
+ A (int j) : i(j) {printf("this = %p A(%d)\n", this, j);}
+ A (const A &j) : i(j.i) {printf("this = %p const A&(%d)\n", this, i);}
+ A& operator= (const A &j) { i = j.i; abort(); return *this; }
+ ~A() { printf("this = %p ~A(%d)\n", this, i); }
+};
+
+struct B
+{
+ int i;
+ B (const A& a) { i = a.i; }
+ B() {printf("this = %p B()\n", this);}
+ B (const B &j) : i(j.i) {printf("this = %p const B&(%d)\n", this, i);}
+ ~B() { printf("this = %p ~B(%d)\n", this, i); }
+};
+
+A foo(int j)
+{
+ return ({ j ? A(1) : A(0); });
+}
+
+
+void foo2()
+{
+ A b = ({ A a(1); A a1(2); A a2(3); a1; a2; a; });
+ if (b.i != 1)
+ abort();
+ A c = ({ A a(1); A a1(2); A a2(3); a1; a2; a; A a3(4); a2; a3; });
+ if (c.i != 4)
+ abort();
+}
+
+void foo3()
+{
+ const A &b = ({ A a(1); a; });
+ if (b.i != 1)
+ abort();
+}
+
+void foo4()
+{
+// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1AC1ERKS_
+// CHECK: call void @_ZN1AD1Ev
+// CHECK: call void @_ZN1BC1ERK1A
+// CHECK: call void @_ZN1AD1Ev
+ const B &b = ({ A a(1); a; });
+ if (b.i != 1)
+ abort();
+}
+
+int main()
+{
+ foo2();
+ foo3();
+ foo4();
+ return foo(1).i-1;
+}
+
+// rdar: // 8600553
+int a[128];
+int* foo5() {
+// CHECK-NOT: memcpy
+ // Check that array-to-pointer conversion occurs in a
+ // statement-expression.
+ return (({ a; }));
+}
+
diff --git a/test/CodeGenCXX/template-anonymous-types.cpp b/test/CodeGenCXX/template-anonymous-types.cpp
index 5e7a71f..68bdc0c 100644
--- a/test/CodeGenCXX/template-anonymous-types.cpp
+++ b/test/CodeGenCXX/template-anonymous-types.cpp
@@ -29,9 +29,9 @@ void test() {
//
// BAR's instantiation of X:
// CHECK: define internal i32 @"_ZN1XIN1S3$_1EE1fEv"(%struct.X* %this)
- // CHECK: define internal void @"_ZN1XIN1S3$_1EEC2ES1_"(%struct.X* %this, i32 %t)
+ // CHECK: define internal void @"_ZN1XIN1S3$_1EEC2ES1_"(%struct.X* %this, i32 %t) unnamed_addr
//
// FOO's instantiation of X:
// CHECK: define internal i32 @"_ZN1XIN1S3$_0EE1fEv"(%struct.X* %this)
- // CHECK: define internal void @"_ZN1XIN1S3$_0EEC2ES1_"(%struct.X* %this, i32 %t)
+ // CHECK: define internal void @"_ZN1XIN1S3$_0EEC2ES1_"(%struct.X* %this, i32 %t) unnamed_addr
}
diff --git a/test/CodeGenCXX/template-dependent-bind-temporary.cpp b/test/CodeGenCXX/template-dependent-bind-temporary.cpp
new file mode 100644
index 0000000..cc1ce86
--- /dev/null
+++ b/test/CodeGenCXX/template-dependent-bind-temporary.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// rdar: //8620524
+// PR7851
+struct string {
+ string (const string& );
+ string ();
+ ~string();
+};
+
+string operator + (char ch, const string&);
+
+template <class T>
+void IntToString(T a)
+{
+ string result;
+ T digit;
+ char((digit < 10 ? '0' : 'a') + digit) + result;
+}
+
+int main() {
+// CHECK: define linkonce_odr void @_Z11IntToStringIcEvT_(
+ IntToString('a');
+}
+
diff --git a/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp b/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
new file mode 100644
index 0000000..ca4446c
--- /dev/null
+++ b/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fvisibility hidden -emit-llvm -o - %s | FileCheck %s
+
+// Verify that symbols are hidden.
+// CHECK: @_ZN1CIiE5Inner6Inner26StaticE = weak hidden global
+// CHECK: define weak_odr hidden void @_ZN1CIiE5Inner1fEv
+// CHECK: define weak_odr hidden void @_ZN1CIiE5Inner6Inner21gEv
+
+template<typename T>
+struct C {
+ struct Inner {
+ void f();
+ struct Inner2 {
+ void g();
+ static int Static;
+ };
+ };
+};
+
+template<typename T> void C<T>::Inner::f() { }
+template<typename T> void C<T>::Inner::Inner2::g() { }
+template<typename T> int C<T>::Inner::Inner2::Static;
+
+extern template struct C<int>;
+template struct C<int>;
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
index cb6c812..635e1d2 100644
--- a/test/CodeGenCXX/template-instantiation.cpp
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -2,9 +2,12 @@
// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
-// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = constant
+// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = unnamed_addr constant
-// CHECK: define linkonce_odr void @_ZN5test21CIiEC1Ev(
+// CHECK-NOT: _ZTVN5test31SIiEE
+// CHECK-NOT: _ZTSN5test31SIiEE
+
+// CHECK: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C"* nocapture %this) unnamed_addr
// CHECK: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(
// CHECK: define available_externally void @_ZN5test21CIiE6zedbarEd(
@@ -75,3 +78,47 @@ namespace test3 {
// (test at the top).
template void basic_fstreamXX<char>::is_open() const;
}
+
+namespace test3 {
+ template <typename T>
+ struct S {
+ virtual void m();
+ };
+
+ template<typename T>
+ void S<T>::m() { }
+
+ // Should not cause us to produce vtable because template instantiations
+ // don't have key functions.
+ template void S<int>::m();
+}
+
+namespace test4 {
+ template <class T> struct A { static void foo(); };
+
+ class B {
+ template <class T> friend void A<T>::foo();
+ B();
+ };
+
+ template <class T> void A<T>::foo() {
+ B b;
+ }
+
+ unsigned test() {
+ A<int>::foo();
+ }
+}
+
+namespace PR8505 {
+// Hits an assertion due to bogus instantiation of class B.
+template <int i> class A {
+ class B* g;
+};
+class B {
+ void f () {}
+};
+// Should not instantiate class B since it is introduced in namespace scope.
+// CHECK-NOT: _ZN6PR85051AILi0EE1B1fEv
+template class A<0>;
+}
diff --git a/test/CodeGenCXX/template-linkage.cpp b/test/CodeGenCXX/template-linkage.cpp
index 63a5c09..20508c1 100644
--- a/test/CodeGenCXX/template-linkage.cpp
+++ b/test/CodeGenCXX/template-linkage.cpp
@@ -37,7 +37,7 @@ template<typename T> void X1<T>::blarg() { }
extern template struct X0<char>;
extern template struct X1<char>;
-// CHECK: define linkonce_odr void @_ZN2X1IcED1Ev(
+// CHECK: define linkonce_odr void @_ZN2X1IcED1Ev(%struct.X1* %this) unnamed_addr
void test_X1() {
X1<char> i1c;
}
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index 9a397ab..348d51e 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -338,3 +338,188 @@ namespace PR7556 {
// CHECK-NEXT: ret void
}
}
+
+namespace Elision {
+ struct A {
+ A(); A(const A &); ~A();
+ void *p;
+ void foo() const;
+ };
+
+ void foo();
+ A fooA();
+ void takeA(A a);
+
+ // CHECK: define void @_ZN7Elision5test0Ev()
+ void test0() {
+ // CHECK: [[I:%.*]] = alloca [[A:%.*]], align 8
+ // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
+ // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8
+ // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8
+ // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8
+
+ // CHECK-NEXT: call void @_ZN7Elision3fooEv()
+ // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
+ A i = (foo(), A());
+
+ // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]])
+ // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
+ A j = (fooA(), A());
+
+ // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]])
+ // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]])
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]])
+ A k = (A(), fooA());
+
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]])
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
+ }
+
+
+ // CHECK: define void @_ZN7Elision5test1EbNS_1AE(
+ void test1(bool c, A x) {
+ // CHECK: [[I:%.*]] = alloca [[A]], align 8
+ // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
+
+ // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
+ // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* [[X:%.*]])
+ A i = (c ? A() : x);
+
+ // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* [[X]])
+ // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
+ A j = (c ? x : A());
+
+ // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
+ }
+
+ // CHECK: define void @_ZN7Elision5test2Ev([[A]]* sret
+ A test2() {
+ // CHECK: call void @_ZN7Elision3fooEv()
+ // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
+ // CHECK-NEXT: ret void
+ return (foo(), A());
+ }
+
+ // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* sret
+ A test3(int v, A x) {
+ if (v < 5)
+ // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
+ // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X:%.*]])
+ return (v < 0 ? A() : x);
+ else
+ // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X]])
+ // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
+ return (v > 10 ? x : A());
+
+ // CHECK: ret void
+ }
+
+ // CHECK: define void @_ZN7Elision5test4Ev()
+ void test4() {
+ // CHECK: [[X:%.*]] = alloca [[A]], align 8
+ // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
+ // CHECK-NEXT: [[I:%.*]] = alloca i64
+
+ // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
+ A x;
+
+ // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
+ // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 1
+ // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]])
+ // CHECK-NEXT: [[XSB:%.*]] = bitcast [2 x [[A]]]* [[XS]] to [[A]]*
+ A xs[] = { A(), x };
+
+ // CHECK-NEXT: store i64 2, i64* [[I]]
+ // CHECK-NEXT: br label
+ // CHECK: [[I0:%.*]] = load i64* [[I]]
+ // CHECK-NEXT: icmp ne i64 [[I0]], 0
+ // CHECK-NEXT: br i1
+ // CHECK: [[I1:%.*]] = load i64* [[I]]
+ // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I1]], 1
+ // CHECK-NEXT: [[XSI:%.*]] = getelementptr inbounds [[A]]* [[XSB]], i64 [[I2]]
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[XSI]])
+ // CHECK-NEXT: br label
+
+ // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
+ }
+
+ // rdar://problem/8433352
+ // CHECK: define void @_ZN7Elision5test5Ev([[A]]* sret
+ struct B { A a; B(); };
+ A test5() {
+ // CHECK: [[AT0:%.*]] = alloca [[A]], align 8
+ // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8
+ // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8
+ // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8
+ // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8
+
+ // CHECK: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
+ // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* [[AM]])
+ // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
+ // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
+ takeA(B().a);
+
+ // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
+ // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* [[AM]])
+ // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
+ A x = B().a;
+
+ // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
+ // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0
+ // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* [[AM]])
+ // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
+ return B().a;
+
+ // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
+ }
+
+ // Reduced from webkit.
+ // CHECK: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]*
+ struct C { operator A() const; };
+ void test6(const C *x) {
+ // CHECK: [[T0:%.*]] = alloca [[A]], align 8
+ // CHECK: [[X:%.*]] = load [[C]]** {{%.*}}, align 8
+ // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]])
+ // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]])
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
+ // CHECK-NEXT: ret void
+ A(*x).foo();
+ }
+}
+
+namespace PR8623 {
+ struct A { A(int); ~A(); };
+
+ // CHECK: define void @_ZN6PR86233fooEb(
+ void foo(bool b) {
+ // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK-NEXT: [[LCONS:%.*]] = alloca i1
+ // CHECK-NEXT: [[RCONS:%.*]] = alloca i1
+ // CHECK: store i1 false, i1* [[LCONS]]
+ // CHECK-NEXT: store i1 false, i1* [[RCONS]]
+ // CHECK-NEXT: br i1
+ // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2)
+ // CHECK-NEXT: store i1 true, i1* [[LCONS]]
+ // CHECK-NEXT: br label
+ // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3)
+ // CHECK-NEXT: store i1 true, i1* [[RCONS]]
+ // CHECK-NEXT: br label
+ // CHECK: load i1* [[RCONS]]
+ // CHECK-NEXT: br i1
+ // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
+ // CHECK-NEXT: br label
+ // CHECK: load i1* [[LCONS]]
+ // CHECK-NEXT: br i1
+ // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
+ // CHECK-NEXT: br label
+ // CHECK: ret void
+ b ? A(2) : A(3);
+ }
+}
diff --git a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
index c91590f..87be572 100644
--- a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
+++ b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
@@ -11,8 +11,8 @@ struct Y { };
void f() {
// CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ1fvE1x)
// CHECK: invoke void @_ZN1XC1Ev
- // CHECK: call void @__cxa_guard_release(i64* @_ZGVZ1fvE1x)
- // CHECK-NEXT: call i32 @__cxa_atexit
+ // CHECK: call i32 @__cxa_atexit
+ // CHECK-NEXT: call void @__cxa_guard_release(i64* @_ZGVZ1fvE1x)
// CHECK: br
static X x;
diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp
index 1670e44..1d22ec0 100644
--- a/test/CodeGenCXX/throw-expressions.cpp
+++ b/test/CodeGenCXX/throw-expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -verify %s -Wno-unreachable-code
+// RUN: %clang_cc1 -fexceptions -emit-llvm-only -verify %s -Wno-unreachable-code
int val = 42;
int& test1() {
@@ -8,3 +8,8 @@ int& test1() {
int test2() {
return val ? throw val : val;
}
+
+// rdar://problem/8608801
+void test3() {
+ throw false;
+}
diff --git a/test/CodeGenCXX/thunks-available-externally.cpp b/test/CodeGenCXX/thunks-available-externally.cpp
new file mode 100644
index 0000000..dfdb786
--- /dev/null
+++ b/test/CodeGenCXX/thunks-available-externally.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+
+// Check that we don't assert on this case.
+namespace Test1 {
+
+struct Incomplete;
+
+struct A {
+ virtual void f();
+ virtual void g(Incomplete);
+ virtual void h();
+ virtual void i();
+ int a;
+};
+
+struct B {
+ virtual void f();
+ virtual void g(Incomplete);
+ virtual void h();
+ virtual void i();
+ int b;
+};
+
+struct C : A, B {
+ C();
+
+ virtual void f();
+ virtual void g(Incomplete);
+ virtual void h();
+ virtual void i();
+};
+
+void C::h() { }
+
+C::C() { }
+
+void C::i() { }
+
+}
+
+namespace Test2 {
+
+struct A {
+ virtual void f();
+ int a;
+};
+
+struct B {
+ virtual void f();
+ int b;
+};
+
+struct C : A, B {
+ virtual void f();
+};
+
+static void f(B* b) {
+ b->f();
+}
+
+// CHECK: define void @_ZN5Test21fEv()
+// CHECK: call void @_ZN5Test21C1fEv
+// CHECK: ret void
+// CHECK: define available_externally void @_ZThn16_N5Test21C1fEv
+void f() {
+ C c;
+ f(&c);
+}
+
+}
+
+// Test that we don't assert.
+namespace Test3 {
+
+struct A {
+ virtual ~A();
+
+ int a;
+};
+
+struct B : A { };
+struct C : virtual B { };
+
+void f() {
+ C c;
+}
+
+}
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index ba60385..a74cc05 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -88,31 +88,29 @@ void C::f() { }
}
// Check that the thunk gets internal linkage.
-namespace {
-
-struct A {
- virtual void f();
-};
-
-struct B {
- virtual void f();
-};
-
-struct C : A, B {
- virtual void c();
-
- virtual void f();
-};
+namespace Test4B {
+ struct A {
+ virtual void f();
+ };
-void C::f() { }
+ struct B {
+ virtual void f();
+ };
-}
+ namespace {
+ struct C : A, B {
+ virtual void c();
+ virtual void f();
+ };
+ }
+ void C::c() {}
+ void C::f() {}
-// Force C::f to be used.
-void f() {
- C c;
-
- c.f();
+ // Force C::f to be used.
+ void f() {
+ C c;
+ c.f();
+ }
}
namespace Test5 {
@@ -260,8 +258,27 @@ namespace Test10 {
}
}
+// PR7611
+namespace Test11 {
+ struct A { virtual A* f(); };
+ struct B : virtual A { virtual A* f(); };
+ struct C : B { virtual C* f(); };
+ C* C::f() { return 0; }
+
+ // The this-adjustment and return-adjustment thunk required when
+ // C::f appears in a vtable where A is at a nonzero offset from C.
+ // CHECK: define {{.*}} @_ZTcv0_n24_v0_n32_N6Test111C1fEv(
+
+ // C::f itself.
+ // CHECK: define {{.*}} @_ZN6Test111C1fEv(
+
+ // The return-adjustment thunk required when C::f appears in a vtable
+ // where A is at a zero offset from C.
+ // CHECK: define {{.*}} @_ZTch0_v0_n32_N6Test111C1fEv(
+}
+
/**** The following has to go at the end of the file ****/
// This is from Test5:
// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
-// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv(
+// CHECK: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index c4eb1c8..258d692 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -133,8 +133,21 @@ namespace zeroinit {
X3<int>().f();
}
- // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev
+ // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%struct.B* %this) unnamed_addr
// CHECK: call void @llvm.memset.p0i8.i64
// CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
// CHECK-NEXT: ret void
}
+
+namespace PR8726 {
+class C;
+struct S {
+ const C &c1;
+ int i;
+ const C &c2;
+};
+void f(const C& c) {
+ S s = {c, 42, c};
+}
+
+}
diff --git a/test/CodeGenCXX/variadic-templates.cpp b/test/CodeGenCXX/variadic-templates.cpp
new file mode 100644
index 0000000..4f3cf1f
--- /dev/null
+++ b/test/CodeGenCXX/variadic-templates.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+template<typename ...Types>
+int get_num_types(Types...) {
+ return sizeof...(Types);
+}
+
+// CHECK: define weak_odr i32 @_Z13get_num_typesIJifdEEiDpT_
+// CHECK: ret i32 3
+template int get_num_types(int, float, double);
+
+
diff --git a/test/CodeGenCXX/virt-dtor-gen.cpp b/test/CodeGenCXX/virt-dtor-gen.cpp
index a4346ba..1a6c583 100644
--- a/test/CodeGenCXX/virt-dtor-gen.cpp
+++ b/test/CodeGenCXX/virt-dtor-gen.cpp
@@ -7,4 +7,4 @@ class Foo {
};
Foo::~Foo() {}
-// CHECK: define void @_ZN3FooD0Ev
+// CHECK: define void @_ZN3FooD0Ev(%class.Foo* %this) unnamed_addr
diff --git a/test/CodeGenCXX/virt-dtor-key.cpp b/test/CodeGenCXX/virt-dtor-key.cpp
index 6a58c50..a8fa371 100644
--- a/test/CodeGenCXX/virt-dtor-key.cpp
+++ b/test/CodeGenCXX/virt-dtor-key.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
-// CHECK: @_ZTI3foo = constant
+// CHECK: @_ZTI3foo = unnamed_addr constant
class foo {
foo();
virtual ~foo();
diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp
index d60cfb9..25736fd 100644
--- a/test/CodeGenCXX/virt-template-vtable.cpp
+++ b/test/CodeGenCXX/virt-template-vtable.cpp
@@ -16,7 +16,7 @@ extern template class A<short>;
template class A<short>;
-// CHECK: @_ZTV1B = weak_odr constant
-// CHECK: @_ZTV1AIlE = weak_odr constant
-// CHECK: @_ZTV1AIsE = weak_odr constant
-// CHECK: @_ZTV1AIiE = weak_odr constant
+// CHECK: @_ZTV1B = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTV1AIlE = weak_odr unnamed_addr constant
+// CHECK: @_ZTV1AIsE = weak_odr unnamed_addr constant
+// CHECK: @_ZTV1AIiE = linkonce_odr unnamed_addr constant
diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
index 4618a03..807eaff 100644
--- a/test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -18,34 +18,34 @@ int main() {
// basic_iostream's complete dtor calls its base dtor, then its
// virtual base's dtor.
-// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED1Ev
+// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED1Ev(%struct.basic_iostream* %this) unnamed_addr
// CHECK: call void @_ZN14basic_iostreamIcED2Ev
// CHECK: call void @_ZN9basic_iosD2Ev
// basic_iostream's base dtor calls its non-virtual base dtor.
-// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev
+// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev(%struct.basic_iostream* %this, i8** %vtt) unnamed_addr
// CHECK: call void @_ZN13basic_istreamIcED2Ev
// CHECK: }
// basic_istream's base dtor is a no-op.
-// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
+// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev(%struct.basic_istream* %this, i8** %vtt) unnamed_addr
// CHECK-NOT: call
// CHECK: }
// basic_iostream's deleting dtor calls its complete dtor, then
// operator delete().
-// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev
+// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev(%struct.basic_iostream* %this) unnamed_addr
// CHECK: call void @_ZN14basic_iostreamIcED1Ev
// CHECK: call void @_ZdlPv
// basic_istream's complete dtor calls the base dtor,
// then its virtual base's base dtor.
-// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED1Ev
+// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED1Ev(%struct.basic_istream* %this) unnamed_addr
// CHECK: call void @_ZN13basic_istreamIcED2Ev
// CHECK: call void @_ZN9basic_iosD2Ev
// basic_istream's deleting dtor calls the complete dtor, then
// operator delete().
-// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED0Ev
+// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED0Ev(%struct.basic_istream* %this) unnamed_addr
// CHECK: call void @_ZN13basic_istreamIcED1Ev
// CHECK: call void @_ZdlPv
diff --git a/test/CodeGenCXX/virtual-bases.cpp b/test/CodeGenCXX/virtual-bases.cpp
index 61de315..cfb4c83 100644
--- a/test/CodeGenCXX/virtual-bases.cpp
+++ b/test/CodeGenCXX/virtual-bases.cpp
@@ -5,23 +5,23 @@ struct A {
};
// CHECK: @_ZN1AC1Ev = alias {{.*}} @_ZN1AC2Ev
-// CHECK: define void @_ZN1AC2Ev(%struct.A* %this)
+// CHECK: define void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr
A::A() { }
struct B : virtual A {
B();
};
-// CHECK: define void @_ZN1BC1Ev(%struct.B* %this)
-// CHECK: define void @_ZN1BC2Ev(%struct.B* %this, i8** %vtt)
+// CHECK: define void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
+// CHECK: define void @_ZN1BC2Ev(%struct.B* %this, i8** %vtt) unnamed_addr
B::B() { }
struct C : virtual A {
C(bool);
};
-// CHECK: define void @_ZN1CC1Eb(%struct.B* %this, i1 zeroext)
-// CHECK: define void @_ZN1CC2Eb(%struct.B* %this, i8** %vtt, i1 zeroext)
+// CHECK: define void @_ZN1CC1Eb(%struct.B* %this, i1 zeroext) unnamed_addr
+// CHECK: define void @_ZN1CC2Eb(%struct.B* %this, i8** %vtt, i1 zeroext) unnamed_addr
C::C(bool) { }
// PR6251
@@ -39,7 +39,7 @@ struct D : B, C {
D();
};
-// CHECK: define void @_ZN6PR62511DC1Ev
+// CHECK: define void @_ZN6PR62511DC1Ev(%"struct.PR6251::D"* %this) unnamed_addr
// CHECK: call void @_ZN6PR62511AIcEC2Ev
// CHECK-NOT: call void @_ZN6PR62511AIcEC2Ev
// CHECK: ret void
diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp
index c5b9262..1cc8bcc 100644
--- a/test/CodeGenCXX/virtual-destructor-calls.cpp
+++ b/test/CodeGenCXX/virtual-destructor-calls.cpp
@@ -21,12 +21,12 @@ struct B : A {
// CHECK: @_ZN1CD2Ev = alias bitcast {{.*}} @_ZN1BD2Ev
// Deleting dtor: defers to the complete dtor.
-// CHECK: define void @_ZN1BD0Ev
+// CHECK: define void @_ZN1BD0Ev(%struct.B* %this) unnamed_addr
// CHECK: call void @_ZN1BD1Ev
// CHECK: call void @_ZdlPv
// Base dtor: actually calls A's base dtor.
-// CHECK: define void @_ZN1BD2Ev
+// CHECK: define void @_ZN1BD2Ev(%struct.B* %this) unnamed_addr
// CHECK: call void @_ZN6MemberD1Ev
// CHECK: call void @_ZN1AD2Ev
@@ -41,7 +41,7 @@ C::~C() { }
// Complete dtor: just an alias (checked above).
// Deleting dtor: defers to the complete dtor.
-// CHECK: define void @_ZN1CD0Ev
+// CHECK: define void @_ZN1CD0Ev(%struct.C* %this) unnamed_addr
// CHECK: call void @_ZN1CD1Ev
// CHECK: call void @_ZdlPv
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
index bb1574f..760879a 100644
--- a/test/CodeGenCXX/visibility-inlines-hidden.cpp
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -1,4 +1,9 @@
-// RUN: %clang_cc1 -fvisibility-inlines-hidden -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
+
+// The trickery with optimization in the run line is to get IR
+// generation to emit available_externally function bodies, but not
+// actually inline them (and thus remove the emitted bodies).
+
struct X0 {
void __attribute__((visibility("default"))) f1() { }
void f2() { }
@@ -29,7 +34,9 @@ struct __attribute__((visibility("default"))) X2 {
void f2() { }
};
-void use(X0 *x0, X1<int> *x1, X2 *x2) {
+extern template struct X1<float>;
+
+void use(X0 *x0, X1<int> *x1, X2 *x2, X1<float> *x3) {
// CHECK: define linkonce_odr void @_ZN2X02f1Ev
x0->f1();
// CHECK: define linkonce_odr hidden void @_ZN2X02f2Ev
@@ -54,4 +61,39 @@ void use(X0 *x0, X1<int> *x1, X2 *x2) {
x1->X1::f6();
// CHECK: define linkonce_odr hidden void @_ZN2X22f2Ev
x2->f2();
+ // CHECK: define available_externally void @_ZN2X1IfE2f2Ev
+ x3->f2();
+}
+
+// rdar://problem/8614470
+namespace test1 {
+ struct __attribute__((visibility("default"))) A {
+ inline void foo();
+ ~A();
+ };
+
+ void test() {
+ A a;
+ a.foo();
+ }
+// CHECK: declare void @_ZN5test11A3fooEv
+// CHECK: declare void @_ZN5test11AD1Ev
+}
+
+// PR8713
+namespace test2 {
+ struct A {};
+ template <class T> class B {};
+ typedef B<A> arg;
+
+ namespace ns __attribute__((visibility("default"))) {
+ template <class T> inline void foo() {}
+ extern template void foo<arg>();
+ }
+
+ void test() {
+ ns::foo<arg>();
+ }
+
+ // CHECK: define available_externally void @_ZN5test22ns3fooINS_1BINS_1AEEEEEvv()
}
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index ee3c179..9314650 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -1,11 +1,35 @@
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
#define HIDDEN __attribute__((visibility("hidden")))
#define PROTECTED __attribute__((visibility("protected")))
#define DEFAULT __attribute__((visibility("default")))
// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
-// CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant
+// CHECK: @_ZN5Test71aE = hidden global
+// CHECK: @_ZN5Test71bE = global
+// CHECK: @test9_var = global
+// CHECK-HIDDEN: @test9_var = global
+// CHECK: @_ZN6Test121A6hiddenE = external hidden global
+// CHECK: @_ZN6Test121A7visibleE = external global
+// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
+// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
+// CHECK: @_ZN6Test131B1aE = hidden global
+// CHECK: @_ZN6Test131C1aE = global
+// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
+// CHECK-HIDDEN: @_ZN6Test131C1aE = global
+// CHECK: @_ZN6Test143varE = external global
+// CHECK-HIDDEN: @_ZN6Test143varE = external global
+// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
+// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
+// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
+// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
+// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
+// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
+// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
+// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
+// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
+
namespace Test1 {
// CHECK: define hidden void @_ZN5Test11fEv
void HIDDEN f() { }
@@ -82,3 +106,308 @@ namespace Test6 {
barc::barc() {}
}
+
+namespace Test7 {
+ class HIDDEN A {};
+ A a; // top of file
+
+ template <A&> struct Aref {
+ static void foo() {}
+ };
+
+ class B : public A {};
+ B b; // top of file
+
+ // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
+ void test() {
+ Aref<a>::foo();
+ }
+}
+
+namespace Test8 {
+ void foo();
+ void bar() {}
+ // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
+ // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
+
+ void test() {
+ foo();
+ bar();
+ }
+}
+
+// PR8457
+namespace Test9 {
+ extern "C" {
+ struct A { int field; };
+ void DEFAULT test9_fun(struct A *a) { }
+ struct A DEFAULT test9_var; // above
+ }
+ // CHECK: define void @test9_fun(
+ // CHECK-HIDDEN: define void @test9_fun(
+
+ void test() {
+ A a = test9_var;
+ test9_fun(&a);
+ }
+}
+
+// PR8478
+namespace Test10 {
+ struct A;
+
+ DEFAULT class B {
+ void foo(A*);
+ };
+
+ // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
+ // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
+ void B::foo(A*) {}
+}
+
+// PR8492
+namespace Test11 {
+ struct A {
+ void foo() {}
+ void DEFAULT bar() {}
+ };
+
+ void test() {
+ A a;
+ a.foo();
+ a.bar();
+ }
+
+ // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
+ // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
+ // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
+ // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
+}
+
+// Tested at top of file.
+namespace Test12 {
+ struct A {
+ // This is hidden in all cases: the explicit attribute takes
+ // priority over -fvisibility on the parent.
+ static int hidden HIDDEN;
+
+ // This is default in all cases because it's only a declaration.
+ static int visible;
+ };
+
+ void test() {
+ A::hidden = 0;
+ A::visible = 0;
+ }
+}
+
+// Tested at top of file.
+namespace Test13 {
+ struct HIDDEN A {};
+
+ // Should be hidden in all cases.
+ struct B {
+ static A a;
+ };
+ A B::a;
+
+ // Should be default in all cases.
+ struct DEFAULT C {
+ static A a;
+ };
+ A C::a;
+};
+
+// Tested at top of file.
+namespace Test14 {
+ // Neither the visibility of the type nor -fvisibility=hidden should
+ // apply to declarations.
+ extern struct A *var;
+
+ struct A *test() { return var; }
+}
+
+// rdar://problem/8613093
+namespace Test15 {
+ struct A {};
+ template <class T> struct Temp {
+ struct Inner {
+ static char buffer[0];
+ };
+ };
+
+ char *test() {
+ return Temp<A>::Inner::buffer;
+ }
+}
+
+namespace Test16 {
+ struct Base1 { virtual void foo(); };
+ struct Base2 : virtual Base1 { virtual void foo(); };
+ template <class T> struct A : virtual Base1, Base2 {
+ virtual void foo();
+ };
+ extern template struct A<char>;
+
+ void test() {
+ A<char> a;
+ a.foo();
+ }
+}
+
+namespace Test17 {
+ struct HIDDEN A {
+ static void foo();
+ static void DEFAULT bar();
+ static void HIDDEN baz();
+
+ struct DEFAULT B {
+ static void foo();
+ static void DEFAULT bar();
+ static void HIDDEN baz();
+ };
+ };
+
+ void test() {
+ A::foo();
+ A::bar();
+ A::baz();
+ A::B::foo();
+ A::B::bar();
+ A::B::baz();
+ }
+ // CHECK: declare hidden void @_ZN6Test171A3fooEv()
+ // CHECK: declare void @_ZN6Test171A3barEv()
+ // CHECK: declare hidden void @_ZN6Test171A3bazEv()
+ // CHECK: declare void @_ZN6Test171A1B3fooEv()
+ // CHECK: declare void @_ZN6Test171A1B3barEv()
+ // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
+ // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
+ // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
+ // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
+}
+
+namespace Test18 {
+ template <class T> struct HIDDEN A {
+ static void foo();
+ static void DEFAULT bar();
+ static void HIDDEN baz();
+
+ struct DEFAULT B {
+ static void foo();
+ static void DEFAULT bar();
+ static void HIDDEN baz();
+ };
+ };
+ struct HIDDEN H;
+
+ void test() {
+ A<int>::foo();
+ A<int>::bar();
+ A<int>::baz();
+ A<int>::B::foo();
+ A<int>::B::bar();
+ A<int>::B::baz();
+ A<H>::foo();
+ A<H>::bar();
+ A<H>::baz();
+ A<H>::B::foo();
+ A<H>::B::bar();
+ A<H>::B::baz();
+ }
+ // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
+ // CHECK: declare void @_ZN6Test181AIiE3barEv()
+ // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
+ // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
+ // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
+ // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
+ // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
+ // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
+ // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
+ // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
+ // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
+ // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
+ // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
+ // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
+ // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
+ // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
+}
+
+namespace Test19 {
+ struct A { A(); ~A(); };
+
+ // Tested at top of file.
+ template <class T> void foo() {
+ static A a;
+ }
+
+ void test() {
+ foo<int>();
+ }
+}
+
+// Various things with class template specializations.
+namespace Test20 {
+ template <unsigned> struct HIDDEN A {};
+
+ // An explicit specialization inherits the explicit visibility of
+ // the template.
+ template <> struct A<0> {
+ static void test0();
+ static void test1();
+ };
+
+ // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
+ void A<0>::test0() {}
+
+ // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
+ void test1() {
+ A<0>::test1();
+ }
+
+ // ...unless that's explicitly overridden.
+ template <> struct DEFAULT A<1> {
+ static void test2();
+ static void test3();
+ };
+
+ // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
+ void A<1>::test2() {}
+
+ // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
+ void test3() {
+ A<1>::test3();
+ }
+
+ // <rdar://problem/8778497>
+ // But we should assume that an unknown specialization has the
+ // explicit visibility settings of the template.
+ template <class T> struct B {
+ static void test4() {}
+ static void test5();
+ };
+
+ // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
+ void test4() {
+ B<A<2> >::test4();
+ }
+
+ // CHECK: declare void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
+ // (but explicit visibility on a template argument doesn't count as
+ // explicit visibility for the template for purposes of deciding
+ // whether an external symbol gets visibility)
+ void test5() {
+ B<A<2> >::test5();
+ }
+}
diff --git a/test/CodeGenCXX/volatile-1.cpp b/test/CodeGenCXX/volatile-1.cpp
new file mode 100644
index 0000000..3ae17bd
--- /dev/null
+++ b/test/CodeGenCXX/volatile-1.cpp
@@ -0,0 +1,352 @@
+// RUN: %clang_cc1 -Wno-unused-value -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @i = global [[INT:i[0-9]+]] 0
+volatile int i, j, k;
+volatile int ar[5];
+volatile char c;
+// CHECK: @ci = global [[CINT:%.*]] zeroinitializer
+volatile _Complex int ci;
+volatile struct S {
+#ifdef __cplusplus
+ void operator =(volatile struct S&o) volatile;
+#endif
+ int i;
+} a, b;
+
+//void operator =(volatile struct S&o1, volatile struct S&o2) volatile;
+int printf(const char *, ...);
+
+
+// CHECK: define void @{{.*}}test
+void test() {
+
+ asm("nop"); // CHECK: call void asm
+
+ // should not load
+ i;
+
+ (float)(ci);
+ // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: sitofp [[INT]]
+
+ // These are not uses in C++:
+ // [expr.static.cast]p6:
+ // The lvalue-to-rvalue . . . conversions are not applied to the expression.
+ (void)ci;
+ (void)a;
+
+ (void)(ci=ci);
+ // CHECK-NEXT: [[R:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+
+ (void)(i=j);
+ // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* @j
+ // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* @i
+
+ ci+=ci;
+ // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // Not sure why they're ordered this way.
+ // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
+ // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
+ // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+
+ // Note that C++ requires an extra volatile load over C from the LHS of the '+'.
+ (ci += ci) + ci;
+ // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
+ // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
+ // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0)
+ // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // These additions can be elided.
+ // CHECK-NEXT: add [[INT]] [[R1]], [[R2]]
+ // CHECK-NEXT: add [[INT]] [[I1]], [[I2]]
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ // Extra volatile load in C++.
+ (i += j) + k;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add nsw [[INT]]
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add nsw [[INT]]
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ // Extra volatile load in C++.
+ (i += j) + 1;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add nsw [[INT]]
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add nsw [[INT]]
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ ci+ci;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add [[INT]]
+ // CHECK-NEXT: add [[INT]]
+
+ __real i;
+
+ +ci;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ (void)(i=i);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+
+ (float)(i=i);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: sitofp
+
+ (void)i;
+
+ i=i;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+
+ // Extra volatile load in C++.
+ i=i=i;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+
+ (void)__builtin_choose_expr(0, i=i, j=j);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+
+ k ? (i=i) : (j=j);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: icmp
+ // CHECK-NEXT: br i1
+ // CHECK: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: br label
+ // CHECK: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: br label
+ // CHECK: phi
+
+ (void)(i,(i=i));
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+
+ i=i,k;
+ // CHECK-NEXT: volatile load [[INT]]* @i
+ // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i
+
+ (i=j,k=j);
+ // CHECK-NEXT: volatile load [[INT]]* @j
+ // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i
+ // CHECK-NEXT: volatile load [[INT]]* @j
+ // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @k
+
+ (i=j,k);
+ // CHECK-NEXT: volatile load [[INT]]* @j
+ // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i
+
+ (i,j);
+
+ // Extra load in C++.
+ i=c=k;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: trunc
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: sext
+ // CHECK-NEXT: volatile store
+
+ i+=k;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add nsw [[INT]]
+ // CHECK-NEXT: volatile store
+
+ ci;
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ (int)ci;
+ // CHECK-NEXT: volatile load {{.*}} @ci, i32 0, i32 0
+ // CHECK-NEXT: volatile load {{.*}} @ci, i32 0, i32 1
+
+ (bool)ci;
+ // CHECK-NEXT: volatile load {{.*}} @ci, i32 0, i32 0
+ // CHECK-NEXT: volatile load {{.*}} @ci, i32 0, i32 1
+ // CHECK-NEXT: icmp ne
+ // CHECK-NEXT: icmp ne
+ // CHECK-NEXT: or i1
+
+ ci=ci;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile store
+
+ asm("nop"); // CHECK-NEXT: call void asm
+
+ // Extra load in C++.
+ ci=ci=ci;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile store
+
+ __imag ci = __imag ci = __imag ci;
+ // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+ // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1)
+
+ __real (i = j);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+
+ __imag i;
+
+ // ============================================================
+ // FIXME: Test cases we get wrong.
+
+ // A use. We load all of a into a copy of a, then load i. gcc forgets to do
+ // the assignment.
+ // (a = a).i;
+
+ // ============================================================
+ // Test cases where we intentionally differ from gcc, due to suspected bugs in
+ // gcc.
+
+ // Not a use. gcc forgets to do the assignment.
+ // CHECK-NEXT: call
+ ((a=a),a);
+
+ // Not a use. gcc gets this wrong, it doesn't emit the copy!
+ // CHECK-NEXT: call
+ (void)(a=a);
+
+ // Not a use. gcc got this wrong in 4.2 and omitted the side effects
+ // entirely, but it is fixed in 4.4.0.
+ __imag (i = j);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+
+ // C++ does an extra load here. Note that we have to do full loads.
+ (float)(ci=ci);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: sitofp
+
+ // Not a use, bug? gcc treats this as not a use, that's probably a
+ // bug due to tree folding ignoring volatile.
+ (int)(ci=ci);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+
+ // A use.
+ (float)(i=i);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: sitofp
+
+ // A use. gcc treats this as not a use, that's probably a bug due to tree
+ // folding ignoring volatile.
+ (int)(i=i);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+
+ // A use.
+ -(i=j);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: sub
+
+ // A use. gcc treats this a not a use, that's probably a bug due to tree
+ // folding ignoring volatile.
+ +(i=k);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+
+ // A use. gcc treats this a not a use, that's probably a bug due to tree
+ // folding ignoring volatile.
+ __real (ci=ci);
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile store
+
+ // A use.
+ i + 0;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add
+
+ // A use.
+ (i=j) + i;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add
+
+ // A use. gcc treats this as not a use, that's probably a bug due to tree
+ // folding ignoring volatile.
+ (i=j) + 0;
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: volatile store
+ // CHECK-NEXT: volatile load
+ // CHECK-NEXT: add
+
+ (i,j)=k;
+ // CHECK-NEXT: volatile load [[INT]]* @k
+ // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @j
+
+ (j=k,i)=i;
+ // CHECK-NEXT: volatile load [[INT]]* @i
+ // CHECK-NEXT: volatile load [[INT]]* @k
+ // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @j
+ // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i
+
+ // CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenCXX/volatile.cpp b/test/CodeGenCXX/volatile.cpp
index 58f433f..6ebb2f1 100644
--- a/test/CodeGenCXX/volatile.cpp
+++ b/test/CodeGenCXX/volatile.cpp
@@ -27,8 +27,6 @@ namespace test1 {
// CHECK: define void @_ZN5test14testEv()
void test() {
// CHECK: [[TMP:%.*]] = load i32** @_ZN5test11xE, align 8
- // *** FIXME: no! bad! should not be loaded! ***
- // CHECK-NEXT: [[TMP1:%.*]] = volatile load i32* [[TMP]]
// CHECK-NEXT: ret void
*x;
}
diff --git a/test/CodeGenCXX/vtable-available-externally.cpp b/test/CodeGenCXX/vtable-available-externally.cpp
new file mode 100644
index 0000000..23baac9
--- /dev/null
+++ b/test/CodeGenCXX/vtable-available-externally.cpp
@@ -0,0 +1,171 @@
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o %t
+// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-TEST7 %s < %t
+
+#include <typeinfo>
+
+// Test1::A's key function (f) is not defined in this translation unit, but in
+// order to devirtualize calls, we emit the class related data with
+// available_externally linkage.
+
+// CHECK-TEST1: @_ZTVN5Test11AE = available_externally
+// CHECK-TEST1: @_ZTSN5Test11AE = available_externally
+// CHECK-TEST1: @_ZTIN5Test11AE = available_externally
+namespace Test1 {
+
+struct A {
+ A();
+ virtual void f();
+ virtual ~A() { }
+};
+
+A::A() { }
+
+void f(A* a) {
+ a->f();
+};
+
+// CHECK: define void @_ZN5Test11gEv
+// CHECK: call void @_ZN5Test11A1fEv
+void g() {
+ A a;
+ f(&a);
+}
+
+}
+
+// Test2::A's key function (f) is defined in this translation unit, but when
+// we're doing codegen for the typeid(A) call, we don't know that yet.
+// This tests mainly that the typeinfo and typename constants have their linkage
+// updated correctly.
+
+// CHECK-TEST2: @_ZTSN5Test21AE = constant
+// CHECK-TEST2: @_ZTIN5Test21AE = unnamed_addr constant
+// CHECK-TEST2: @_ZTVN5Test21AE = unnamed_addr constant
+namespace Test2 {
+ struct A {
+ virtual void f();
+ };
+
+ const std::type_info &g() {
+ return typeid(A);
+ };
+
+ void A::f() { }
+}
+
+// Test that we don't assert on this test.
+namespace Test3 {
+
+struct A {
+ virtual void f();
+ virtual ~A() { }
+};
+
+struct B : A {
+ B();
+ virtual void f();
+};
+
+B::B() { }
+
+void g(A* a) {
+ a->f();
+};
+
+}
+
+// PR9114, test that we don't try to instantiate RefPtr<Node>.
+namespace Test4 {
+
+template <class T> struct RefPtr {
+ T* p;
+ ~RefPtr() {
+ p->deref();
+ }
+};
+
+struct A {
+ virtual ~A();
+};
+
+struct Node;
+
+struct B : A {
+ virtual void deref();
+ RefPtr<Node> m;
+};
+
+void f() {
+ RefPtr<B> b;
+}
+
+}
+
+// PR9130, test that we emit a definition of A::f.
+// CHECK-TEST5: define linkonce_odr void @_ZN5Test51A1fEv
+namespace Test5 {
+
+struct A {
+ virtual void f() { }
+};
+
+struct B : A {
+ virtual ~B();
+};
+
+B::~B() { }
+
+}
+
+// Check that we don't assert on this test.
+namespace Test6 {
+
+struct A {
+ virtual ~A();
+ int a;
+};
+
+struct B {
+ virtual ~B();
+ int b;
+};
+
+struct C : A, B {
+ C();
+};
+
+struct D : C {
+ virtual void f();
+ D();
+};
+
+D::D() { }
+
+}
+
+namespace Test7 {
+
+struct c1 {};
+struct c10 : c1{
+ virtual void foo ();
+};
+struct c11 : c10, c1{
+ virtual void f6 ();
+};
+struct c28 : virtual c11{
+ void f6 ();
+};
+
+// CHECK-TEST7: define void @_ZN5Test79check_c28Ev
+// CHECK-TEST7: call void @_ZN5Test73c282f6Ev
+// CHECK-TEST7: ret void
+void check_c28 () {
+ c28 obj;
+ c11 *ptr = &obj;
+ ptr->f6 ();
+}
+
+}
diff --git a/test/CodeGenCXX/vtable-debug-info.cpp b/test/CodeGenCXX/vtable-debug-info.cpp
new file mode 100644
index 0000000..c355406
--- /dev/null
+++ b/test/CodeGenCXX/vtable-debug-info.cpp
@@ -0,0 +1,318 @@
+// RUN: %clang -c -g %s -o /dev/null
+// Radar 8730409
+// XFAIL: win32
+
+// FIXME: This test crashes on Windows.
+#ifdef _WIN32
+
+#error this test must xfail
+
+#else
+class foo {
+public:
+#define x(a) virtual void v ## a (void)
+x(1);
+x(2);
+x(3);
+x(4);
+x(5);
+x(6);
+x(7);
+x(8);
+x(9);
+x(10);
+x(11);
+x(12);
+x(13);
+x(14);
+x(15);
+x(16);
+x(17);
+x(18);
+x(19);
+x(20);
+x(21);
+x(22);
+x(23);
+x(24);
+x(25);
+x(26);
+x(27);
+x(28);
+x(29);
+x(30);
+x(31);
+x(32);
+x(33);
+x(34);
+x(35);
+x(36);
+x(37);
+x(38);
+x(39);
+x(40);
+x(41);
+x(42);
+x(43);
+x(44);
+x(45);
+x(46);
+x(47);
+x(48);
+x(49);
+x(50);
+x(51);
+x(52);
+x(53);
+x(54);
+x(55);
+x(56);
+x(57);
+x(58);
+x(59);
+x(60);
+x(61);
+x(62);
+x(63);
+x(64);
+x(65);
+x(66);
+x(67);
+x(68);
+x(69);
+x(70);
+x(71);
+x(72);
+x(73);
+x(74);
+x(75);
+x(76);
+x(77);
+x(78);
+x(79);
+x(80);
+x(81);
+x(82);
+x(83);
+x(84);
+x(85);
+x(86);
+x(87);
+x(88);
+x(89);
+x(90);
+x(91);
+x(92);
+x(93);
+x(94);
+x(95);
+x(96);
+x(97);
+x(98);
+x(99);
+x(100);
+x(101);
+x(102);
+x(103);
+x(104);
+x(105);
+x(106);
+x(107);
+x(108);
+x(109);
+x(110);
+x(111);
+x(112);
+x(113);
+x(114);
+x(115);
+x(116);
+x(117);
+x(118);
+x(119);
+x(120);
+x(121);
+x(122);
+x(123);
+x(124);
+x(125);
+x(126);
+x(127);
+x(128);
+x(129);
+x(130);
+x(131);
+x(132);
+x(133);
+x(134);
+x(135);
+x(136);
+x(137);
+x(138);
+x(139);
+x(140);
+x(141);
+x(142);
+x(143);
+x(144);
+x(145);
+x(146);
+x(147);
+x(148);
+x(149);
+x(150);
+x(151);
+x(152);
+x(153);
+x(154);
+x(155);
+x(156);
+x(157);
+x(158);
+x(159);
+x(160);
+x(161);
+x(162);
+x(163);
+x(164);
+x(165);
+x(166);
+x(167);
+x(168);
+x(169);
+x(170);
+x(171);
+x(172);
+x(173);
+x(174);
+x(175);
+x(176);
+x(177);
+x(178);
+x(179);
+x(180);
+x(181);
+x(182);
+x(183);
+x(184);
+x(185);
+x(186);
+x(187);
+x(188);
+x(189);
+x(190);
+x(191);
+x(192);
+x(193);
+x(194);
+x(195);
+x(196);
+x(197);
+x(198);
+x(199);
+x(200);
+x(201);
+x(202);
+x(203);
+x(204);
+x(205);
+x(206);
+x(207);
+x(208);
+x(209);
+x(210);
+x(211);
+x(212);
+x(213);
+x(214);
+x(215);
+x(216);
+x(217);
+x(218);
+x(219);
+x(220);
+x(221);
+x(222);
+x(223);
+x(224);
+x(225);
+x(226);
+x(227);
+x(228);
+x(229);
+x(230);
+x(231);
+x(232);
+x(233);
+x(234);
+x(235);
+x(236);
+x(237);
+x(238);
+x(239);
+x(240);
+x(241);
+x(242);
+x(243);
+x(244);
+x(245);
+x(246);
+x(247);
+x(248);
+x(249);
+x(250);
+x(251);
+x(252);
+x(253);
+x(254);
+x(255);
+x(256);
+x(257);
+x(258);
+x(259);
+x(260);
+x(261);
+x(262);
+x(263);
+x(264);
+x(265);
+x(266);
+x(267);
+x(268);
+x(269);
+x(270);
+x(271);
+x(272);
+x(273);
+x(274);
+x(275);
+x(276);
+x(277);
+x(278);
+x(279);
+x(280);
+x(281);
+x(282);
+x(283);
+x(284);
+x(285);
+x(286);
+x(287);
+x(288);
+x(289);
+x(290);
+x(291);
+x(292);
+x(293);
+x(294);
+x(295);
+x(296);
+x(297);
+x(298);
+x(299);
+x(300);
+};
+
+foo b;
+
+#endif
diff --git a/test/CodeGenCXX/vtable-key-function.cpp b/test/CodeGenCXX/vtable-key-function.cpp
index 97a546f..bf2e679 100644
--- a/test/CodeGenCXX/vtable-key-function.cpp
+++ b/test/CodeGenCXX/vtable-key-function.cpp
@@ -9,7 +9,7 @@ struct A {
// A does not have a key function, so the first constructor we emit should
// cause the vtable to be defined (without assertions.)
-// CHECK: @_ZTVN6PR56971AE = weak_odr constant
+// CHECK: @_ZTVN6PR56971AE = linkonce_odr unnamed_addr constant
A::A() { }
A::A(int) { }
}
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
index 60b46fe..1cf8a52 100644
--- a/test/CodeGenCXX/vtable-layout.cpp
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -78,7 +78,7 @@ namespace Test2 {
// CHECK-2-NEXT: 5 | Test2::A::~A() [complete]
// CHECK-2-NEXT: 6 | Test2::A::~A() [deleting]
// CHECK-2-NEXT: 7 | void Test2::A::h()
-// CHECK-2-NEXT: 8 | Test2::A &Test2::A::operator=(Test2::A const &)
+// CHECK-2-NEXT: 8 | Test2::A &Test2::A::operator=(const Test2::A &)
struct A {
virtual void f();
virtual void f() const;
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index cf988d1..fc14c71 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -32,7 +32,7 @@ struct B {
B::B() { }
-struct C {
+struct C : virtual B {
C();
virtual void f() { }
};
@@ -99,92 +99,94 @@ void use_F() {
// B has a key function that is not defined in this translation unit so its vtable
// has external linkage.
-// CHECK-1: @_ZTV1B = external constant
+// CHECK-1: @_ZTV1B = external unnamed_addr constant
// C has no key function, so its vtable should have weak_odr linkage
// and hidden visibility (rdar://problem/7523229).
-// CHECK-2: @_ZTV1C = weak_odr constant
-// CHECK-2: @_ZTS1C = weak_odr constant
-// CHECK-2: @_ZTI1C = weak_odr constant
-// CHECK-2-HIDDEN: @_ZTV1C = weak_odr hidden constant
-// CHECK-2-HIDDEN: @_ZTS1C = weak_odr constant
-// CHECK-2-HIDDEN: @_ZTI1C = weak_odr hidden constant
+// CHECK-2: @_ZTV1C = linkonce_odr unnamed_addr constant
+// CHECK-2: @_ZTS1C = linkonce_odr constant
+// CHECK-2: @_ZTI1C = linkonce_odr unnamed_addr constant
+// CHECK-2: @_ZTT1C = linkonce_odr unnamed_addr constant
+// CHECK-2-HIDDEN: @_ZTV1C = linkonce_odr hidden unnamed_addr constant
+// CHECK-2-HIDDEN: @_ZTS1C = linkonce_odr constant
+// CHECK-2-HIDDEN: @_ZTI1C = linkonce_odr hidden unnamed_addr constant
+// CHECK-2-HIDDEN: @_ZTT1C = linkonce_odr hidden unnamed_addr constant
// D has a key function that is defined in this translation unit so its vtable is
// defined in the translation unit.
-// CHECK-3: @_ZTV1D = constant
+// CHECK-3: @_ZTV1D = unnamed_addr constant
// CHECK-3: @_ZTS1D = constant
-// CHECK-3: @_ZTI1D = constant
+// CHECK-3: @_ZTI1D = unnamed_addr constant
// E<char> is an explicit specialization with a key function defined
// in this translation unit, so its vtable should have external
// linkage.
-// CHECK-4: @_ZTV1EIcE = constant
+// CHECK-4: @_ZTV1EIcE = unnamed_addr constant
// CHECK-4: @_ZTS1EIcE = constant
-// CHECK-4: @_ZTI1EIcE = constant
+// CHECK-4: @_ZTI1EIcE = unnamed_addr constant
// E<short> is an explicit template instantiation with a key function
// defined in this translation unit, so its vtable should have
// weak_odr linkage.
-// CHECK-5: @_ZTV1EIsE = weak_odr constant
+// CHECK-5: @_ZTV1EIsE = weak_odr unnamed_addr constant
// CHECK-5: @_ZTS1EIsE = weak_odr constant
-// CHECK-5: @_ZTI1EIsE = weak_odr constant
-// CHECK-5-HIDDEN: @_ZTV1EIsE = weak_odr constant
+// CHECK-5: @_ZTI1EIsE = weak_odr unnamed_addr constant
+// CHECK-5-HIDDEN: @_ZTV1EIsE = weak_odr unnamed_addr constant
// CHECK-5-HIDDEN: @_ZTS1EIsE = weak_odr constant
-// CHECK-5-HIDDEN: @_ZTI1EIsE = weak_odr constant
+// CHECK-5-HIDDEN: @_ZTI1EIsE = weak_odr unnamed_addr constant
// F<short> is an explicit template instantiation without a key
// function, so its vtable should have weak_odr linkage
-// CHECK-6: @_ZTV1FIsE = weak_odr constant
+// CHECK-6: @_ZTV1FIsE = weak_odr unnamed_addr constant
// CHECK-6: @_ZTS1FIsE = weak_odr constant
-// CHECK-6: @_ZTI1FIsE = weak_odr constant
-// CHECK-6-HIDDEN: @_ZTV1FIsE = weak_odr constant
+// CHECK-6: @_ZTI1FIsE = weak_odr unnamed_addr constant
+// CHECK-6-HIDDEN: @_ZTV1FIsE = weak_odr unnamed_addr constant
// CHECK-6-HIDDEN: @_ZTS1FIsE = weak_odr constant
-// CHECK-6-HIDDEN: @_ZTI1FIsE = weak_odr constant
+// CHECK-6-HIDDEN: @_ZTI1FIsE = weak_odr unnamed_addr constant
// E<long> is an implicit template instantiation with a key function
// defined in this translation unit, so its vtable should have
-// weak_odr linkage.
-// CHECK-7: @_ZTV1EIlE = weak_odr constant
-// CHECK-7: @_ZTS1EIlE = weak_odr constant
-// CHECK-7: @_ZTI1EIlE = weak_odr constant
+// linkonce_odr linkage.
+// CHECK-7: @_ZTV1EIlE = linkonce_odr unnamed_addr constant
+// CHECK-7: @_ZTS1EIlE = linkonce_odr constant
+// CHECK-7: @_ZTI1EIlE = linkonce_odr unnamed_addr constant
// F<long> is an implicit template instantiation with no key function,
-// so its vtable should have weak_odr linkage.
-// CHECK-8: @_ZTV1FIlE = weak_odr constant
-// CHECK-8: @_ZTS1FIlE = weak_odr constant
-// CHECK-8: @_ZTI1FIlE = weak_odr constant
+// so its vtable should have linkonce_odr linkage.
+// CHECK-8: @_ZTV1FIlE = linkonce_odr unnamed_addr constant
+// CHECK-8: @_ZTS1FIlE = linkonce_odr constant
+// CHECK-8: @_ZTI1FIlE = linkonce_odr unnamed_addr constant
// F<int> is an explicit template instantiation declaration without a
// key function, so its vtable should have external linkage.
-// CHECK-9: @_ZTV1FIiE = external constant
+// CHECK-9: @_ZTV1FIiE = external unnamed_addr constant
// E<int> is an explicit template instantiation declaration. It has a
// key function that is not instantiated, so we should only reference
// its vtable, not define it.
-// CHECK-10: @_ZTV1EIiE = external constant
+// CHECK-10: @_ZTV1EIiE = external unnamed_addr constant
// The anonymous struct for e has no linkage, so the vtable should have
// internal linkage.
-// CHECK-11: @"_ZTV3$_0" = internal constant
+// CHECK-11: @"_ZTV3$_0" = internal unnamed_addr constant
// CHECK-11: @"_ZTS3$_0" = internal constant
-// CHECK-11: @"_ZTI3$_0" = internal constant
+// CHECK-11: @"_ZTI3$_0" = internal unnamed_addr constant
// The A vtable should have internal linkage since it is inside an anonymous
// namespace.
-// CHECK-12: @_ZTVN12_GLOBAL__N_11AE = internal constant
+// CHECK-12: @_ZTVN12_GLOBAL__N_11AE = internal unnamed_addr constant
// CHECK-12: @_ZTSN12_GLOBAL__N_11AE = internal constant
-// CHECK-12: @_ZTIN12_GLOBAL__N_11AE = internal constant
+// CHECK-12: @_ZTIN12_GLOBAL__N_11AE = internal unnamed_addr constant
// F<char> is an explicit specialization without a key function, so
-// its vtable should have weak_odr linkage.
-// CHECK-13: @_ZTV1FIcE = weak_odr constant
-// CHECK-13: @_ZTS1FIcE = weak_odr constant
-// CHECK-13: @_ZTI1FIcE = weak_odr constant
+// its vtable should have linkonce_odr linkage.
+// CHECK-13: @_ZTV1FIcE = linkonce_odr unnamed_addr constant
+// CHECK-13: @_ZTS1FIcE = linkonce_odr constant
+// CHECK-13: @_ZTI1FIcE = linkonce_odr unnamed_addr constant
// RUN: FileCheck --check-prefix=CHECK-G %s < %t
//
-// CHECK-G: @_ZTV1GIiE = weak_odr constant
+// CHECK-G: @_ZTV1GIiE = linkonce_odr unnamed_addr constant
template <typename T>
class G {
public:
@@ -197,3 +199,18 @@ void G<int>::f1() {}
template <typename T>
void G<T>::f0() {}
void G_f0() { new G<int>(); }
+
+// RUN: FileCheck --check-prefix=CHECK-H %s < %t
+
+// H<int> has a key function without a body but it's a template instantiation
+// so its VTable must be emmitted.
+// CHECK-H: @_ZTV1HIiE = linkonce_odr unnamed_addr constant
+template <typename T>
+class H {
+public:
+ virtual ~H();
+};
+
+void use_H() {
+ H<int> h;
+}
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
index 75620ab..f629c2d 100644
--- a/test/CodeGenCXX/vtable-pointer-initialization.cpp
+++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -19,14 +19,14 @@ struct A : Base {
Field field;
};
-// CHECK: define void @_ZN1AC2Ev(
+// CHECK: define void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr
// CHECK: call void @_ZN4BaseC2Ev(
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
// CHECK: call void @_ZN5FieldC1Ev(
// CHECK: ret void
A::A() { }
-// CHECK: define void @_ZN1AD2Ev(
+// CHECK: define void @_ZN1AD2Ev(%struct.A* %this) unnamed_addr
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
// CHECK: call void @_ZN5FieldD1Ev(
// CHECK: call void @_ZN4BaseD2Ev(
@@ -41,16 +41,16 @@ struct B : Base {
void f() { B b; }
-// CHECK: define linkonce_odr void @_ZN1BC1Ev(
+// CHECK: define linkonce_odr void @_ZN1BC1Ev(%struct.A* %this) unnamed_addr
// CHECK: call void @_ZN1BC2Ev(
-// CHECK: define linkonce_odr void @_ZN1BD1Ev(
+// CHECK: define linkonce_odr void @_ZN1BD1Ev(%struct.A* %this) unnamed_addr
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
// CHECK: call void @_ZN5FieldD1Ev(
// CHECK: call void @_ZN4BaseD2Ev(
// CHECK: ret void
-// CHECK: define linkonce_odr void @_ZN1BC2Ev(
+// CHECK: define linkonce_odr void @_ZN1BC2Ev(%struct.A* %this) unnamed_addr
// CHECK: call void @_ZN4BaseC2Ev(
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
// CHECK: call void @_ZN5FieldC1Ev
diff --git a/test/CodeGenCXX/vtt-layout.cpp b/test/CodeGenCXX/vtt-layout.cpp
index 814adf0..ace7b74 100644
--- a/test/CodeGenCXX/vtt-layout.cpp
+++ b/test/CodeGenCXX/vtt-layout.cpp
@@ -58,7 +58,7 @@ namespace Test4 {
D d;
}
-// CHECK: @_ZTTN5Test11BE = constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)]
-// CHECK: @_ZTTN5Test41DE = weak_odr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 10) to i8*)]
-// CHECK: @_ZTTN5Test31DE = weak_odr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 6) to i8*)]
-// CHECK: @_ZTTN5Test21CE = weak_odr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)]
+// CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)]
+// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 10) to i8*)]
+// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 6) to i8*)]
+// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)]
diff --git a/test/CodeGenCXX/warn-padded-packed.cpp b/test/CodeGenCXX/warn-padded-packed.cpp
new file mode 100644
index 0000000..4203bb3
--- /dev/null
+++ b/test/CodeGenCXX/warn-padded-packed.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -verify %s -emit-llvm-only
+
+struct S1 {
+ char c;
+ short s; // expected-warning {{padding struct 'S1' with 1 byte to align 's'}}
+ long l; // expected-warning {{padding struct 'S1' with 4 bytes to align 'l'}}
+};
+
+struct S2 { // expected-warning {{padding size of 'S2' with 3 bytes to alignment boundary}}
+ int i;
+ char c;
+};
+
+struct S3 {
+ char c;
+ int i;
+} __attribute__((packed));
+
+struct S4 {
+ int i; // expected-warning {{packed attribute is unnecessary for 'i'}}
+ char c;
+} __attribute__((packed));
+
+struct S5 {
+ char c;
+ union {
+ char c;
+ int i;
+ } u; // expected-warning {{padding struct 'S5' with 3 bytes to align 'u'}}
+};
+
+struct S6 { // expected-warning {{padding size of 'S6' with 30 bits to alignment boundary}}
+ int i : 2;
+};
+
+struct S7 { // expected-warning {{padding size of 'S7' with 7 bytes to alignment boundary}}
+ char c;
+ virtual void m();
+};
+
+struct B {
+ char c;
+};
+
+struct S8 : B {
+ int i; // expected-warning {{padding struct 'S8' with 3 bytes to align 'i'}}
+};
+
+struct S9 { // expected-warning {{packed attribute is unnecessary for 'S9'}}
+ int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+ int y; // expected-warning {{packed attribute is unnecessary for 'y'}}
+} __attribute__((packed));
+
+struct S10 { // expected-warning {{packed attribute is unnecessary for 'S10'}}
+ int x; // expected-warning {{packed attribute is unnecessary for 'x'}}
+ char a,b,c,d;
+} __attribute__((packed));
+
+
+struct S11 {
+ bool x;
+ char a,b,c,d;
+} __attribute__((packed));
+
+struct S12 {
+ bool b : 1;
+ char c; // expected-warning {{padding struct 'S12' with 7 bits to align 'c'}}
+};
+
+struct S13 { // expected-warning {{padding size of 'S13' with 6 bits to alignment boundary}}
+ char c;
+ bool b : 10; // expected-warning {{size of bit-field 'b' (10 bits) exceeds the size of its type}}
+};
+
+// The warnings are emitted when the layout of the structs is computed, so we have to use them.
+void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*) { }
OpenPOWER on IntegriCloud